GENZITSU / UsefulMaterials

34 stars 0 forks source link

weekly useful materials - 09/21 - #69

Open GENZITSU opened 3 years ago

GENZITSU commented 3 years ago

PyTorchの新しい推論モードについて

pytorchにinference modeという新しい機能が追加された。

Inference Mode API allows significant speed-up for inference workloads while remaining safe and ensuring no incorrect gradients can ever be computed. It offers the best possible performance when no autograd is required.

これまでの推論方法

# https://rest-term.com/archives/3622/

model.eval()  ## torch.nn.Module.eval
with torch.no_grad():  ## disable autograd
    model(data)  # forward

inference modeの使用はtorch.no_grad()と同じでコンテキストマネージャーベースで可能。

# https://rest-term.com/archives/3622/

x = torch.ones(1, 2, 3, requires_grad=True)
with torch.inference_mode():
    y = x * x
print(y.requires_grad)  ## False

@torch.inference_mode()
def func(x):
    return x * x
out = func(x)
print(out.requires_grad)  ## False

ではtorch.no_grad()と何が異なるのか?
端的に言えば、torch.no_grad()から更なる無駄を排除した形

torch.no_grad() ではVersion Counterは保存していますし、Tensor内の値も後で変更可能です。Inference Modeは低レイヤー実装内でメモリ使用の無駄を省く処理がいろいろ施されているようでした。公式にも the extreme version of no-grad mode. としているので内部実装ではそこそこ差はあるようです。

具体的にはまず、 Version Counterが保存されない

というのは自動微分するために内部で必要となるデータバージョニング用のカウンター変数ですが推論用には不要なので保存されません。

# https://rest-term.com/archives/3622/

v = values.add_(1).add_(1).sub_(1).sub_(1)
print(v._version)  ## => 4 (オペレーション毎にカウントアップされるデータバージョニング用変数)

## 推論モード
with torch.inference_mode():
    y = x * x
print(y._version)
## Inference Modeではversion counterは保存されない
Traceback (most recent call last):
  File "./test.py", line 14, in <module>
    print(y._version)
RuntimeError: Inference tensors do not track version counter.

そして、Inference Modeの外側ではTensor内の値は変更不可

# https://rest-term.com/archives/3622/

x = torch.ones(1, 2, 3, requires_grad=True)
with torch.inference_mode():
    y = x * x
y[0][0][1] = 2
RuntimeError: Inplace update to inference tensor outside InferenceMode is not allowed.You can make a clone to get a normal tensor before doing inplace update.See https://github.com/pytorch/rfcs/pull/17 for more details.

さらにはRAILというテクニックまで用いられているとのこと: リンク

Resource Acquisition Is Initializationの略で,リソースの確保(Acquisition)と解放を変数の初期化(Initialization)と破棄に紐付けるというテクニックです。

ただし性能は微増というコメントも見られる

no_gradに対する性能は微増(MobileNetV3で1.5%、ResNet34で0.1%程度)。

コメント

no_gradの部分を取り替えるだけで良いとのことなので、使ってみたい。

出典

元記事

GENZITSU commented 3 years ago

CCTVカメラ(AI解析)の精度に関する報告

従来のトラッキングカウンターと比較して、通過した車両の種類を見分けることが期待されている。

スクリーンショット 2021-09-17 15 05 55

現状の精度はトラッキングカウンターよりも低く、特に

スクリーンショット 2021-09-17 15 06 12

非混雑時に精度が確保できている区間は7割程度となっている。

スクリーンショット 2021-09-17 15 06 22

今後の方針としては、精度が確保できている箇所にういてはCCTV利用を進め、活用時間としては09:00 - 17:00までを原則とするようだ。

スクリーンショット 2021-09-17 15 06 32

コメント

以前、CCTVとうかうということで話題になっていたが、めちゃくちゃ精度が高いわけでもないようだ。
精度が確保できていない場所や時間については、従来のトラカンとの併用になるのか...?

今後の画像認識技術の向上に伴い順繰りと置き換えていく感じなんだろうか・

出典

元記事

GENZITSU commented 3 years ago

Kaggleで学んだBERTをfine-tuningする際のTips③〜過学習抑制編〜

ai-shift 戸田さんのシリーズ3部作目。

Transformer系のモデルと相性の良い過学習抑制テクニックが紹介されている。

Multi Sample Dropout (通称MSD)

元論文はMulti-Sample Dropout for Accelerated Training and Better Generalization

1 iterationでdropoutを複数回行いlossを計算し、それらの平均をそのイテレーションのlossとする手法。

スクリーンショット 2021-09-16 22 12 31

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

元論文はMixout: Effective Regularization to Finetune Large-scale Pretrained Language Models

やっていることのイメージとしては、dropoutを用いないネットワークの出力と、dropoutを用いるネットワークの出力を混合する感じ。 L2正則化の効果があるというらしいがほんまか?

こうすることでL2正則化のような効果を得ることができ、fine-tuningを安定させることができます

スクリーンショット 2021-09-16 22 17 50

なお実装は結構複雑になるので、ぜひ元記事をみてほしい。

R-Drop

元論文はR-Drop: Regularized Dropout for Neural Networks

複数回dropout層を通して、それらのKLを小さくするようにする正則化をかける

スクリーンショット 2021-09-16 22 34 42
# 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が重くなることには注意。

今回の結果

スクリーンショット 2021-09-16 22 40 17

コメント

計算量があまり増加しないMSDは使ってみたいな。 R-dropも仕組みは単純なので余力がある時に...

出典

元記事

GENZITSU commented 3 years ago

【エンジニア必見】VS Code拡張機能まとめ25選!!

自分が知らなかったけど使えそうなやつだけピックアップ。

Trailing Spaces

リンク: https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces

行末のスペースを削除・可視化してくれる拡張機能」 行末の削除は、VS Codeのデフォルト設定で指定可能(むしろこちらを推奨)。 しかし、ハイライト(可視化)の目的で入れることをおすすめ。

Todo Tree

リンク: https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree

「TODOとコメントされた箇所がハイライトされる上、サイドバーでタスクを一元管理することができる拡張機能」

Live Share

リンク: https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare

VS Codeの画面上で同時編集をすることができる拡張機能」 具体的な共有手順

  • VS CodeからGithubなどのアカウントへログイン
  • 共有リンクを発行し、共同編集者へ送信
  • 共同編集者がリクエストを送り、承認すれば同時編集開始

コメント

ToDo Treeしらなかった、TODO多用しているので使いたい、

出典

元記事

GENZITSU commented 3 years ago

BERTより精度がよく推論時間の短いALBERT TexAIntelligenceへの導入方法と工夫点

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という仕組みに対応するようにしました。

スクリーンショット 2021-09-17 23 24 16

ALBERTにした結果として、メモリの削減 / 精度の向上 / 推論速度の削減を達成している。

スクリーンショット 2021-09-17 23 24 58 スクリーンショット 2021-09-17 23 25 11

類似度検索というユースケースではALBERTの出力をそのまま使うケースだとうまくいかなかったようで、日本語日本語SNLIデータを用いて、sentence-BERTの要領でfine-tuningをしたとのこと。

スクリーンショット 2021-09-17 23 27 55

コメント

文章長が長くなっているからか、通常のBERTとくらべて推論速度がそこまで上がっていないように見える。
とはいえメモリサイズが10分の1になっているのでそれだけでも、助かる。

出典

元記事

GENZITSU commented 3 years ago

Long-tail learning via logit adjustment

損失関数を工夫することで、高頻度データに対しては性能が良いが低頻度データに対しては微妙なモデルになる問題を回避する試み。

スクリーンショット 2021-09-18 11 26 14 スクリーンショット 2021-09-18 11 32 54 スクリーンショット 2021-09-18 11 33 44

実験設定

真の分布を知った状態で最適化できる、オラクルベースに肉薄できるポテンシャルを確認。

スクリーンショット 2021-09-18 11 34 20 スクリーンショット 2021-09-18 11 34 28 スクリーンショット 2021-09-18 11 34 38 スクリーンショット 2021-09-18 11 34 50

コメント

損失関数にクラス分布の下駄をはかせることで不均衡データを是正する取り組み。
一方で、重みのバイアス項に下駄をはかせるアプローチ(最初だけ下駄を履かせるやつ)もあるが、そっちと比べてどっちがいいのだろうか

出典

元記事

GENZITSU commented 3 years ago

自然言語処理の分散表現(Word2Vec,fastText)の課題

静的な単語分散表現が持つ課題が列挙されている。

① 類義語と対義語の区別ができない

長い」と「短い」は、ほぼ同じような文脈で出現するため、当然ながらほぼ同じベクトルになる。

② 語の関連性を把握できない

前後の文脈で判断する類義語と、同時出現で判断する関連語は包含関係にない。

単語分散表現は、単語の周辺文脈で判断するので、「チョーク」と文脈が類似する「鉛筆」や「ボールペン」は類似度が高いと表現する。 一方、「チョーク」と同時出現しやすい「教室」は、品詞などの文法的性質や意味的な性質が類似しているわけではない。

③ 低頻度後に対応できない

④表記ゆれに対処できない

表記ゆれの単語は異なる単語として学習されるため、学習事例が少数となり、高い性能が得られにくい。

⑤多義語を分離できない

それぞれの語義で周辺文脈は異なるが、全て同じ単語として学習されてしまう。そのため、一定程度の性能劣化が存在する。

コメント

動的な単語ベクトル(たとえばBERTとか)であれば、語の関連性、多義語の分離はクリアできそう。
類義語/対義語, 表記揺れに関してはどうだろう...
なんかいけそうな気もするけどどうだろう。

出典

元記事

GENZITSU commented 3 years ago

2021年最新 AI トレンドとビジネス活用の落とし穴

最近のAIの進歩(自然言語処理 / 画像処理 )の紹介に加えてAIをビジネスに活用する際の落とし穴についてもまとめられている。ABEJAからの発表。

失敗パターン①: 全てをAIで対応する

スクリーンショット 2021-09-18 23 43 00 スクリーンショット 2021-09-18 23 43 28 スクリーンショット 2021-09-18 23 43 48 スクリーンショット 2021-09-18 23 45 34 スクリーンショット 2021-09-18 23 45 43

失敗パターン② 運用イメージを考えられていない。

スクリーンショット 2021-09-18 23 45 52 スクリーンショット 2021-09-18 23 46 02 スクリーンショット 2021-09-18 23 46 11

コメント

confidentialと書いてあるが、ネットで公開されているのはどうなんだろう...? AIの活用範囲を絞りながら現場にバリューを出す方法を模索する必要がありそうだ。
(段階的にやっていくときの投資判断・投資の妥当性とかはどう説明するんだろう。)

出典

元記事

GENZITSU commented 3 years ago

PyTorch: requires_grad = False と optimizerにparamを与えないことの違い

prameterに対してrequires_grad=Falseすることと、optimizerに対象のparameterを渡さないことの違いが述べられている。

結論から行けば、requires_grad=Falseをちゃんとしましょうということになるのだが、

param.requires_grad = Falseをパラメータに与えた場合、勾配計算の対象外となり、その結果、勾配も更新されない。 一方、optimizerのparamsに設定しない場合、勾配計算の更新の対象外となるものの、勾配の計算自体は行われる。

これを検証した実験もされていて、

  1. 更新したいパラメータについてのみrequires_grad=True かつ optimizerには更新したいパラメータのみ指定
  2. 全てのパラメータにおいてrequires_grad=True かつ optimizerには更新したいパラメータのみ指定
  3. 更新したいパラメータについてのみrequires_grad=True かつ optimizerには全てのパラメータを指定

のそれぞれのパターンでの学習時間は

  1. 205秒
  2. 458秒
  3. 216秒
  1. 3の実行時間がほとんど変わらないことから、requires_grad=Falseが大事であることがわかる。

コメント

多分脳死でrequires_grad=Falseにしていたとおもうがこういう違いがあったとは。

出典

元記事

GENZITSU commented 3 years ago

Python Sorted Containers

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系でこいつの出番は思いつかないが、記憶の片隅にでも残しておきたい。

出典

元記事

GENZITSU commented 2 years ago

【python】VSCodeおすすめ設定【setting.json】

settings.jsonをレポジトリに置いておくことで、vscodeの設定をいじらなくても、共通の設定が可能になる。

コードチェッカーにflake8、自動整形ツールにblack、アノテーションの型チェックにPylanceを使う設定にしています。

コメント

地味に自動整形ツール(保存した時に自動にフォーマットをかけてくれるやつ)がかなり便利。 自分は型アノテーションつかってないので、Pylanceはoffにしておきたい。

出典

元記事

GENZITSU commented 2 years ago

【2021】モダンなPython開発環境の紹介

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ってやつは知らなかった。

出典

元記事

GENZITSU commented 2 years ago

どんな粗い画像でも犯人を特定できる!防犯カメラの不鮮明画像の処理法とは?【科学捜査】

防犯カメラのような粗い画像から犯人を特定するための、画像処理方法についての概説

ガウス分散処理を行った上で、コントラスト調整やガンマ補正、露出補正などの先鋭化処理などを行うことで、ある程度人物を特定できるような画像を得ることができるらしい。

スクリーンショット 2021-09-21 19 16 27

コメント

ぼかした後に、シャープ処理を噛ませるのがよいっぽい?   実務でつかってみたいところ。

出典

元記事

GENZITSU commented 2 years ago

pre-commitでコミット時にコードの整形やチェックを行う

githubのcommt時に自動でコードのチェックや整形を行わせることができるツールの紹介

スクリーンショット 2021-09-21 22 47 31

hookが失敗した場合には該当箇所の修正(フォーマッタに関するhookは自動で修正してくれるので手動での修正は不要)を行ってから,git add → git commitを実行する必要があります,

pre-commitから提供されているものに加えて、isortやblackもサポートされている、

スクリーンショット 2021-09-21 22 50 50 スクリーンショット 2021-09-21 22 51 01 スクリーンショット 2021-09-21 22 51 06

コメント

github actionsに任せる派と別れそう。   設定ファイルをいちいち各レポジトリにおかなきゃいけないのが気になる、、
そういうことを考えると、一個前で紹介したpoetry+αみたいなやつで一括管理したくなったりするな,,,

出典

元記事

GENZITSU commented 2 years ago

特徴量選択のための予測力スコア Predictive Power Score

特徴量が非説明変数をどれだけ予測できるかを測定したスコア

Predictive Power Score(以降PPSとする)はドイツに拠点を持つ8080Labsというソフトウェア会社が開発した考え方です。 ピアソン相関係数の相関マトリックスを使った分析と似たような形で使え、より汎用的に使用できるような指標を作れないだろうかというのモチベーションのもと開発されているようです。

下記が特徴

スクリーンショット 2021-09-21 23 06 11

実際の算出方法は以下
ある特徴量だけを用いて、予測モデルを立てることで算出しているらしい。

スクリーンショット 2021-09-21 23 07 18

コメント

なんか理論的な背景があるスコアなのかと思ったが、ただモデル作ってるだけか...
うーんみが深い値だな...

出典

元記事