Open GENZITSU opened 3 years ago
従来のトラッキングカウンターと比較して、通過した車両の種類を見分けることが期待されている。
現状の精度はトラッキングカウンターよりも低く、特に
非混雑時に精度が確保できている区間は7割程度となっている。
今後の方針としては、精度が確保できている箇所にういてはCCTV利用を進め、活用時間としては09:00 - 17:00までを原則とするようだ。
以前、CCTVとうかうということで話題になっていたが、めちゃくちゃ精度が高いわけでもないようだ。
精度が確保できていない場所や時間については、従来のトラカンとの併用になるのか...?
今後の画像認識技術の向上に伴い順繰りと置き換えていく感じなんだろうか・
ai-shift 戸田さんのシリーズ3部作目。
Transformer系のモデルと相性の良い過学習抑制テクニックが紹介されている。
元論文はMulti-Sample Dropout for Accelerated Training and Better Generalization
1 iterationでdropoutを複数回行いlossを計算し、それらの平均をそのイテレーションのlossとする手法。
Transformerに限らずいろいろなDNNモデルで使用されています
実装サンプルは以下
# from https://www.ai-shift.co.jp/techblog/2170
class CommonLitModel(nn.Module):
def __init__(self):
super(CommonLitModel, self).__init__()
self.config = AutoConfig.from_pretrained(MODEL_NAME)
self.bert = AutoModel.from_pretrained(
MODEL_NAME,
config=self.config
)
self.dropouts = nn.ModuleList([nn.Dropout(0.2) for _ in range(N_MSD)])
self.regressor = nn.Linear(self.config.hidden_size, 1)
def forward(self, input_ids, attention_mask, token_type_ids):
outputs = self.bert(
input_ids,
attention_mask=attention_mask,
token_type_ids=token_type_ids,
)
sequence_output = outputs['last_hidden_state'][:, 0] # baseline
logits = sum([self.regressor(dropout(sequence_output)) for dropout in self.dropouts])/N_MSD
return logits
私の観測範囲では5〜8が設定されることが多いようです
元論文はMixout: Effective Regularization to Finetune Large-scale Pretrained Language Models
やっていることのイメージとしては、dropoutを用いないネットワークの出力と、dropoutを用いるネットワークの出力を混合する感じ。 L2正則化の効果があるというらしいがほんまか?
こうすることでL2正則化のような効果を得ることができ、fine-tuningを安定させることができます
なお実装は結構複雑になるので、ぜひ元記事をみてほしい。
元論文はR-Drop: Regularized Dropout for Neural Networks
複数回dropout層を通して、それらのKLを小さくするようにする正則化をかける
# from https://www.ai-shift.co.jp/techblog/2170
def compute_kl_loss(p, q, pad_mask=None):
p_loss = F.kl_div(F.log_softmax(p, dim=-1), F.softmax(q, dim=-1), reduction='none')
q_loss = F.kl_div(F.log_softmax(q, dim=-1), F.softmax(p, dim=-1), reduction='none')
# pad_mask is for seq-level tasks
if pad_mask is not None:
p_loss.masked_fill_(pad_mask, 0.)
q_loss.masked_fill_(pad_mask, 0.)
# You can choose whether to use function "sum" and "mean" depending on your task
p_loss = p_loss.sum()
q_loss = q_loss.sum()
loss = (p_loss + q_loss) / 2
return loss
def loss_fn(logits1, logits2, label):
# RMSE loss
rmse1 = torch.sqrt(nn.MSELoss(reduction='mean')(logits1[:, 0], label))
rmse2 = torch.sqrt(nn.MSELoss(reduction='mean')(logits2[:, 0], label))
# R-Drop
kl_loss = compute_kl_loss(rmse1, rmse2)
total_loss = (rmse1 + rmse2) / 2 + RDROP_ALPHA * kl_loss
# 多分こっちが正解
total_loss = (logits1 + logits2) / 2 + RDROP_ALPHA * kl_loss
return total_loss
RDROP_ALPHAで損失関数におけるKL-divergenceの重みを調整します(論文では0.1, 0.5, 1.0が実験されていました)
ネットワークには2回通す必要があるので1iterationが重くなることには注意。
計算量があまり増加しないMSDは使ってみたいな。 R-dropも仕組みは単純なので余力がある時に...
自分が知らなかったけど使えそうなやつだけピックアップ。
リンク: https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces
行末のスペースを削除・可視化してくれる拡張機能」 行末の削除は、VS Codeのデフォルト設定で指定可能(むしろこちらを推奨)。 しかし、ハイライト(可視化)の目的で入れることをおすすめ。
リンク: https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree
「TODOとコメントされた箇所がハイライトされる上、サイドバーでタスクを一元管理することができる拡張機能」
リンク: https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare
VS Codeの画面上で同時編集をすることができる拡張機能」 具体的な共有手順
- VS CodeからGithubなどのアカウントへログイン
- 共有リンクを発行し、共同編集者へ送信
- 共同編集者がリクエストを送り、承認すれば同時編集開始
ToDo Treeしらなかった、TODO多用しているので使いたい、
BERT(ALBERT)を実務で使うときに工夫した点がいろいろ紹介されていた。
工夫は大きく分けて3つ inputする単語長を2倍に
1つ目は、入力文章の長さを2倍に。BERT系のモデルは基本的に512単語までしか扱っていませんが、業務文章では512単語より長い文章がけっこうあるので、今回は512の単語を2倍にして、1024単語まで拡大する工夫をしていました。
SentencePieceではなくSudachiによる形態素解析を実施
もともとのALBERTではSentencePieceというトークナイザーを利用していますが、日本語の場合はSentencePieceを使うよりも事前に形態素解析を行ったほうがよりよい結果が得られるので、今回は形態素解析を使うことにしました。 . 多数の形態素解析ライブラリの中から、Sudachiを選択しました。なぜかというとSudachiで使用している辞書は比較的新しく、より多くの単語に対応しているのでSudachiを選択しました。
事前学習としてWhole Word Maskingを使用
最後に、Whole Word Maskingという仕組みに対応するようにしました。
ALBERTにした結果として、メモリの削減 / 精度の向上 / 推論速度の削減を達成している。
類似度検索というユースケースではALBERTの出力をそのまま使うケースだとうまくいかなかったようで、日本語日本語SNLIデータを用いて、sentence-BERTの要領でfine-tuningをしたとのこと。
文章長が長くなっているからか、通常のBERTとくらべて推論速度がそこまで上がっていないように見える。
とはいえメモリサイズが10分の1になっているのでそれだけでも、助かる。
損失関数を工夫することで、高頻度データに対しては性能が良いが低頻度データに対しては微妙なモデルになる問題を回避する試み。
真の分布を知った状態で最適化できる、オラクルベースに肉薄できるポテンシャルを確認。
損失関数にクラス分布の下駄をはかせることで不均衡データを是正する取り組み。
一方で、重みのバイアス項に下駄をはかせるアプローチ(最初だけ下駄を履かせるやつ)もあるが、そっちと比べてどっちがいいのだろうか
静的な単語分散表現が持つ課題が列挙されている。
長い」と「短い」は、ほぼ同じような文脈で出現するため、当然ながらほぼ同じベクトルになる。
前後の文脈で判断する類義語と、同時出現で判断する関連語は包含関係にない。
単語分散表現は、単語の周辺文脈で判断するので、「チョーク」と文脈が類似する「鉛筆」や「ボールペン」は類似度が高いと表現する。 一方、「チョーク」と同時出現しやすい「教室」は、品詞などの文法的性質や意味的な性質が類似しているわけではない。
表記ゆれの単語は異なる単語として学習されるため、学習事例が少数となり、高い性能が得られにくい。
それぞれの語義で周辺文脈は異なるが、全て同じ単語として学習されてしまう。そのため、一定程度の性能劣化が存在する。
動的な単語ベクトル(たとえばBERTとか)であれば、語の関連性、多義語の分離はクリアできそう。
類義語/対義語, 表記揺れに関してはどうだろう...
なんかいけそうな気もするけどどうだろう。
最近のAIの進歩(自然言語処理 / 画像処理 )の紹介に加えてAIをビジネスに活用する際の落とし穴についてもまとめられている。ABEJAからの発表。
confidentialと書いてあるが、ネットで公開されているのはどうなんだろう...?
AIの活用範囲を絞りながら現場にバリューを出す方法を模索する必要がありそうだ。
(段階的にやっていくときの投資判断・投資の妥当性とかはどう説明するんだろう。)
prameterに対してrequires_grad=Falseすることと、optimizerに対象のparameterを渡さないことの違いが述べられている。
結論から行けば、requires_grad=Falseをちゃんとしましょうということになるのだが、
param.requires_grad = Falseをパラメータに与えた場合、勾配計算の対象外となり、その結果、勾配も更新されない。 一方、optimizerのparamsに設定しない場合、勾配計算の更新の対象外となるものの、勾配の計算自体は行われる。
これを検証した実験もされていて、
- 更新したいパラメータについてのみrequires_grad=True かつ optimizerには更新したいパラメータのみ指定
- 全てのパラメータにおいてrequires_grad=True かつ optimizerには更新したいパラメータのみ指定
- 更新したいパラメータについてのみrequires_grad=True かつ optimizerには全てのパラメータを指定
のそれぞれのパターンでの学習時間は
- 205秒
- 458秒
- 216秒
多分脳死でrequires_grad=Falseにしていたとおもうがこういう違いがあったとは。
pure Pythonなのに高速に動作するsorted listやsorted dic, sorted setを提供するライブラリ。
下記のような操作を全て線形時間以下で実施することができる。
# from http://www.grantjenks.com/docs/sortedcontainers/index.html
>>> from sortedcontainers import SortedList
>>> sl = SortedList(['e', 'a', 'c', 'd', 'b'])
>>> sl
SortedList(['a', 'b', 'c', 'd', 'e'])
>>> sl *= 10_000_000
>>> sl.count('c')
10000000
>>> sl[-3:]
['e', 'e', 'e']
>>> from sortedcontainers import SortedDict
>>> sd = SortedDict({'c': 3, 'a': 1, 'b': 2})
>>> sd
SortedDict({'a': 1, 'b': 2, 'c': 3})
>>> sd.popitem(index=-1)
('c', 3)
>>> from sortedcontainers import SortedSet
>>> ss = SortedSet('abracadabra')
>>> ss
SortedSet(['a', 'b', 'c', 'd', 'r'])
>>> ss.bisect_left('c')
2
詳しいパフォーマンス表は以下のリンクにある http://www.grantjenks.com/docs/sortedcontainers/performance.html
sortされていないものをこいつに渡して、脳死でpopすればいいのかな?
あまりML系でこいつの出番は思いつかないが、記憶の片隅にでも残しておきたい。
settings.jsonをレポジトリに置いておくことで、vscodeの設定をいじらなくても、共通の設定が可能になる。
コードチェッカーにflake8、自動整形ツールにblack、アノテーションの型チェックにPylanceを使う設定にしています。
地味に自動整形ツール(保存した時に自動にフォーマットをかけてくれるやつ)がかなり便利。 自分は型アノテーションつかってないので、Pylanceはoffにしておきたい。
poetryと各種開発ツールを利用した2021年度版python開発環境の紹介 設定ファイルのサンプルも添付されているのが◎
以下のような構成
CPython: 3.9
Package manager: poetry
Formatter: black
Import sorter: isort
Linter: pflake8
Plugin: flake8-bugbear
Type checker: mypy
Git hook manager: pre-commit
Max line length: 119
flake8-bugbearってやつは知らなかった。
防犯カメラのような粗い画像から犯人を特定するための、画像処理方法についての概説
ガウス分散処理を行った上で、コントラスト調整やガンマ補正、露出補正などの先鋭化処理などを行うことで、ある程度人物を特定できるような画像を得ることができるらしい。
ぼかした後に、シャープ処理を噛ませるのがよいっぽい? 実務でつかってみたいところ。
githubのcommt時に自動でコードのチェックや整形を行わせることができるツールの紹介
hookが失敗した場合には該当箇所の修正(フォーマッタに関するhookは自動で修正してくれるので手動での修正は不要)を行ってから,git add → git commitを実行する必要があります,
pre-commitから提供されているものに加えて、isortやblackもサポートされている、
github actionsに任せる派と別れそう。
設定ファイルをいちいち各レポジトリにおかなきゃいけないのが気になる、、
そういうことを考えると、一個前で紹介したpoetry+αみたいなやつで一括管理したくなったりするな,,,
特徴量が非説明変数をどれだけ予測できるかを測定したスコア
Predictive Power Score(以降PPSとする)はドイツに拠点を持つ8080Labsというソフトウェア会社が開発した考え方です。 ピアソン相関係数の相関マトリックスを使った分析と似たような形で使え、より汎用的に使用できるような指標を作れないだろうかというのモチベーションのもと開発されているようです。
下記が特徴
実際の算出方法は以下
ある特徴量だけを用いて、予測モデルを立てることで算出しているらしい。
なんか理論的な背景があるスコアなのかと思ったが、ただモデル作ってるだけか...
うーんみが深い値だな...
PyTorchの新しい推論モードについて
pytorchにinference modeという新しい機能が追加された。
これまでの推論方法
inference modeの使用はtorch.no_grad()と同じでコンテキストマネージャーベースで可能。
ではtorch.no_grad()と何が異なるのか?
端的に言えば、torch.no_grad()から更なる無駄を排除した形
具体的にはまず、 Version Counterが保存されない
そして、Inference Modeの外側ではTensor内の値は変更不可
さらにはRAILというテクニックまで用いられているとのこと: リンク
ただし性能は微増というコメントも見られる
コメント
no_gradの部分を取り替えるだけで良いとのことなので、使ってみたい。
出典
元記事