不確定な世界

科学の話題を中心に、勉強したことや考えたことを残していきたいと思います

「つくりながら学ぶ!PyTorchによる発展ディープラーニング」;小川雄太郎著 読書感想

本日紹介するのは、小川雄太郎著「つくりながら学ぶ!PyTorchによる発展ディープラーニング」。
書名に「発展」とあるように、本書で扱われる手法は非常に発展的・応用的だ。物体検出のSSD、姿勢推定のOpenPose、異常検知のAnoGANなどは、メディアや書籍などで一度は聞いたことがあるだろう。しかしこの手のモデルは構造が複雑で、メディアの解説はもちろん原著論文を読んでもいまいち理解できないことも多い。このような論文レベルの手法*1の仕組みが詳細に解説されているだけでもありがたいのだが、本書はさらに、これらのモデルをPyTorchを使って1から組み上げていく*2。既にライブラリがある程度整備されているTransformerやBERTも、自分で実装する経験は貴重なものになった。なお本書の想定開発環境はAWSだが、私はGoogle Colaboratory(以下colab)で実装した。colab環境ではデータのダウンロードや解凍・モデルの学習にかかる時間が書籍に書いてあるより数倍速く、colabがいかに強力であるかも再認識することができた*3

また、サポートが丁寧であることも本書の特徴の一つである。まずコード中のコメントが非常に充実している*4。特に実装が非直感的になっている部分は徹底的にコメントで解説してくれているので、迷子にならずに済む。githubのイシューも活発で、著者が直々に議論に参加している。サンプルコード付き書籍のgithubはせいぜいこっそりバグフィックスしている程度のものが多いが、ここまで丁寧にアフターサービスを実施している著者には本当に頭が下がる。

最後にもう一つ。本書は基本的にコーディング中心で理論の説明はあまりないのだが、所々に著者独自の考察(感覚的理解)が述べられており、それが非常に参考になる。ネタバレになるので詳細は控えるが、DCGANにLeakyReLUが使われる理由や、CBOWよりもskip-gramで得た分散表現の方が性能が良い理由*5についての考察がある。興味のある方はぜひ本書を読んでみて欲しい。

こちらのイシューによると、著者は業界の動向を見て、方向性がある程度FIXしたらアルゴリズムを選定し直して新刊を出す予定のようだ。その時にどのアルゴリズムが選定されるかは分からないが、本書のような粒度でViTや拡散モデルなどを解説していただけるのであれば、その新刊も名著になることは確定だろう。楽しみにしたい。

TIPS+トラブルシューティング

本書は既に出版されてだいぶ経っており、所々エラーが発生することもある。前述したのように本書のgithubイシューは非常に活発で、大抵のエラーはイシューを調べればすぐに解決する。しかし、それでもやはり一筋縄ではいかなかった部分もあり、ここでは特に苦労した点やcolab特有と思われるエラーを挙げる。

公開GoogleDriveや公開Dropboxからcolabに直接ダウンロードする

本書の学習データや学習済みモデルの一部はGoogleDriveやDropboxからダウンロードすることになっている。手動でダウンロードしてローカルドライブからcolab環境に持ってきても良いのだが、本書に用いるデータはサイズが大きく、ドライブの容量を圧迫する。それにマウントは認証の手間があるので、直接ダウンロードした方が手っ取り早いと思う。GoogleDriveについてはこちらこちらを参考にして、以下のようなコードを使用した*6。もちろん、URLやファイル名の部分はその都度変更が必要。

!pip install --upgrade gdown
import gdown
gdown.download("https://drive.google.com/u/0/uc?id=0ByFQ96A4DgSPUm9wVWRLdm5qbmc", "./data/vector_neologd.zip", quiet=False)

また、Dropboxからのダウンロードについてはこちらを参考にした。例えば、以下のようになる。

#!wget -O tmp/FILENAME "対象URL(末尾?dl=1)"
!wget -O ./data/COCO.json https://www.dropbox.com/s/0sj2q24hipiiq5t/COCO.json?dl=1
!wget -O ./data/mask.tar.gz https://www.dropbox.com/s/bd9ty7b4fqd5ebf/mask.tar.gz?dl=1

SSDの推論時のエラー

対応するイシューはこちら。一番簡単な対策であるダウングレードについては、古いバージョンがpipの対象外?になっていたため実行できなかった。そのためryota0051さんの5/10のコメントを参考にしてスクリプトを修正したところ、無事に動いた(修正したスクリプトは%%writefileコマンドで保存するのが一番手っ取り早いだろう。colabセルとしてそのまま実行してもいいかもしれないが未確認)。

姿勢推定(OpenPose)の学習でメモリオーバー

バッチサイズを32から24にしたら動いた。たまたまその時だけcolabのGPUガチャに外れただけかも。

NEologd辞書のインストール

こちらの記事を参考にしつつ、さらにgit curl python-mecabという記述を削除。以下のようになる。

!apt-get -q -y install sudo file mecab libmecab-dev mecab-ipadic-utf8 > /dev/null #git curl python-mecab > /dev/null
!git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git > /dev/null 
!echo yes | mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n > /dev/null 2>&1
!pip install mecab-python3 unidic-lite > /dev/null
!pip install janome > /dev/null

# シンボリックリンクによるエラー回避
!ln -s /etc/mecabrc /usr/local/etc/mecabrc

Mecabの-Ochasenオプションを単独で使うとエラー

以下のように-dオプションで辞書を明示的に指定。

# m_t = MeCab.Tagger("-Ochasen")
m_t = MeCab.Tagger("-d /var/lib/mecab/dic/ipadic-utf8 -Ochasen")

torchtextのFieldやTabularDatasetの廃止

現在は既にtorchtext.legacyすら廃止されているので、おとなしくv0.8.1までダウングレードした。これもpipで対応できなくなると更なる対策が必要かも。

utils.dataloader.get_IMDb_DataLoaders_and_TEXT関数がエンコーディングエラー

colabセルにコピペしたら普通に動いた。また、io.open関数にencoding="utf-8"を追加して%%writefileコマンドでファイルを保存し直したら動いた。よくわからない。

youtube動画のダウンロードと前処理

1. 幸いなことに必要な動画はたった8つなので、ここは手動でダウンロード。ファイル名は1.mp4、2.mp4 ... などと通し番号を付けた。これをzipにまとめてcolab環境にアップロード。パスが/tmp/kinetics/*.mp4になるように展開する。

2. download.pyを以下のように修正してdownload2.pyとして保存(%%writefileコマンド使用)。以下は修正箇所しか見せないが本書を読んでいる人なら分かると思う。

#import youtube_dl
#中略 
###追加
def filename_generator():
    for i in range(1, 1000):
        yield str(i) + ".mp4"
g = filename_generator()
###
def download_clip(video_identifier, output_filename,
    #中略
    #tmp_filename = os.path.join(tmp_dir,
    #                            '%s.%%(ext)s' % uuid.uuid4())
    #追加
    tmp_filename = os.path.join(tmp_dir, next(g))
    command = ['youtube-dl',
    #中略
    while True:
        try:
            #output = subprocess.check_output(command, shell=True,
            #                                 stderr=subprocess.STDOUT)
            #追加
            pass

なお、ffmpegはcolab環境のものがきちんと動いたので修正箇所はyoube-dlに関する部分だけでよかった。

3. 以下のコマンドでdownload2.pyを実行。注意点は、上記の修正でジェネレータを使っており並列処理に対応していないため、ジョブ数を1としていること。それでも大した処理時間ではなかった。

!python ./video_download/download2.py -n 1 ./video_download/kinetics-400_val_8videos.csv ./data/kinetics_videos/

これ以降の処理は問題なく動いた。

*1:もはや"最先端"ではないが。

*2:フレームワークを使っているのでゼロからとは言わない笑

*3:もともと学習に極端に時間がかかる章では学習済みモデルがそのまま使えるようになっている

*4:本書の分厚さの要因の一つである

*5:単純にskip-gramの方が難しいタスクだからというのはよく聞くが、著者はもう一つ理由を挙げており、そちらが目からウロコだった。

*6:2023年2月現在、ダウングレードが必要だった