catalinaの備忘録

ソフトウェアやハードウェアの備忘録。後で逆引きできるように。

kerasを試す

この記事は以前下書きしたものを公開し忘れていたものです。

情報が古い恐れがありますのでご注意ください。

リモートワークでいつもと違う環境で仕事しています。かたりぃなです。 通勤時間がゼロなので、睡眠時間と勉強時間が増えていい感じです。 とはいえ自宅にはゲームなどの誘惑があるので、電源やLANを引っこ抜いておくなどの物理的対策を施しておく必要があります。

今回はDeepLearningフレームワークのKerasを試してみます。

動機

chainerの最終リリースが行われ、これが最終バージョンとなるそうです。 最新のDeepLearningを追いたい人はPyTorchへどうぞとのことです。

とはいえ、折角選んだchainerというフレームワークが終わってしまうので、そのままどうぞとガイドに従うのも少々嫌です。 ので、導入が簡単ときいたことのあるkerasを試してみます。

kerasはバックエンドを切り替えることができるらしいです。 一旦デフォルトのtensor flowで動かしてみて、慣れてきたらCNTK(Microsoft Cognitive toolkit)とかに変えて試したみたいなとか思っています。

環境構築

vscodeのコンテナ機能を使って簡単に試してみます

手元の環境は

です。

早速やっていきます。まずは実験用のコンテナを作ります。

  1. コマンドパレット(Ctrl + Shift + 'P')を開く
  2. コマンドパレットに'Remote'と入力。候補が表示される
  3. 表示された候補から'Remote-Containers: Open Workspace In Container'を選択
  4. 言語やフレームワークの選択で、Python3(Develop python3 applications)を選択する。

dockerfileのビルドが行われ、コンテナが起動します。 dockerfileやコンテナ起動時のパラメータ類は.devcontainerに格納されます

早速動かしてみましたが、ダメでしたので、設定変更しておきます。

コンテナの設定を変更する

pythonのバージョンを確認する KerasのバックエンドであるTensorFlowがpython3.7までしか対応していないとのことでした。(2020.02.28現在) バージョンを確認して、合ってないようなら修正します。

$ python -V
Python 3.8.1

はいダメですね。

dockerfileのfrom行で指定しているpythonのバージョンを細かく指示しておきましょう。

FROM python:3

FROM python:3.7

として保存します。

そしてvscodeを開きなおすと、「dockerfileが変更されているけどどうするか。rebuild or ignore」という選択肢が出るので、rebuildを選択してしばし待ちます。 暇なら"detail"をクリックしてログでも眺めておきましょう。

シェルが起動したら再度バージョンを確認。

$python -V
Python 3.7.6

よさそうです。 これでTensor Flowが入ります。あとでdockerfileに書くか、コミットしましょう。

apt-get update
pip3 install tensorflow
pip3 install keras

トラブルシューティング詳細

TensorFlowのPythonインターフェースを使うには、以下のurlにあるsystem requirementにあわせる必要があります ここにないバージョンの場合は修正する。(3.8 -> 3.7) https://www.tensorflow.org/install/pip

kerasの動作確認

サンプルコードで動作確認をします サンプルコードは

git clone https://github.com/keras-team/keras.git

で持ってこれます examplesに色々入ってる。 中身はchainerのやつと似たり寄ったりですね。

examplesの動かし方

cd keras/examples python ./mnist_mlp.py

ログ

Using TensorFlow backend.
2020-02-03 00:10:50.371771: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer.so.6'; dlerror: libnvinfer.so.6: cannot open shared object file: No such file or directory
2020-02-03 00:10:50.371973: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer_plugin.so.6'; dlerror: libnvinfer_plugin.so.6: cannot open shared object file: No such file or directory
2020-02-03 00:10:50.372012: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:30] Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 3s 0us/step
60000 train samples
10000 test samples
2020-02-03 00:10:55.722601: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory
2020-02-03 00:10:55.722728: E tensorflow/stream_executor/cuda/cuda_driver.cc:351] failed call to cuInit: UNKNOWN ERROR (303)
2020-02-03 00:10:55.722776: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (2a25a8fd3a58): /proc/driver/nvidia/version does not exist
2020-02-03 00:10:55.723133: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-02-03 00:10:55.738064: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2904000000 Hz
2020-02-03 00:10:55.738448: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5591706d4e20 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-02-03 00:10:55.738608: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 7s 115us/step - loss: 0.2429 - accuracy: 0.9252 - val_loss: 0.1477 - val_accuracy: 0.9557
Epoch 2/20

ログをざっくり翻訳

mnistデータのダウンロードしてくれてますね。 ダウンロードしたデータセット~/.keras/datasets/に置かれるようです。

なんか警告がたくさん出てるけど、動かすだけなので今は無視します。NVidiaのDeepLearningSDKが入ってないとか、CUDAが入ってないとかそういうの。 cuInitでCUDA初期化失敗したり、カーネルモードドライバが無いと言ってたり。 さらに、CPUのSIMD命令を使おうとしたけどそれもダメでしたと(AVX2) 一言で言うと「学習すごく時間かかるよ」ってことですね。 GPUなし、CPUのSIMD拡張命令も無しってことなので。

ネットワーク確認

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706

コードでいうと以下の箇所と一致します。

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))

入門でよくあるmnistの3層のNNです。 Denseで生成される関数は output = activation(dot(input, kernel) + bias)とのことなので、そのまま解釈すればよさそうです。

  • dense_1,dense_2では512個のユニットがあり、
  • 活性化関数RELUを通して出力する
  • 念のため。dotはいわゆる内積。重みと入力を掛けて足す
  • ログ中のParamは各層の結合数 + ユニット数

ログ中のParamの値は、たとえばdense_1はMNISTの784次元のデータが入力されるので 784 * 512 + 512 = 401920 ということですね。 最初の512が重み係数をもつユニット数で、次の512がバイアスですね。 同様にdense_2は 512 * 512 + 512 で 262656となります。

感想と今後の展望

思ったより簡単に動きました。 マニュアルも普通に読めますし、当面はこれでいいかなといったところです。 それでは今回はこれくらいで。