stMind

about Tech, Computer vision and Machine learning

Efficient Deep Learning: A Survey on Making Deep Learning Models Smaller, Faster, and Better

論文のURL:https://arxiv.org/pdf/2106.08962.pdf

深層学習は、ビジョンや自然言語処理音声認識など様々な分野で飛躍的な進歩をもたらしましたが、モデルの改良が進むにつれてパラメータ数やレイテンシー、学習に必要なリソースなどが大幅に増えており、単にモデルの品質だけでなく、これらの指標にも注目する必要があります。

この論文は、深層学習における効率性の問題に対し、モデルの効率性に関する5つの主要素のサーベイ論文になっています。

f:id:satojkovic:20210704181435p:plain

5つのそれぞれを要約すると、

  1. Compression techniques
    • 例えば、量子化(32bit floatではなく8bit intに精度を削減)
  2. Learning techniques
    • 例えば、distillation
      • 教師モデルの知識をパラメータ数の少ない生徒モデルが学習
  3. Automation
    • 例えば、ハイパーパラメータ最適化(HPO)
    • 他にはarchitecture searchなど
  4. Efficient architectures
    • 例えば、画像分類におけるConv layerは画像全体でパラメータ共有する仕組み
    • 他にはseq2seq modelにおけるattention layer
  5. Infrastructure & Hardware
    • TFやPytorchなどのフレームワーク
      • TF LiteやPytorch mobileのような効率的なモデルのDeployに使われる

それぞれの分野を調べるのはそれなりに時間がかかるものですが、このサーベイ論文で概観を掴んで、必要なところだけ詳細に調べると良さそうです。これから、ちょっとずつ読んでみることにしようかな。

HRNetのQuick Start Guide

CVPR2019で提案されたDeep High-Resolution Representation Learning for Human Pose Estimationのオフィシャル実装をEC2上で実行するまでの記録です。

jingdongwang2017.github.io

EC2は、Deep Learning Base AMI (Ubuntu 18.04) Version 38.0 のP3インスタンスを起動しました。CUDA10.0からCUDA11.1までがプリインストールされていますが、全ては使わないし、容量も圧迫するので、10.0以外は削除しました。これで、32GBほど空きました。

基本は、オフィシャルのレポジトリREADME通りですが、pytorchやcocoapiも含めて全てpip経由でインストールしました。また、EasyDictのbuildが失敗するので、明示的にpip install wheelが必要でした。

github.com

$ git clone https://github.com/leoxiaobin/deep-high-resolution-net.pytorch.git
$ cd deep-high-resolution-net
$ python3 -m venv hrnet_env
$ source hrnet_env/bin/activate
$ pip install torch torchvision pycocotools
$ pip install wheel 
$ pip install -r requirements.txt
$ cd lib; make ; cd ..
$ mkdir log
$ mkdir output

あとは、データセットとモデルファイルの準備ですが、これが一番時間かかりますね。mpii_human_pose_v1.tar.gzの画像ファイルはimages以下に展開されます。

data/
└── mpii
    ├── annot
    │   ├── gt_valid.mat
    │   ├── test.json
    │   ├── train.json
    │   ├── trainval.json
    │   └── valid.json
    ├── images
    └── mpii_human_pose_v1.tar.gz
models/
└── pytorch
    └── pose_mpii
        └── pose_hrnet_w32_256x256.pth

最後に、test.pyを実行して、READMEと同じスコアが見れました。

$ python tools/test.py --cfg experiments/mpii/hrnet/w32_256x256_adam_lr1e-3.yaml TEST.MODEL_FILE models/pytorch/pose_mpii/pose_hrnet_w32_256x256.pth GPUS '(0,)'

Test: [0/93]    Time 9.480 (9.480)  Loss 0.0003 (0.0003)    Accuracy 0.958 (0.958)
| Arch | Head | Shoulder | Elbow | Wrist | Hip | Knee | Ankle | Mean | Mean@0.1 |
|---|---|---|---|---|---|---|---|---|---|
| pose_hrnet | 97.101 | 95.941 | 90.336 | 86.449 | 89.095 | 87.084 | 83.278 | 90.330 | 37.702 |

Natural Language Processing Specialization

www.coursera.org

CourseraのNLP Specialization、完走しました!

NLP Specializationは全部で4つのコース、各コースはさらに4週間分のサブコースで構成されている専門講座になります。最初のコースの終了が7月だったので、全4コースを終了するのに4ヶ月かかったことになります。約4ヶ月のコースと記述されているので、ほぼ標準通りの進捗でした。

また、Certificationを最後にもらうためにSubscriptionに入っていたので、4ヶ月で合計約2万円の出費でした。

一つ一つのビデオは短く(2分から3分くらいが主)、疲れている日は一つだけちょっと見るか、みたいな感じで続けられるのが良かったかな。後は、どちらかというと理論的に踏み込んだ内容というよりは、概念や問題を理解するためのIntuition重視の説明で、またプログラミング課題も理論的に難しいところはスキップされていたりするので、これだけでエキスパートになれるというわけではないけれど、深層学習登場以前の古典的な機械学習アルゴリズムから、NNベースのアルゴリズムに至る過程を体系的に学べるので、自然言語処理技術や関連ワードを知っている状態からもう一歩進んだ状態になるには良いコースだと思いました。

T-shaped knowledge base

Machine Learning Engineerとして応募するのであれば、幅広い分野の知識を持つと同時に、一つの領域に関して深く専門的になろうという話。

自分はComputer Visionを専門にしていますが、特に自然言語処理で使われている技術は画像認識でも適用されたり、またその逆も然りで、両方の分野の知識があることは、明確なプラス作用があると思いますし、違った分野の知識を複合して持っていると、問題を違った側面から見ることができるのかなと思います。(単純に、NLPとCVの融合領域は面白いなぁと思ったり)

あとは、そういった知識をもとに、どの問題に対してどのようなアプローチを取るのか、といった経験が必要なのだと思いますが、そのあたりはこの図でいうと、縦軸に関する取り組みをやってみることで身についていくものなのかなと感じます。

Work From Home with Radiko

Work From Homeでのお供、Radikoでラジオ。

大体、こんなところを聞いてる。

あと金曜日は、はなさんのLovely Day - Fm yokohama 84.7も聞いている。

ラジオをここまで聞くのは人生で初めてだけど、面白い。ラジオ初心者に良い番組があれば、他にも何か知りたいところ。

imdb_reviews datasetのレビューに含まれるunique wordの上位N件の分布

レビューのテキストに含まれる語には、どういったものがあるか。特に、上位に含まれる語について、分布を見てみます。

scikit-learnのCountVectorizerを使って実装します。

def get_top_n_words(corpus, n=20, is_stop_words=False):
    vectorizer = CountVectorizer(stop_words='english') if is_stop_words else CountVectorizer()
    X = vectorizer.fit_transform(corpus)
    X_sum = X.sum(axis=0)
    words_freq = [(word, X_sum[0, idx]) for word, idx in vectorizer.vocabulary_.items()]
    words_freq = sorted(words_freq, key=lambda x: x[1], reverse=True)
    return words_freq[:n]

fit_transformで、corpusに含まれるunique wordのcountを含むarrayが得られるので、sumでword毎のcountを計算しています。

公式の例から引用。

>>> from sklearn.feature_extraction.text import CountVectorizer
>>> corpus = [
...     'This is the first document.',
...     'This document is the second document.',
...     'And this is the third one.',
...     'Is this the first document?',
... ]
>>> vectorizer = CountVectorizer()
>>> X = vectorizer.fit_transform(corpus)
>>> print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
>>> print(X.toarray())
[[0 1 1 1 0 0 1 0 1]
 [0 2 0 1 0 1 1 0 1]
 [1 0 0 1 1 0 1 1 1]
 [0 1 1 1 0 0 1 0 1]]

このsumを計算すると以下のようにword毎のカウントが得られます。

>>> X.sum(axis=0)                                                                                             
matrix([[1, 4, 2, 4, 1, 1, 4, 1, 4]], dtype=int64)

では、分布を見てみます。上段のグラフがStop wordsを含むもの、下段がStop wordsを除いたものです。

f:id:satojkovic:20200704171438p:plain

上位の語のリストで見ると、結構似ています。goodやbadのような感情分析に有効であると思われる語だけでなく、movieやfilmのようなニュートラルな語も含まれています。positiveなテキストにおいて、goodはbadより多く含まれていますが、negativeなテキストではbadはgoodより多いものの、同じくらい多く含まれていることも分かりました。

imdb_reviews datasetのレビュー長のヒストグラム

データセット自体を理解し、モデル改善に役立てていきます。

Positiveなレビュー、Negativeなレビュー、それぞれについてレビュー長(ワード数)をカウントし、ヒストグラムで可視化します。

    # 4. Count the length of sentences
    all_sentences = training_sentences + testing_sentences
    all_labels = training_labels + testing_labels
    positive_sentence_length = [len(sentence.split(' ')) for sentence, label in zip(all_sentences, all_labels) if label == 1]
    negative_sentence_length = [len(sentence.split(' ')) for sentence, label in zip(all_sentences, all_labels) if label == 0]
    max_length = max(max(positive_sentence_length), max(negative_sentence_length))

    # 5. Plot the distribution
    plt.hist(positive_sentence_length, bins=max_length, alpha=0.5, rwidth=2, label='positive')
    plt.hist(negative_sentence_length, bins=max_length, alpha=0.5, rwidth=2, label='negative')
    plt.xlabel('Review length')
    plt.ylabel('Frequency')
    plt.legend()
    plt.show()

f:id:satojkovic:20200629210500p:plain

100〜200ワード前後が最も多いですね。