TensorFlowをソースからビルドする方法とその効果
TensorFlowをソースからビルドする方法とその効果
はじめに
カブクで機械学習エンジニアをしている大串正矢です。今回はTensorFlowをソースからビルドする方法とその効果について書きます。
背景
機械学習ではトライ&エラーが当たり前です。この回数をできるだけ多くすることでより良いモデルの選定が可能になります。そのために少しでもモデルの学習速度を上げたいので今回はその手段の一つであるTensorFlowをソースからビルドすることによる高速化について紹介します。
TensorFlowをソースからビルドすることによって得られる最適化について
sourceからビルドしていない場合は下記のメッセージが出ます。(TensorFlow1.8.0の場合)CPUに用意されている命令セットAVX2、FMAを使用していないことになります。
CPUでこれらの命令セットに対応している場合はソースからビルドする方が早くなります。
2018-05-01 17:28:49.354524: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
AVX2とは
AVX2を知る前にSIMDについて知る必要があります。SIMDとは一つの命令で複数のデータを処理する手法になります。扱えるデータ数が増えるほど高速になるのが理解できます。特に深層学習の場合は行列を用いた計算が多いのでこのSIMDが効果を発揮します。
下記の動画でC++のforループでSIMDがどのような効果を発揮しているか確認できます。
AVX2を知る前にAVXについて
下記の動画で命令に使用できるレジスターのサイズが増えることにより、アセンブリレベルでの命令数が減ることによる高速化を説明しています。
ここまででAVX2を理解するための下準備としてSIMDとAVXについて説明しました。
AVX2:
wikipediaによると
インテルはHaswellマイクロアーキテクチャから搭載。従来のSIMD整数演算命令が128ビットから256ビットに拡張されるのが主な変更点であるが、要素ごとに独立したシフト量を設定できるシフト命令、非連続なデータを並べ替えながらロードが可能なギャザー命令等の新たな命令も実装される。AMDはExcavatorアーキテクチャからAVX2を実装している
AVX2はSIMDで扱えるデータの量が多く、かつ適用できる命令数も多いので、学習速度の高速化に役立ちます。
FMA
FMAはAVX2命令セットに含まれる命令で、これにより下記のような積和演算を一つの命令で行えます。
a = b*c + d
効果を発揮しそうな分野の仮説
行列演算が多い画像系の処理をCPUで行なっている場合に効果を発揮すると思われます。
TensorFlowをソースからビルドするための手順
- ホスト環境でcudaの環境をバージョンアップしてTensorFlowが動作するか確認
– Docker環境でTensorFlowをソースからビルド
最近は簡単になってきているようですがcudaのインストールは一筋縄ではいきません。
CUDA、cuDNNのバージョンアップ
バージョンアップの手順
- ライブラリの更新
– nvidiaドライバーの更新
ライブラリの更新
TensorFlow1.8で使用可能なcudaとcuDNNの確認
下記のように記述されています。(2018.05.10)
CUDA Toolkit 9.0. For details, see NVIDIA's documentation. Ensure that you append the relevant CUDA pathnames to the LD_LIBRARY_PATH environment variable as described in the NVIDIA documentation.
cuDNN SDK v7. For details, see NVIDIA's documentation. Ensure that you create the CUDA_HOME environment variable as described in the NVIDIA documentation.
CUDAは最新が9.1(2018.05.10時点)なのでTesnorFlowを使用する場合はバージョンを指定してインストールする必要があります。cuDNNは最新が7.1.3(2018.05.10時点)なのでこちらもバージョンに注意しないとCUDAのインストールとcuDNNのインストールに成功してもTensorFlowが動作しなくなるので注意が必要です。
cudaのインストール
Ubuntu16.04から対応なのでUbuntuのバージョンが古い場合は更新する必要があります。
今回はcuda-repo-ubuntu1604_9.0.176-1_amd64.deb
を下記ページからダウンロードして配置します。
下記の手順でインストールします。
sudo dpkg -i cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
sudo apt-get update
sudo apt-get install cuda-9.0
cuDNNのインストール
下記から対象のバージョンのtarファイルを取得
下記の手順でインストールします。
tar -xzvf cudnn-9.0-linux-x64-v7.tgz
sudo cp cuda/include/cudnn.h /usr/local/cuda/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn.h
sudo chmod a+r /usr/local/cuda/lib64/libcudnn*
nvidiaドライバーの更新
前のバージョンの不要なドライバーの削除をします。
sudo apt-get purge nvidia*
下記コマンドを実行して最新のnvidiaドライバーを導入します。再起動しないとドライバの更新が反映されないので再起動しましょう。
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-get install -y nvidia-390
sudo reboot now
ホスト環境でTensorFlowが動作するか確認
仮想環境の構築
pyenvのインストールはpythonのバージョンを指定したい場合だけで良いので標準のpython3(3.5.2)を使用する場合は無理に使用する必要はありません。
Docker上では標準のpython3(3.5.2)を使用しています。
pyenvのインストール方法は下記です。
https://github.com/pyenv/pyenv
pyenvで必要なバージョンのpythonをインストール
pyenv install 3.5.2
先ほどインストールしたpyenvを適用
pyenv local 3.5.2
virtualenvでpythonのバージョンを指定して仮想環境を構築
virtualenv --python=/home/masaya/.pyenv/shims/python tensorflow_latest
TensorFlowの動作確認
source tensorflow_latest/bin/activate
pip install tensorflow-gpu
Pythonインタプリタを起動して動作を確認します。
>> import tensorflow as tf
>> tf.Session()
下記のような出力が出れば成功です。
2018-04-27 11:09:14.051326: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2018-04-27 11:09:14.165599: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:898] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2018-04-27 11:09:14.165860: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1344] Found device 0 with properties:
name: GeForce GTX 1080 major: 6 minor: 1 memoryClockRate(GHz): 1.7335
pciBusID: 0000:01:00.0
totalMemory: 7.93GiB freeMemory: 7.75GiB
2018-04-27 11:09:14.165871: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1423] Adding visible gpu devices: 0
2018-04-27 11:09:15.259196: I tensorflow/core/common_runtime/gpu/gpu_device.cc:911] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-04-27 11:09:15.259242: I tensorflow/core/common_runtime/gpu/gpu_device.cc:917] 0
2018-04-27 11:09:15.259255: I tensorflow/core/common_runtime/gpu/gpu_device.cc:930] 0: N
2018-04-27 11:09:15.260241: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1041] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 7483 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0, compute capability: 6.1)
<tensorflow.python.client.session.Session object at 0x7fe18f379d30>
失敗例(CUDAもしくはcuDNNのバージョンがTensorFlowで使用しているバージョンとあっていない場合もしくはパスが通せていない場合に発生します。)
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
_pywrap_tensorflow_internal = swig_import_helper()
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
_mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
File "/usr/lib/python3.5/imp.py", line 242, in load_module
return load_dynamic(name, filename, file)
File "/usr/lib/python3.5/imp.py", line 342, in load_dynamic
return _load(spec)
ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/tensorflow/__init__.py", line 24, in <module>
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/__init__.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow.py", line 74, in <module>
raise ImportError(msg)
ImportError: Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
_pywrap_tensorflow_internal = swig_import_helper()
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
_mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
File "/usr/lib/python3.5/imp.py", line 242, in load_module
return load_dynamic(name, filename, file)
File "/usr/lib/python3.5/imp.py", line 342, in load_dynamic
return _load(spec)
ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory
Failed to load the native TensorFlow runtime.
See https://www.tensorflow.org/install/install_sources#common_installation_problems
for some common reasons and solutions. Include the entire stack trace
above this error message when asking for help.
以下の出力は一見、成功しているように見えますがドライバーのバージョンがCUDAのバージョンにあっていないエラーでGPUを使用できていません。このようなケースの場合はCUDAに対応しているドライバーに更新し、再起動して新しいドライバーが適用されるようにする必要があります。
2018-04-27 10:51:47.168103: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2018-04-27 10:51:47.176481: E tensorflow/stream_executor/cuda/cuda_driver.cc:406] failed call to cuInit: CUDA_ERROR_NO_DEVICE
2018-04-27 10:51:47.176589: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:158] retrieving CUDA diagnostic information for host: luke
2018-04-27 10:51:47.176618: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:165] hostname: luke
2018-04-27 10:51:47.176698: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:189] libcuda reported version is: 390.30.0
2018-04-27 10:51:47.176901: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:193] kernel reported version is: 384.111.0
2018-04-27 10:51:47.176939: E tensorflow/stream_executor/cuda/cuda_diagnostics.cc:303] kernel version 384.111.0 does not match DSO version 390.30.0 -- cannot find working devices in this configuration
<tensorflow.python.client.session.Session object at 0x7ff7f94b8710>
TensorFlowのソースからのビルド
TensorFlowをソースからビルドすることによってAVX2とFMAを有効にします。
ソースからのビルド時間が長いので行う際は業務の終わりや別の業務の合間などで行う方が良いとおもいます。筆者の環境では50分程度かかりました。
Docker上でビルドしました。理由としてはコンテナで扱うと複数のGPUマシーン間で差分なく使用可能であることと、クラウドに移しても使用可能であることなどです。
Docker環境でのTensorFlowのソースからのビルド
デバイスオプションなどを意識しないためにnvidia-dockerを使用します。
https://github.com/NVIDIA/nvidia-docker
Dockerイメージを取得します。
docker pull nvidia/cuda:9.0-cudnn7-devel
Docker環境でTensorFlowが使用できるか確認します。下記でDockerの環境にアクセスします。
docker run -it --runtime=nvidia --rm nvidia/cuda:9.0-cudnn7-devel bash
DockerイメージでTensorFlowのGPU動作できることを確認します。
必要なライブラリを取得します。
apt-get update
apt-get install -y python3-pip python3-dev
TensorFlowをインストールします。
pip3 install --upgrade tensorflow-gpu
動作を確認します。
$ python3
...
>>> import tensorflow as tf
>>> s = tf.Session()
2018-03-06 07:25:43.710870: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:898] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2018-03-06 07:25:43.711253: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1212] Found device 0 with properties:
name: Tesla K80 major: 3 minor: 7 memoryClockRate(GHz): 0.8235
pciBusID: 0000:00:04.0
totalMemory: 11.17GiB freeMemory: 11.08GiB
2018-03-06 07:25:43.711319: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1312] Adding visible gpu devices: 0
2018-03-06 07:25:43.964388: I tensorflow/core/common_runtime/gpu/gpu_device.cc:993] Creating TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 10739 MB memory) -> physical GPU (device: 0, name: Tesla K80, pci bus id: 0000:00:04.0, compute capability: 3.7)
Dockerfileを用意してビルドします。
TensorFlowのソースビルドに関連する部分を載せておきます。全ての内容が気になる方は弊社への応募を検討してみてください。ソースからビルドする場合は対応するPythonのバージョンもチェックしておいてください。今回はTensorFlowのバージョン1.8.0でPythonのバージョン3.5.2でビルドを行いました。
下記リンク先で各環境における対応しているバージョンを確認できます。
Dockerでビルドする際は対話的やりとりができないので環境変数に設定するなどの処理が必要になります。
Single-source Heterogeneous Programming for OpenCLのオプションを使用したい場合は下記から環境に対応する圧縮ファイルを取得してください。
SYCLは、単一ソースのモダンなC++でOpenCLデバイスを扱うための規格です。下記のようなイメージになります。
https://www.khronos.org/sycl
下記によると行列やベクトル計算を必要とする機械学習においてGPUに適したC++のコードを生成するので並列処理速度が向上するようです。
Machine learning framework TensorFlow requires large amounts of vector and matrix operations. Performance and power consumption can be vastly improved by using parallel computing. ComputeCpp enables developers to target OpenCL devices such as GPUs using modern C++ code.
ライセンスは配布される圧縮ファイルに記述されているのでご利用の際はご確認ください。
################################################################################################
# Bazel Setting
################################################################################################
RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:webupd8team/java && apt-get update
RUN echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
RUN echo debconf shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections
RUN apt-get install -y oracle-java8-installer
RUN apt-get install -y locate
RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
RUN apt-get update && apt-get install -y bazel
RUN curl -LO "https://github.com/bazelbuild/bazel/releases/download/0.11.1/bazel_0.11.1-linux-x86_64.deb" && dpkg -i bazel_*.deb
################################################################################################
# TensorFlow source build
################################################################################################
ARG TENSORFLOW_VERSION=1.8.0
ARG TENSORFLOW_DEVICE=gpu
ARG TENSORFLOW_APPEND=_gpu
ENV TF_NEED_S3=0
ENV TF_NEED_KAFKA=0
ENV TF_NEED_GDR=0
ENV TF_NEED_VERBS=0
ENV TF_NEED_OPENCL_SYCL=1
ENV TF_NEED_COMPUTECPP=1
ENV TF_NEED_OPENCL=1
ENV TF_CUDA_CLANG=0
ENV TF_CUDA_VERSION=9.0
ENV TF_CUDNN_VERSION=7
ENV TF_NEED_TENSORRT=0
ENV TF_NEED_MPI=0
ENV TF_SET_ANDROID_WORKSPACE=0
ENV PYTHON_BIN_PATH=/usr/bin/python3
ENV CC_OPT_FLAGS="--config=opt"
ENV TF_NEED_JEMALLOC=1
ENV TF_NEED_GCP=0
ENV TF_NEED_HDFS=0
ENV TF_ENABLE_XLA=1
ENV TF_NEED_CUDA=1
ENV GCC_HOST_COMPILER_PATH=/usr/bin/gcc
ENV USE_DEFAULT_PYTHON_LIB_PATH=1
ENV HOST_CXX_COMPILER=/usr/bin/g++
ENV CUDA_TOOLKIT_PATH=/usr/local/cuda-9.0
ENV CUDNN_INSTALL_PATH=/usr/local/cuda-9.0
ENV HOST_CXX_COMPILER=/usr/bin/g++
ENV HOST_C_COMPILER=/usr/bin/gcc
ENV COMPUTECPP_TOOLKIT_PATH=/usr/local/computecpp
ENV TF_CUDA_COMPUTE_CAPABILITIES="3.5,5.2"
ENV LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:/usr/local/cuda-9.0/extras/CUPTI/lib64:/usr/local/cuda-9.0/lib64/stubs
ENV CUDA_PATH=/usr/local/cuda-9.0
ENV CLANG_CUDA_COMPILER_PATH=/usr/local/cuda-9.0/bin/nvcc
ADD template/ComputeCpp-CE-0.7.0-Ubuntu.16.04-64bit.tar.gz /home/
RUN mkdir -p /usr/local/computecpp/ && mv /home/ComputeCpp-CE-0.7.0-Ubuntu-16.04-x86_64/* /usr/local/computecpp/
RUN git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git /home/tensorflow && cd /home/tensorflow && git checkout r1.8
RUN echo "/usr/local/cuda-9.0/targets/x86_64-linux/lib/stubs" > /etc/ld.so.conf.d/cuda-9.0-stubs.conf && ldconfig
RUN cd /home/tensorflow && ./configure
RUN cd /home/tensorflow && bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --config=cuda --action_env="LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" -k //tensorflow/tools/pip_package:build_pip_package
RUN cd /home/tensorflow && bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
RUN pip3 install /tmp/tensorflow_pkg/tensorflow-1.8.0-cp35-cp35m-linux_x86_64.whl
ではソースからビルドした結果が正しく反映されているか確認します。
pipでインストールした場合は最初にAVX2とFMAのメッセージが出ます。
<font color="Red">
2018-05-10 14:06:46.264856: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA</font></br>
ソースからビルドして最適化オプションを有効にしてインストールした場合はAVX2とFMAのメッセージが出ません。下記に実行例を示します。
2018-05-10 14:28:01.165038: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:898] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2018-05-10 14:28:01.165422: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1356] Found device 0 with properties:
name: GeForce GTX 1080 major: 6 minor: 1 memoryClockRate(GHz): 1.7335
pciBusID: 0000:01:00.0
totalMemory: 7.93GiB freeMemory: 7.75GiB
2018-05-10 14:28:01.165435: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1435] Adding visible gpu devices: 0
2018-05-10 14:28:01.509180: I tensorflow/core/common_runtime/gpu/gpu_device.cc:923] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-05-10 14:28:01.509197: I tensorflow/core/common_runtime/gpu/gpu_device.cc:929] 0
2018-05-10 14:28:01.509200: I tensorflow/core/common_runtime/gpu/gpu_device.cc:942] 0: N
2018-05-10 14:28:01.509350: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1053] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 7483 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0, compute capability: 6.1)
ソースからビルドした際の効果検証
ここまで時間がかかって効果がない場合はやらない方がマシです。そこで人柱となって効果を検証してみます。
今回のビルドでもっとも効果が期待されるのがCPU側処理の高速化です。そこで下記の例で効果を検証してみました。
Keras(バックエンドがTensorFlow)のExampleケースを使用
https://github.com/keras-team/keras/tree/master/examples
- 画像処理
- mnist: mnist_cnn.py
- cifar10
- CNN: cifar10_cnn.py
- カプセルネット: cifar10_cnn_capsule.py
選定ケースの理由
- cifar10のデータはData augumentation処理があるためこの部分が高速化すれば速度向上が期待できる
- カプセルネットはCNNに比べより行列演算が多くなるため効果が大きく速度向上が期待できる
データの変更に対してどの程度、影響があるのかモデルの構造に対してどの程度影響があるのか見てみるために簡易的でありますが、上記の3ケースを試しました。
マシーンスペック
- OS: Ubuntu 16.04.4 LTS
- メモリー: 32GB
- CPU: Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz (4コア)
- GPU: GeForce GTX 1080
実験条件
ネットワーク速度の影響をなくすために全ての処理はデータは取得済みのケースを対象とします。
- Python 3.5.2
結果
速度比較のためtime
コマンドで時間を測定しました。
ソースからインストールしてDocker上で動作した結果
ソースコード名 | real | user | sys |
---|---|---|---|
mnist_cnn.py | 0m54.261s | 1m8.356s | 0m11.824s |
cifar10_cnn.py | 16m31.682s | 39m58.412s | 5m40.044s |
cifar10_cnn_capsule.py | 14m20.213s | 34m25.948s | 5m30.168s |
pipでインストールしてホスト上で動作した結果
ソースコード名 | real | user | sys |
---|---|---|---|
mnist_cnn.py | 0m55.290s | 1m15.452s | 0m12.232s |
cifar10_cnn.py | 16m40.971s | 39m23.144s | 5m37.640s |
cifar10_cnn_capsule.py | 14m33.171s | 33m45.332s | 5m21.984s |
結果として劇的な向上はせずに微妙に向上しただけでした。予想通り、行列演算の多いカプセルネットで最も効果を発揮していますが向上率としては約2%程度でした。以前は警告として出ていたSSE1, SSE2の命令がpipでインストールする場合も反映されているので速度差があまり出なかったと思われます。
最後に
弊社ではTensorFlowのビルドを失敗なくできる強者や業務効率化に対する飽くなき探究心をお持ちの方も絶賛採用中なので是非、応募してください。
参考
https://machinelearningmastery.com/multivariate-time-series-forecasting-lstms-keras/
https://github.com/tensorflow/tensorflow/issues/16694
https://github.com/bazelbuild/bazel/issues/629
https://github.com/tensorflow/tensorflow/issues/13243
http://math-koshimizu.hatenablog.jp/entry/2017/08/06/151212
https://github.com/keras-team/keras/tree/master/examples
その他の記事
Other Articles
関連職種
Recruit