├── .gitignore ├── README.md ├── doc ├── chainer_basic.md ├── chainer_caffemodel.md ├── chainer_convolution.md ├── chainer_install.md ├── chainer_layer.md ├── chainer_optimizer.md ├── chainer_trainer.md ├── environment.md ├── exercise_1.md ├── mnist.md ├── numpy_1.md ├── numpy_2.md ├── numpy_3.md ├── numpy_4.md ├── numpy_5.md ├── reinforcement.md └── translation.md ├── image └── digit │ ├── digit_0.png │ ├── digit_1.png │ ├── digit_2.png │ ├── digit_3.png │ ├── digit_4.png │ ├── digit_5.png │ ├── digit_6.png │ ├── digit_7.png │ ├── digit_8.png │ └── digit_9.png └── src ├── bouncing ├── make_animation.py └── train.py ├── caffemodel ├── labels.txt └── predict.py ├── ex1 ├── data_test.txt ├── data_train.txt ├── example │ ├── image │ │ └── .gitkeep │ └── train.py ├── image │ └── .gitkeep └── train.py ├── ex1_2 ├── data_test.txt ├── data_train.txt ├── example │ ├── image │ │ └── .gitkeep │ └── train.py ├── image │ └── .gitkeep └── train.py ├── ex2 ├── zundoko.py └── zundoko_lstm.py ├── gan ├── image │ └── .gitkeep └── train.py ├── human_activity ├── make_animation.py └── train_lstm.py ├── mnist ├── net.py ├── predict.py └── train.py ├── open_ai_gym └── train.py ├── translation ├── dataset │ ├── dataset.json │ └── dev.json ├── make_dataset.py ├── model │ └── .gitkeep └── train.py └── vae ├── image └── .gitkeep ├── net.py ├── train.py └── train_m2.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.model 3 | *.caffemodel 4 | src/**/*.png 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deep Learning 2 | 3 | ## 実行環境 4 | 5 | * [Chainer](http://chainer.org/) 1.15 6 | * [Pillow](http://pillow.readthedocs.io/en/3.0.x/index.html) 7 | 8 | ## 目次 9 | 10 | ### 準備 11 | 12 | * [Deep Learning 開発に必要な環境](/doc/environment.md) 13 | * [Chainerのインストール方法](/doc/chainer_install.md) 14 | 15 | ### Numpyの基本 16 | 17 | * [Numpyについて、配列の生成](/doc/numpy_1.md) 18 | * [要素へのアクセス](/doc/numpy_2.md) 19 | * [配列の変形と連結](/doc/numpy_3.md) 20 | * [配列の演算](/doc/numpy_4.md) 21 | * [統計処理と線形代数](/doc/numpy_5.md) 22 | 23 | ### Chainerを使ったDeep Lerningの実践 24 | 25 | * [手書き数字の認識](/doc/mnist.md) 26 | * [Chainerの基本的な使い方](/doc/chainer_basic.md) 27 | * [Convolutional Neural Network](/doc/chainer_convolution.md) 28 | * [Layerについて](/doc/chainer_layer.md) 29 | * [最適化アルゴリズム](/doc/chainer_optimizer.md) 30 | * [Caffe modelの使用](/doc/chainer_caffemodel.md) 31 | * [翻訳](/doc/translation.md) 32 | * [強化学習](/doc/reinforcement.md) 33 | 34 | ### 演習 35 | 36 | * [演習1 領域の分割](/doc/exercise_1.md) 37 | 38 | ### その他 39 | 40 | * [ChainerのTrainerについて](/doc/chainer_trainer.md) 41 | 42 | ### 参考資料 43 | 44 | * [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/) ([日本語訳](http://nnadl-ja.github.io/nnadl_site_ja/index.html)) 45 | * Convolutional Neural Network 46 | * [How do Convolutional Neural Networks work?](http://brohrer.github.io/how_convolutional_neural_networks_work.html) 47 | * [Convolution arithmetic](https://github.com/vdumoulin/conv_arithmetic) 48 | * [Convolutional Neural Networks (CNNs): An Illustrated Explanation](http://xrds.acm.org/blog/2016/06/convolutional-neural-networks-cnns-illustrated-explanation/) 49 | * Optimizer 50 | * [An overview of gradient descent optimization algorithms](http://sebastianruder.com/optimizing-gradient-descent/) [日本語訳](http://postd.cc/optimizing-gradient-descent/) 51 | * Recurrent Neural Network, LSTM 52 | * [わかるLSTM ~ 最近の動向と共に](http://qiita.com/t_Signull/items/21b82be280b46f467d1b) 53 | * [Understanding LSTM Networks](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) [日本語訳](http://qiita.com/KojiOhki/items/89cd7b69a8a6239d67ca) 54 | -------------------------------------------------------------------------------- /doc/chainer_basic.md: -------------------------------------------------------------------------------- 1 | # Chainerの基本的な使い方 2 | 3 | Chainerに限らずニューラルネットワークのフレームワークは機能ごとにモジュール化されており、必要な機能を組み合わせて目的に沿ったニューラルネットワークを構築したり、学習を行ったりすることが容易になっている。 4 | 5 | 注意: ここの説明はTrainerを使用していないためChainer公式のMNISTデータセットの学習とは異なる。Trainerを使用しない理由は[ChainerのTrainerについて](chainer_trainer.md)を参照すること。 6 | 7 | ## 学習とは 8 | 9 | ニューラルネットワークのパラメータを最適な値に調整することを指す。 10 | 11 | ## ニューラルネットワークを使った教師あり学習の流れ 12 | 13 | ### データセットを用意する 14 | 15 | 通常以下の3つを用意する。それぞれ入力データと教師データとがある。 16 | 17 | * 学習データ (train data) 18 | パラメータ学習に使用するデータ 19 | * validationデータ (validation data) 20 | どのiteration/epochでのモデルが最適であるか比較したり、ハイパーパラメータのどの値が適切かを比較するのに使用するデータ 21 | * テストデータ (test data) 22 | 学習後のモデルを評価するのに使用するデータ 23 | 24 | ### ニューラルネットワークとoptimizerを構築する 25 | 26 | * ニューラルネットワークを構築する 27 | ニューラルネットワークの各層はモジュール化されており、モジュールを選択して結合することで容易に構築できるようになっている。必要ならパラメータをファイルから読み込む 28 | * optimizerを構築する 29 | どのoptimizerを使用するか決め、ニューラルネットワークと関連付ける 30 | 31 | ### 学習 32 | 33 | 以下の処理を繰り返して学習を行う。以下の処理1回を1 iteration と呼ぶ。これに対して学習データを一通り使用するまでiterationを繰り返すことを1 epochと呼ぶ 34 | 35 | * 学習データをニューラルネットワークに入力する 36 | * ニューラルネットワークの出力と正解データから損失を計算する 37 | * 損失から各パラメータの勾配を求める 38 | * 勾配を基にパラメータを更新する 39 | 40 | ### 学習後のパラメータをファイルに保存する 41 | 42 | 学習後のパラメータを保存しておいて予測時に使用する 43 | 44 | ## 教師あり学習の詳細 45 | 46 | ### データセットを用意する 47 | 48 | データセットごとに異なる。以下にMNISTデータの場合について述べる。 49 | 50 | #### 読み込み 51 | 52 | Chainerでは`chainer.datasets.get_mnist`を使うことでMNISTデータセットを取得することができる。 53 | 内部ではデータセットのダウンロードを行っているので初回呼び出し時にはインターネット環境に接続している必要がある。 54 | 55 | 以下のようにするとtrain_dataに学習データが、test_dataにテストデータが格納される。 56 | 57 | ``` 58 | > import chainer 59 | > train_data, test_data = chainer.datasets.get_mnist() 60 | ``` 61 | 62 | 学習データとvalidationデータを分離する場合には`chainer.datasets.split_dataset_random`を使う。 63 | 64 | ``` 65 | > train_data, valid_data = chainer.datasets.split_dataset_random(train_data, len(train_data) - 5000) 66 | ``` 67 | 68 | #### データの取得 69 | 70 | `Iterator`を使うことで学習データ、テストデータを順に取得することができる。 71 | `Iterator`については[Chainer Referance ManualのIterator examples](http://docs.chainer.org/en/stable/reference/iterators.html)を参照のこと。 72 | 73 | ``` 74 | > batch_size = 100 75 | > train_iterator = chainer.iterators.SerialIterator(train_data, batch_size) 76 | > batch = train_iterator.next() 77 | ``` 78 | 79 | `batch`はlistで、各要素は1枚の画像を表すnumpy配列と正解ラベルを表す整数とのtupleである。 80 | これを複数画像のnumpy配列と正解ラベルのnumpy配列に変換するには`chainer.dataset.convert.concat_examples`を使う。 81 | 82 | ``` 83 | > from chainer.dataset import convert 84 | > x, t = convert.concat_examples(batch) 85 | ``` 86 | 87 | ### ニューラルネットワークを構築する 88 | 89 | 以下にFully Connected Layer 3層からならニューラルネットワークの例を挙げる。 90 | 91 | ``` 92 | class MLP(chainer.Chain): 93 | 94 | def __init__(self, n_in, n_out, n_hidden): 95 | # Networkの持つLinkを定義する 96 | # superクラスの__init__を使う方法と 97 | # add_link()メソッドで追加する方法とがある 98 | # Chainer1.12からL.Linear()の第1引数はNoneでよく、 99 | # その場合入力サイズは実際のデータから自動的に決まる 100 | super(MLP, self).__init__( 101 | l1=L.Linear(n_in, n_hidden), 102 | l2=L.Linear(n_hidden, n_hidden), 103 | l3=L.Linear(n_hidden, n_out), 104 | ) 105 | 106 | def __call__(self, x, train=True): 107 | # Linkはcallableとなっており、関数として呼び出すとLinkの処理 108 | # L.LinearはWx + bを計算する(W, bはL.Linearが持つ重み行列とバイアス項) 109 | h = self.l1(x) 110 | # Dropoutを実行する 111 | # Dropoutは学習時と予測時とで挙動が異なるので、trainでどちらであるかを指定する必要がある 112 | h = F.dropout(h, 0.5, train=train) 113 | # ReLUを実行する 114 | h = F.relu(h) 115 | h = self.l2(h) 116 | h = F.dropout(h, 0.5, train=train) 117 | h = F.relu(h) 118 | h = self.l3(h) 119 | return h 120 | ``` 121 | 122 | クラスの定義は以下のようになる。 123 | 124 | * `chainer.Chain`を継承したクラスを定義する 125 | * `__init__`で必要な`link`を追加する。`link`はパラメータつきの層として機能し、ここで追加した`link`の持つパラメータが学習対象のパラメータとなる。 126 | * `__call__`で各層をどう結合するかを定義する。 127 | 128 | `__init__`と`__call__`の引数は自由に決めることができる。例えば`__init__`の引数に中間層の大きさを渡したり、`__call__`が複数の入力データを受け付けるようにすることができる。 129 | 130 | 以下のようにニューラルネットワークのインスタンスを生成する。 131 | 132 | ``` 133 | net = MLP(28 * 28, 10, 100) 134 | ``` 135 | 136 | ### optimizerを構築する 137 | 138 | optimizerの構築は、optimizerのインスタンスを生成して`setup`メソッドでニューラルネットワークと関連付けるだけである。 139 | `chainer.optimizers`以下に複数の最適化アルゴリズムのモジュールがあり、使用したいものを選ぶことができる。 140 | 141 | ``` 142 | from chainer import optimizers 143 | 144 | optimizer = optimizers.Adam() 145 | optimizer.setup(net) 146 | ``` 147 | 148 | ### 学習を行う 149 | 150 | #### 学習データをニューラルネットワークに入力する 151 | 152 | ニューラルネットワークに入力するには 153 | * 入力のnumpy配列(またはcupy配列)から`chainer.Variable`インスタンスを生成する。(省略可) 154 | * ニューラルネットワークインスタンスを関数として呼び出す。このとき`chainer.Variable`インスタンスをの引数とする。 155 | 156 | ``` 157 | y = net(chainer.Variable(x), train=True) 158 | ``` 159 | 160 | Chainer 1.10から以下のように`chainer.Variable`インスタンス生成を省略できるようになった。numpy配列を直接渡した場合には内部で`Variable`インスタンスを生成する。 161 | 162 | ``` 163 | y = net(x, train=True) 164 | ``` 165 | 166 | #### ニューラルネットワークの出力と正解データから損失を計算する 167 | 168 | ここでは画像分類でよく使われる損失関数(loss function, cost function)を計算する。 169 | 170 | ``` 171 | from chainer import functions as F 172 | 173 | loss = F.softmax_cross_entropy(y, chainer.Variable(t)) 174 | ``` 175 | 176 | 以下のように`chainer.Variable`の省略が可能である。 177 | 178 | ``` 179 | loss = F.softmax_cross_entropy(y, t) 180 | ``` 181 | 182 | #### 損失から各パラメータの勾配を求める 183 | 184 | 以下のように`cleargrads`メソッドでパラメータの勾配を初期化し、`backward`メソッドで勾配を計算する。 185 | 186 | ``` 187 | net.cleargrads() 188 | loss.backward() 189 | ``` 190 | 191 | Chainer 1.14までは勾配初期化に`zerograds`メソッドを使用していたが1.15からdeprecatedとなった。 192 | 193 | #### 勾配を基にパラメータを更新する 194 | 195 | optimizerの`update`メソッドを呼ぶだけである。 196 | 197 | ``` 198 | optimizer.update() 199 | ``` 200 | 201 | ### 学習後のパラメータをファイルに保存する 202 | 203 | パラメータをファイルに保存するには`chainer.serializers`を使う。 204 | ここでは`save_npz`メソッドを使って保存する例を挙げる。 205 | 206 | ``` 207 | from chainer import serializers 208 | 209 | serializers.save_npz('mnist.model', net) 210 | ``` 211 | 212 | `save_npz`メソッドで保存したファイルは`load_npz`メソッドで読み込むことができる。 213 | 214 | ``` 215 | serializers.load_npz('mnist.model', net) 216 | ``` 217 | 218 | `serializers`には他にも保存・読み込みを行うためのメソッドがある。 219 | 詳細は[Chainer Reference ManualのSerializersの項](http://docs.chainer.org/en/stable/reference/serializers.html)を参照すること。 220 | 221 | ## ニューラルネットワークを使った予測 222 | 223 | ### ニューラルネットワークを構築する 224 | 225 | 学習時と同様にニューラルネットワークのインスタンスを生成した後、ファイルからパラメータを読み込む。 226 | 227 | ``` 228 | from chainer import serializers 229 | 230 | net = MLP(28 * 28, 10, 100) 231 | serializers.load_npz('mnist.model', net) 232 | ``` 233 | 234 | ### 入力データを生成する 235 | 236 | 画像を読み込み、numpy配列(またはcupy配列)に変換する。ここではPillowを使って画像を読み込んでいる。注意する点として、学習データの値の範囲が0~1で、背景が黒(0)なので、予測時の入力データも同様になるように変換する必要がある。 237 | 238 | 複数の画像を一度に入力することも可能である。その場合入力となる配列のshapeは(画像枚数, 画像のピクセル数)となる 239 | 240 | ``` 241 | import numpy as np 242 | from PIL import Image 243 | 244 | image = Image.open('sample.png').convert('L').reseize((28, 28), Image.BILINEAR) 245 | image = 1 - np.asarray(image).astype(np.float32) / 255 246 | image = image.reshape((1, -1)) 247 | ``` 248 | 249 | ### ニューラルネットワークに入力する 250 | 251 | ニューラルネットワークインスタンスに入力となる配列を渡す。今回使用する`MLP`クラスは、引数として学習時かどうかを判別する`train`をとるが、今は予測時なので`False`を渡す。 252 | 253 | `chainer.Variable`の`volatile=True`は出力が呼び出された`function`への参照を持たないことを意味する。`volatile`を有効にすると`function`の呼び出しを逆順にたどれなくなるのでバックプロパゲーションができなくなるが、消費メモリ量は減る。 254 | 255 | ``` 256 | y = net(chainer.Variable(image, volatile=True), train=False) 257 | ``` 258 | 259 | 以下のように`chainer.Variable`を省略することが可能だが、無駄なメモリ消費を抑えるために`Variable`を使用して`volatile`を有効にしたほうが良い。 260 | 261 | ``` 262 | y = net(image, train=False) 263 | ``` 264 | 265 | ### Softmax値を求める 266 | 267 | 出力結果としてどのラベルが選ばれたかを知るためにはニューラルネットワークのどの出力が最大であるかわかればよいが、出力の意味をわかりやすくするためにSoftmax値を求める。 268 | Softmax値を求めるには`chainer.functions.softmax`を使用する。 269 | 出力`Variable`で、`data`プロパティを参照することでnumpy配列(またはcupy配列)が得られる。 270 | 271 | ``` 272 | from chainer import functions as F 273 | 274 | result = F.softmax(y).data 275 | ``` 276 | -------------------------------------------------------------------------------- /doc/chainer_caffemodel.md: -------------------------------------------------------------------------------- 1 | # Caffe modelの使用 2 | 3 | ## Caffe modelとは 4 | Deep Learningフレームワークである[Caffe](http://caffe.berkeleyvision.org/)を使って学習したモデルである。多数のモデルファイルが公開されており、研究用途で使われることが多い。画像分類に使われるモデルをそのまま使用したり、画像の特徴量を抽出して別の用途(例えば物体検出、キャプション生成など)に使用することができる。 5 | 6 | ## Caffe modelの属性の調べ方 7 | 8 | Caffe modelはprototextファイルに記述されている。 9 | prototxt内のレイヤー定義については[Caffe公式ドキュメントのLayers](http://caffe.berkeleyvision.org/tutorial/layers.html)を参照すること。 10 | 11 | 例えば[GoogleNet](https://github.com/BVLC/caffe/tree/master/models/bvlc_googlenet)の[train_val.prototxt](https://github.com/BVLC/caffe/blob/master/models/bvlc_googlenet/train_val.prototxt)から次のことがわかる 12 | 13 | * 入力は`data`レイヤー 14 | * `transform_param`から入力の画像サイズは224、BGRの平均値がそれぞれ104, 117, 123である 15 | * 出力は`loss3/classifier` 16 | 17 | ## Caffe modelの読み込み 18 | 19 | caffemodelファイルへのパスを指定して`chainer.functions.caffe.CaffeFunction`のインスタンスを生成する。 20 | 21 | 例: 22 | 23 | ``` 24 | from chainer.functions import caffe 25 | 26 | model = caffe.CaffeFunction('bvlc_googlenet.caffemodel') 27 | ``` 28 | 29 | ## Caffe modelの実行 30 | 31 | 生成したインスタンスを関数として呼び出す 32 | * 入力 33 | * `inputs`: 入力データを`dict`形式で渡す。`dict`のkeyはモデルに依存する 34 | * `outputs`: 出力レイヤー名の`list` 35 | * `disable`: 使用しないレイヤー名の`list`を渡す。出力レイヤーに関与しないレイヤーがある場合に指定する 36 | * `train`: Trueなら学習モード、それ以外はテストモードになる。back propagationが必要な場合はTrueを指定する 37 | * 出力 38 | * 指定したレイヤーの出力の`tuple` 39 | 40 | 例: 41 | 42 | ``` 43 | y, = model( 44 | inputs={'data': chainer.Variable(x, volatile=True)}, 45 | outputs=['loss3/classifier'], 46 | disable=['loss1/ave_pool', 'loss2/ave_pool'], 47 | train=False) 48 | ``` 49 | 50 | * 入力はnumpyもしくはcupy配列である 51 | * 入力のshapeは(mini_batch, color, height, width)であることが多い。 52 | * 入力からは平均画像を引く必要がある。 53 | 平均画像はモデルによって異なる。 54 | * 色空間はRGBではなくBGRであることが多い。 55 | 56 | ## サンプルプログラム 57 | 58 | ### ソースディレクトリ 59 | 60 | (root dir)/src/caffemodel 61 | 62 | ### 実行方法 63 | 64 | ``` 65 | $ cd src/caffemodel 66 | $ python predict.py image_dir 67 | ``` 68 | 69 | オプション: 70 | * `-m ` : GoogleNetモデルのファイルパス(default: bvlc_googlenet.caffemodel) 71 | * `-l