lang_model-arxiv.ipynbで必要となるarxiv.csvとall_arxiv.pickleを取得する方法

ニッチすぎてこれが役に立つ人は果たして何人いるのだろう。。という記事ですが少し苦労したのでメモです。

何かと言うと、細々と続けている MOOC講座 fast.ai の part1 v2の lang_model-arxiv.ipynb でソースとなるファイルが見つからない問題です。

問題となる箇所

3つ目のセル

df_mb = pd.read_csv(f'{PATH}arxiv.csv')
df_all = pd.read_pickle(f'{PATH}all_arxiv.pickle')

jeremyがフォーラムのスレッドで次のようにコメントしてますが

You can download an arxiv dataset using this project: https://hackernoon.com/building-brundage-bot-10252facf3d1

このリンクに飛んで探しても all_arxiv.pickle は見つかりません..。

なぜなら、、

このページにリンクが張ってあるリポジトリのコードを自分で実行して作成する必要があるからです。。

arxiv.csvの取得

all_arxiv.pickleの前にまずarxiv.csvから

こちらは https://github.com/amauboussin/arxiv-twitterbot からリンクが張ってあるbrundage_bot.csvをダウンロードしてarxiv.csvにリネームすれば良さそうです

all_arxiv.pickleの取得

続いてall_arxiv.pickleです。 以下の手順で作成できました

  1. 必要なもの

    • python2
  2. プロジェクトを git clone する

     $ git clone https://github.com/amauboussin/arxiv-twitterbot.git
    
  3. 依存ライブラリのインストール

     $ conda install pandas
     $ conda install requests
     $ pip install feedparser
    
  4. job.pyの修正

    tweetに関する箇所は不要なのでコメントアウトします

     from time import sleep
    
     from get_arxiv import check_for_update, update_arxiv
     # from tweet_papers import tweet_day
    
     # if check_for_update():
     #     update_arxiv()
     #     sleep(2)
     #     tweet_day(dry_run=False)
     update_arxiv()
    
  5. get_arxiv.pyの修正

    pklファイルが元から存在している前提だったり、ループが終わらなかったり(?!)、ちょこちょこと修正する必要がありました :-)

    gist.github.com

  6. job.pyを実行する

    時間がかかりますが辛抱強く待つとall_arxive.pickleが作成されます

    $ python job.py
    

これで一応 lang_model-arxiv.ipynbは最後まで動かせました。 私が作成したall_arxive.pickleはここに置いてあるので面倒くさい方は使ってください

Azureマシンのjupyterをローカルから開けるようにする

Azureで仮想マシンを起動すると毎回パブリックIPアドレスが変わるのでsshするときとても面倒です。

さらに、Azureマシン上でjupyter notebookを立ち上げたときも毎回tokenの値が違うのでこれをコピペでブラウザに貼り付け、localhostの部分を自分のIPアドレスDNS名に置き換えるという作業がとてもとても面倒です。

あぁもう面倒すぎる...

ということで、重い腰を上げてAzure CLIを使ってIPアドレスを意識せずにsshログインしたり、jupyterのtokenつきURLをローカルマシン上で開けるようにできるシェルスクリプトを作りました。

github.com

準備

https://github.com/tanakatsu/azure-cli-wrapper-scripts のファイルをダウンロードしておきます

  1. Azureのマシン名やsshキーのパスなどを設定

    azure-env.shを編集して自分の設定に置き換えます

    export vmName=YourVmName
    export resourceGroup=YourResourceName
    export privateKeyPath=PathToPrivateKey # ~/.ssh/your_azure_private_key
    export jupyterRootDir=. # relative path from home directory
    
  2. Azure CLIのインストール

    公式ページに方法が書いてありますが Macの場合は brew update && brew install azure-cli で一発でインストールできます

  3. az loginでログインしておく

     To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code GDGSSH8M3 to authenticate. 
    

    のようなレスポンスが返ってくるので指示通り、https://aka.ms/deviceloginを開いて コードを入力します。「デバイスMicrosoft Azure Cross-platform Command Line Interface アプリケーションにサインインしました。...」という画面が表示されればokです

使い方の例

# 環境変数とエイリアスのセットアップ
source azure-env.sh
source azure-alias.sh

# VMを起動する
azure-start

# リモートマシンのjupyter notebookをローカルマシンから立ち上げる
azure-start-jupyter

起動したjupyter notebookをローカルマシンのブラウザで開くときは別のターミナルを使います。

## in another terminal

# 環境変数とエイリアスのセットアップ
source azure-env.sh
source azure-alias.sh

# IPアドレスを取得
azure-ip

# jupyter notebookをブラウザで開く
./azure-open-jupyter.sh

これで毎回変わるIPアドレスを意識することなくローカルマシン上での操作だけでjupyter notebookを使えるようになります (◍•ᴗ•◍)

シャットダウンは

# 終了し割り当てを解除する
azure-stop

Azure CLIaz vm stopだとマシン停止だけで割り当て解除まではされないようで az vm deallocateも同時に行っています。 管理画面で停止ボタンを押すと割り当ての解除までやってくれるのでCLIでも割り当て解除までやってほしいです。。(stopだけだと課金が続いちゃいます ><)

シェルスクリプトの中でやっていること

jupyter notebookをリモートで起動する

今まで知らなかったのですが sshコマンドでは ssh接続時に直接コマンドを実行することもできるようです。

例えば、ssh ユーザー名@ipアドレス ls とすればリモートマシンのホームディレクトリのファイルのリストが返ってきます。

これを利用してjupyter notebookを起動します。

具体的なコードはこちら

alias azure-start-jupyter='ssh -i ${privateKeyPath} -o "StrictHostKeyChecking no" ubuntu@${instanceId} "export PATH=~/anaconda3/bin:$PATH;source activate fastai;cd ${jupyterRootDir};jupyter notebook"'

sshを使ってリモートのコマンドを実行したとき.bashrcは実行されないようでその中でやっているPATHの設定等などは明示的にやってあげる必要があります。

リモートで起動したjupyter notebookのtokenを取得する

jupyter notebook listコマンドで tokenつきのURLが出力されるのでこれを sshコマンドを使ってリモートマシン上で実行します。 あとは sed やら awk やらでローカルのブラウザで開くためのURLを構築します。

具体的なコードはこちら

list=`ssh -i ${privateKeyPath} ubuntu@${instanceId} 'export PATH=~/anaconda3/bin:$PATH;source activate fastai;jupyter notebook list'`
url=`echo $list | grep http | sed -e "s/localhost/${instanceId}/g" | awk '{print $4}'`
echo $url
open $url


sshコマンドのいろいろな使い方に関しては以下の記事が大変参考になりました。 orebibou.com

CUDA9.1の環境でTensorFlowをインストールする

fast.aiのpart1 v2は基本的に PyTorch を使って進めることになりますが Keras+TensorFlow用の notebook(keras_lesson1.ipynb)が1つだけあります。

これも動かしたる! と思ってTensorFlowのパッケージをインストールしようとしたところ、、

part1 v2用の環境はCUDAのバージョンが9.1となっており、Anacondaやpipを使ってGPU対応のTensorFlowを一発でインストールができないことが分かりました。。(CUDA8.0用にビルドされているため)

が、先人の記事を発見し何とかインストールできました。(๑˃̵ᴗ˂̵)و

deep-rikei.hatenadiary.jp

自分の記事の中で書きたいことはただ1つ。

bazel は 0.7.0 を使おう

(↑の記事の中で推奨とされている通り。最新版はダメ、絶対)

というのも、最初は 「p3インスタンス(V100)上でCUDA+CUDNN+Tensorflowを動かすのが大変だったのできろく。 - 焼肉が食べたい」 の記事を発見し、これを参考に作業してたのですが

bazelのインストールでそのまま真似したら

sudo apt-get -y install openjdk-8-jdk
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update && sudo apt-get install oracle-java8-installer
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update && sudo apt-get install bazel
sudo apt-get upgrade bazel

の手順で bazel の 0.9.0がインストールされていて、そのまま進めると TensorFlowのビルド時に大量のエラーメッセージ... ><

記事ではその後、TensorFlowのconfigureスクリプトの実行ログで

$ ./configure
You have bazel 0.7.0 installed.

となっているのでその時だときっと bazel 0.7.0 がインストールされたのでしょう。。

CUDAとcudnnをインストールした以降の手順のメモ

fast.aiの環境構築が済んでいるとCUDAとcudnnは既にインストールされているので 先のid:syakai-jinさんの記事の (16) 以降をやればよいです。

  1. bazelのインストール (0.7.0じゃないとダメ。0.9.0だとビルド時にエラーが出た)

     $ wget https://github.com/bazelbuild/bazel/releases/download/0.7.0/bazel-0.7.0-installer-linux-x86_64.sh
     $ chmod +x bazel-0.7.0-installer-linux-x86_64.sh
     $ ./bazel-0.7.0-installer-linux-x86_64.sh
     $ bazel version
    

    bazel のバージョンが 0.7.0 であることを確認しましょう

  2. export PATH=~/bin:$PATH を.bashrcに追加

  3. 必要なパッケージをインストール

    $ sudo apt-get -y install libcupti-dev

  4. TensorFlowのソースコードを取ってきます

     $ git clone -b v1.4.0 https://github.com/tensorflow/tensorflow
     $ cd tensorflow
     $ ./configure
    
    • Do you wish to build TensorFlow with CUDA support? [y/N]: => Yes
    • Please specify the CUDA SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 8.0]: => 9.1
    • Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 6.0]: => 7.0.5

    これら以外は No と ENTER(デフォルトのまま)でよい

    CUDAのバージョンは ls /usr/local/cuda*、cndnnのバージョン確認は ls /usr/local/cuda/lib64/libcudnn.so.* で確認できます

  5. シンボリックリンクを作る

     $ sudo ln -s /usr/local/cuda/include/crt/math_functions.hpp /usr/local/cuda/include/math_functions.hpp
    

    これをしないとファイルがないというビルドエラーになる

  6. ビルド

     $ bazel build -c opt --copt=-march="haswell" --config=cuda //tensorflow/tools/pip_package:build_pip_package
    
  7. パッケージを作成

     $ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg`
    
  8. パッケージをインストール

     $ pip install /tmp/tensorflow_pkg/tensorflow-1.4.0-cp36-cp36m-linux_x86_64.whl`
    

あとは keras と h5py をインストールしましょう。

$ pip install keras
$ conda install h5py # これをインストールしないとweightファイルのload時にエラーが出る

fast.aiのpart1 v2の環境構築

まだオフィシャルではないようですが私がひいきにしているMOOC講座、Deep Learning Part 1: Practical Deep Learning for Coders の v2 が昨年末にオープンになりました。

part1 v2用の環境構築をPaperspaceとAzure上で行ったのでそのメモです。

Paperspace

Paperspaceは講座の中でオススメされている仮想デスクトップ環境を提供するサービスです。

jp.techcrunch.com

以下のガイドに沿って何の問題なくセットアップできました。 github.com

私が作業したときは fast.ai用のテンプレートイメージはまだ存在してなく Ubuntu 16.04 のテンプレートからの構築だったのですが最新版のガイドでも問題ないはず。

ちなみに、当時のガイドはこちらです。

Azure

Paperspace用のセットアップスクリプトを一部修正すれば問題なく環境構築できました。

修正したところ

7行目あたり

# sudo rm /etc/apt/apt.conf.d/*.*
sudo rm /etc/apt/apt.conf.d/*

です。

一連の流れは

$ wget http://files.fast.ai/setup/paperspace
$ sed -i -e 's/\/etc\/apt\/apt.conf.d\/*.*/\/etc\/apt\/apt.conf.d\/*/' paperspace
$ bash paperspace

となります。

Azure (v1用のインスタンスを流用)

v1用に構築したGPUインスタンスでpart1 v2用の環境構築も可能です(並行して使えます)。

part1構築時のインスタンスのCUDAのバージョンが8.0であるためenvironment.ymlを以下のように修正します。

dependencies:
- scipy
# - cuda90 # コメントアウト

...

- zeromq
#- pytorch>=0.2.0 # コメントアウト
- torchvision>=0.1.9
- bcolz
- prompt_toolkit
- pip:
  - http://download.pytorch.org/whl/cu80/torch-0.2.0.post3-cp36-cp36m-manylinux1_x86_64.whl # 追加

あとは、$ conda env update でokです。

ライブラリのimportでエラーになったときのworkaround

Azure (v1用のインスタンスを流用)の方法で自宅PCもv2用の環境構築を行ったのですが

jupyter notebookの

from fastai.transforms import *
from fastai.conv_learner import *
from fastai.model import *
from fastai.dataset import *
from fastai.sgdr import *
from fastai.plots import *

のセルを実行したときに ImportError: dlopen: cannot load any more object with static TLS というエラーが出ちゃいました。。

フォーラムのコメントを参考に以下のように一つ上のセルで import torch, cv2を追加したらエラーを解消できました。

# Workaround for  'ImportError: dlopen: cannot load any more object with static TLS'
# http://forums.fast.ai/t/import-error-in-lesson-1/7704/11
import torch, cv2 

# This file contains all the main external libs we'll use
from fastai.imports import *

もし同じ症状に出くわすことがあったらお試しください!

pytorchのインストールでエラーが出た場合

もし、pytorchのインストール時に

PackageNotFoundError: Dependency missing in current osx-64 channels: 
  - pytorch -> mkl >=2018

というようなエラーが出た場合、

$ conda update conda で解決します。

Error installing 0.3.0 from Anaconda on MacOS 10.13.1 · Issue #4090 · pytorch/pytorch · GitHub

NetlifyとNowへ引っ越し

Azureで自分のホームページ(と呼べるほどの代物でもないけど。。)をホスティングしていますが 何と月々のフリークレジットの85%以上をこれらのWebアプリが占めていました... 😱

エッ、まじ?

どうりでディープラーニング学習用に使える分が残ってないはずだ...

ということで、これらのWebアプリを無料で運用できるところへ引っ越しさせました。

HTMLサーバーを Azure Web Apps から Netlify へ

無料でホームページを公開したいときの選択肢としてGitHubPagesもありますが前から少し気になっていたNetlifyを使ってみました。

Netlifyのサインアップをして、

  1. 管理画面から New site from Git
  2. ホームページを管理しているBitbucketのプライベートのリポジトリを選択

以上です。

簡単でした。🙂

このままだとURLが (ランダムな文字列).netlify.com なので 好きな名前に変えます。

Site settings > General > Site details > Change site name で変更できました

f:id:sanshonoki:20180121075314p:plain:w300

Node.jsアプリを Azue Web Apps から Now へ

Nowというのは Node.jsやDocker用のPaaSです。 今回、引越し先を探していて初めて知りました。

Dockerでのデプロイができるということは事実上何でもよいということですね。 試しにRailsアプリをDockerでデプロイしたら無事動いてくれました。:-)

デプロイの方法(Node.jsアプリ)
  1. CLIツールのインストール

    $ npm install -g now-cli

  2. 起動用のpackage.json を用意する

     {
       "scripts": {
         "test": "echo \"Error: no test specified\" && exit 1",
         "start": "node server.js"
       },
     }
    
  3. デプロイ

    $ now

    これだけです。メールアドレスを尋ねられて入力するとそのメールアドレスに認証コードを含むメールが飛んできます。リンクをクリックして認証が済むとデプロイが進行します。

以上です。

評判通りに驚くほど簡単でした。🙂

プロダクション用のURLの設定

nowコマンドでデプロイすると毎回違ったURLが発行されるのでプロダクション用にURL固定にしたいときはエイリアスを設定します。

now.json

{
    "alias": "panoplaza-multiscreen"
}

というファイルを用意し、$ now alias とすれば

$nowでデプロイしたURLは https://panoplaza-multiscreen.now.sh/ としてアクセスできるようになります。

Node.jsのバージョンの設定

package.jsonの中でenginesのフィールドを設定すればいいようです。

{
  "engines": {
    "node": "6.x.x"
  },
}

なお、デフォルトは 6.x.x のようですが今後デフォルトのバージョンが変わったときのために念のためセットしてあります。

デプロイの状態を見る
$ now ls

> 1 deployment found under xxx@yyy.com [1s]

panoplaza_multiscreen (1 of 1 total)
 url                                            inst #    state                 age
 panoplazamultiscreen-ezswrmhgyn.now.sh              1    READY                  2h

デプロイのIDを確認できます。

ログを見る
$ now logs panoplazamultiscreen-ezswrmhgyn.now.sh

("panoplazamultiscreen-ezswrmhgyn.now.sh" は自分のデプロイIDに置き換えてください)

デプロイを削除する

公式ページのDocsで見つからずググったらBLOGのページが見つかりました。

$ now rm panoplazamultiscreen-ezswrmhgyn.now.sh

("panoplazamultiscreen-ezswrmhgyn.now.sh" は自分のデプロイIDに置き換えてください)

注意点

無料のOSSプランだとソースコードもログも丸見えになっちゃいます。

確かに https://zeit.co/tsuyoshi/panoplazamultiscreen/utusmcofyf のページは認証がかかってなくソースコードやログが誰でも見えちゃいます。。

f:id:sanshonoki:20180122194923p:plain (右上のLogsもSourceもパブリック)

ソースコードはともかくログまで見えちゃうのは少し気持ち悪いです 🤔

https://(デプロイで発行されたURL)/_src でもソースコードが見れるURLに遷移します)

今回のプロジェクトはソースコードにパスワードやsecret key等の秘密情報を含んでないので公開でも問題ないですがそういった場合は、環境変数を使ったりsecretコマンドを使えばいいようです。

あと、OSSプランは以下のように制限がそこそこありますがちょっとしたものを公開するには問題ないでしょう

  • BANDWIDTH: 1GB
  • LOGS: 100MB
  • INSTANCES: 3
  • MAX FILE SIZE: 1MB
  • STORAGE: 1GB


とりあえず移行できました。ディープラーニングの学習用インスタンスを今より強気に使えるようになるはず ƪ(•◡•ƪ)”

ナンガのダウンジャケット

昨年末にナンガのダウンジャケットを買いました。

それがあまりにも良い買い物だったので記事を書きます。。

f:id:sanshonoki:20180118053912p:plain:w400

ナンガとは?

ナンガというのはブランド名

“ジャパンブランド”である“NANGA(ナンガ)”。 社名の由来はヒマラヤにある8,000メートル級の高峰“ナンガバルバット”。伊吹山の麓、滋賀県米原市の創業74年の国産「羽毛商品」メーカーです。主にシュラフ(寝袋)やジャケット・パンツ等登山アパレルを国内生産しています

https://www.mountain-products.com/nanga

友人から教えてもらうまでその存在をまったく知らなかったのですが滋賀県のシェラフ・メーカーが作っているダウンジャケットです。名前の由来はヒマラヤにある山の名前から取っているようでアウトドアウェアの王者パタゴニアやColumbia(コロンビア)にも引けをとらないですね

良いところ 👍

  • Made in Japan
  • 撥水素材
  • コストパフォーマンス

本当に暖かいです。紹介してくれた友人がバイク乗りですがバイクで走っているときでも暖かいとのことです。 そして撥水。ダウンは水濡れや湿気に対して極端に弱いのでこれも大事です。 あと、まったくもってマイナーなのでパタゴニアのように変に値段が高くなっちゃってるということはなく、コストパフォーマンス抜群です。

そして、いちばん驚いたのは手ポケットの内側に羽毛がぎっしり詰まっていること。手をポケットに突っ込んだときの暖かさがたまりません :-)

ネック 👎

ネックは 取り扱っているリアル店舗が少ないことですね.. アパレルを買うのであればやはり試着はしたいものです。

私はナンガとコラボしているアパレルショップ、「URBAN RESEARCH DOORS」がたまたま近くのショッピングモールにあってそこで買うことができました。

www.urdoors.com

本当に良い商品だと思うのでもっと色々なショップで取り扱ってもらってもっともっと流行ってほしいです

Batch Normalizationの実験

Practical Deep Learning For Coders, Part 1の lesson3.ipynb

Batchnorm resolves this problem by normalizing each intermediate layer as well. The details of how it works are not terribly important (although I will outline them in a moment) - the important takeaway is that all modern networks should use batchnorm, or something equivalent. There are two reasons for this:

Adding batchnorm to a model can result in 10x or more improvements in training speed Because normalization greatly reduces the ability of a small number of outlying inputs to over-influence the training, it also tends to reduce overfitting.

と、Batch Normalizationを使うことが強く推奨されていますが MNISTでBatch Normalization(BN)を使ってみたところ、あまり変わりませんでした。

というか、BN使ったほうが微妙に劣っていました。。

lr=0.001で1epoch学習後にlr=0.0001でさらに8epoch学習

loss acc val_loss val_acc
BNなし 0.0133 0.9957 0.0205 0.9936
BNあり 0.0158 0.9948 0.0369 0.9889

というわけで、MNISTとCIFAR10のデータセットを使って少し実験してみました。

Batch Normalization

日本語で概要をつかむには以下の記事が分かりやすかったです。 deepage.net

Batch Normalizationでの逆伝搬の仕組みについてはいろいろな記事で Understanding the backward pass through Batch Normalization Layer がよく引用されていました。

MNIST

モデルは以下のように定義しています。

model = Sequential([
    Lambda(norm_input, input_shape=(1,28,28)),
    ZeroPadding2D((1, 1)),
    Convolution2D(32, 3, 3, activation='relu'),
    MaxPooling2D(),
    ZeroPadding2D((1, 1)),
    Convolution2D(64, 3, 3, activation='relu'),  
    MaxPooling2D(),
    Flatten(),
    Dense(512, activation='relu'),
    Dropout(0.5),
    Dense(10, activation='softmax')
    ])

Batch Normalizationを使うと大きい学習係数を使えると言われているので学習率を10倍にしてみました。

lr=0.01で1epoch学習後にlr=0.001でさらに8epoch学習 (学習率を10倍にする)

loss acc val_loss val_acc
BNなし 0.2219 0.9352 0.1436 0.9582
BNあり 0.0507 0.9886 0.0567 0.9877

BNなしだと 93.5% 程度で止まってしまったのに対して BNありだと 98.8% まで学習が進みました!

確かに効果が確認できました。

CIFAR10

続いてMNISTより難しい分類問題のCIFAR10です。

モデルは Kerasのチュートリアルにあるコードを参考に定義しました。

model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=x_train.shape[1:]))
model.add(Convolution2D(32, 3, 3, activation='relu'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Dropout(0.25))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

50epoch学習した結果

loss acc val_loss val_acc
lr=0.0001、BNなし 0.8875 0.7005 0.8007 0.7398
lr=0.0001、BNあり 0.6417 0.7824 0.7124 0.7671
lr=0.001、BNなし 2.1267 0.2226 2.0676 0.2230
lr=0.001、BNあり 0.5938 0.8006 0.5055 0.8264

MNISTよりも差が顕著に出ました。 学習係数を大きくした lr = 0.001 だと BNなしでは発散してしまっています。

一方、BNありは学習係数を大きくしても学習が進んでいき、 学習係数の大きいlr=0.001 + BNありが最もよい結果になりました。

FC層のみをファインチューニングする場合

Practical Deep Learning For Coders, Part 1の中で幾度となく登場する あらかじめ学習したモデルで最終Conv層の出力を保存しておき、FC層のみをファインチューニングする方法 でもやってみました。

MNIST

FC層のみをlr=0.0001で8epoch学習(lr=0.001で1epoch学習したモデルでconv層出力を計算しておく)

loss acc val_loss val_acc
lr=0.0001, BNなし 0.0170 0.9949 0.0226 0.9918
lr=0.0001, BNあり 0.0144 0.9955 0.0237 0.9923

FC層のみをlr=0.001で8epoch学習(lr=0.01で1epoch学習したモデルでconv層出力を計算しておく)

loss acc val_loss val_acc
lr=0.001, BNなし 0.0664 0.9790 0.0663 0.9801
lr=0.001, BNあり 0.0765 0.9756 0.0704 0.9794

なんと、学習係数の大きい lr=0.001でも BNありと BNなし で差が見られなくなってしまいました。。

CIFAR10

FC層のみをlr=0.0001で25epoch学習(lr=0.0001で25epoch学習したモデルでconv層出力を計算しておく)

loss acc val_loss val_acc
lr=0.0001、BNなし 0.6768 0.7764 0.7716 0.7444
lr=0.0001、BNあり 0.4751 0.8418 0.7227 0.7636

BNありだと学習データのロスがより小さくなりましたが完全に過学習になってます。。

実験結果のまとめ

  • 複雑なモデル、学習率を高くした場合でBatch Normalizationによる安定化効果が効く
  • FC層のファインチューニングだけだとそのメリットが小さくなる。むしろ学習が進みすぎて過学習を招く危険性?!

BNを使うと学習が安定する = 学習が速く進む ということが確認できました。

FC層のファインチューニングだとありがたみが薄れたので学習初期ほどBatch Normalizationによる安定化が効果を発揮するということでしょうか

今回使ったコードはhttps://github.com/tanakatsu/bn-experiments にあります。

fast.aiの記事から

http://www.fast.ai/2017/09/08/introducing-pytorch-for-fastai/

With the increased productivity this enabled, we were able to try far more techniques, and in the process we discovered a number of current standard practices that are actually extremely poor approaches. For example, we found that the combination of batch normalisation (which nearly all modern CNN architectures use) and model pretraining and fine-tuning (which you should use in every project if possible) can result in a 500% decrease in accuracy using standard training approaches. (We will be discussing this issue in-depth in a future post.) The results of this research are being incorporated directly into our framework.

Conv層出力のprecompute + FC層のファインチューニングは良くないと書いてあります。

oh... やはりそうだったのか・・・ !

We will be discussing this issue in-depth in a future post とあるので記事を待ちたいと思います。