RasPi OneでTensorflow/Kerasを動かす。

最近使ってなかったRasPi OneにTensorflowとKerasを入れてみた。
モデル: [Raspbeery Pi 1 MODEL B+](https://www.raspberrypi.org/products/raspberry-pi-1-model-b/)
OS: Linux raspberrypi 4.9.59+ #1047 Sun Oct 29 11:47:10 GMT 2017 armv6l GNU/Linux (NOOBS_v2_4_4.zip)
Python: 2.7.13(Systemに標準でインストール済みのもの)

#RasPi再インストール
2年近く前に使ってそのままだったので、OSから入れ替え
[The initial Raspberry Pi setup without monitor](http://geek-mag.com/posts/255084/)を参考に、ディスプレーとかキーボード無しでUSB-Serial変換ケーブル(とノートPC)でインストール。USB-Serial変換ケーブルは[これ](https://www.amazon.co.jp/gp/product/B00K7YYFNM/)を買った。
注1) NOOBS_v2_4_4.zipでは、/mnt/os/Raspbian内にflavours.jsonというのは無いので、何もしなくて良い。
注2) /mnt/recovery.cmdlineの内容が違うが、とにかくruninstallerとsilentinstallを最初と最後につけとけば良い。
注3) wpasupplicantやwireless-toolsは入っているので、下記を見て設定
https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md

#Tensorflowインストール

[RasPiでKeras/TensorFlowを動かす](http://qiita.com/kazunori279/items/1e23679c534a49c0e837)を参考に入れ始めたが、環境の違い(今時RasPi Oneは非力だ)からかところどころ引っかかったので、メモとして残しておく。

上記記事の通り、普通に入れるとコンパイルが終わらないので、[Cross-compiling TensorFlow for the Raspberry Pi](https://petewarden.com/2017/08/20/cross-compiling-tensorflow-for-the-raspberry-pi/)を参考に

```
sudo apt-get install libblas-dev liblapack-dev python-dev \
libatlas-base-dev gfortran python-setuptools
​sudo pip install \
http://ci.tensorflow.org/view/Nightly/job/nightly-pi-zero/lastSuccessfulBuild/artifact/output-artifacts/tensorflow-1.4.0-cp27-none-any.whl
```
10分くらいですかね。
注) インストールファイル名が変わっている場合があるので、 http://ci.tensorflow.org/view/Nightly/job/nightly-pi-zero/lastSuccessfulBuild/artifact/output-artifacts/
の最新のファイルを確認して読み替えてください。でないとNot Found urlと怒られます。
pip2なかったのでpipでインストールしてます。

例えば[詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~](https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-TensorFlow%E3%83%BBKeras%E3%81%AB%E3%82%88%E3%82%8B%E6%99%82%E7%B3%BB%E5%88%97%E3%83%87%E3%83%BC%E3%82%BF%E5%87%A6%E7%90%86-%E5%B7%A3%E7%B1%A0-%E6%82%A0%E8%BC%94/dp/4839962510/)のロジスティック回帰の[サンプルコード](
https://github.com/yusugomori/deeplearning-tensorflow-keras/blob/master/3/tensorflow/01_logistic_regression_or_tensorflow.py)を動かすと、いろいろwarningでますが、ちゃんと学習できる。

```
pi@raspberrypi:~ $ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170124] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> import numpy as np
>>> tf.set_random_seed(0)
>>> w = tf.Variable(tf.zeros([2, 1]))
2017-11-11 01:51:50.193050: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "ParallelInterleaveDataset" device_type: "CPU"') for unknown op: ParallelInterleaveDataset
2017-11-11 01:51:50.195187: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DenseToSparseBatchDataset" device_type: "CPU"') for unknown op: DenseToSparseBatchDataset
2017-11-11 01:51:50.197338: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "GroupByWindowDataset" device_type: "CPU"') for unknown op: GroupByWindowDataset
2017-11-11 01:51:50.200289: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "IgnoreErrorsDataset" device_type: "CPU"') for unknown op: IgnoreErrorsDataset
2017-11-11 01:51:50.202929: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DatasetToSingleElement" device_type: "CPU"') for unknown op: DatasetToSingleElement
2017-11-11 01:51:50.204565: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "SerializeIterator" device_type: "CPU"') for unknown op: SerializeIterator
2017-11-11 01:51:50.205781: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DeserializeIterator" device_type: "CPU"') for unknown op: DeserializeIterator
2017-11-11 01:51:50.206986: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "MapAndBatchDataset" device_type: "CPU"') for unknown op: MapAndBatchDataset
2017-11-11 01:51:50.208620: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "SqlDataset" device_type: "CPU"') for unknown op: SqlDataset
2017-11-11 01:51:50.215151: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "ScanDataset" device_type: "CPU"') for unknown op: ScanDataset
>>> b = tf.Variable(tf.zeros([1]))
>>> x = tf.placeholder(tf.float32, shape=[None, 2])
>>> t = tf.placeholder(tf.float32, shape=[None, 1])
>>> y = tf.nn.sigmoid(tf.matmul(x, w) + b)
>>> cross_entropy = - tf.reduce_sum(t * tf.log(y) + (1 - t) * tf.log(1 - y))
>>> train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)
>>> correct_prediction = tf.equal(tf.to_float(tf.greater(y, 0.5)), t)
>>> X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
>>> Y = np.array([[0], [1], [1], [1]])
>>> init = tf.global_variables_initializer()
>>> sess = tf.Session()
>>> sess.run(init)
>>> for epoch in range(200):
...     sess.run(train_step, feed_dict={
...         x: X,
...         t: Y
...     })
... 
2017-11-11 01:51:58.221900: W tensorflow/core/grappler/utils.cc:48] Node MatMul_fused is not in the graph.
2017-11-11 01:51:58.229164: W tensorflow/core/grappler/utils.cc:48] Node gradients/MatMul_grad/MatMul_1_fused is not in the graph.
2017-11-11 01:51:58.230564: W tensorflow/core/grappler/utils.cc:48] Node gradients/MatMul_grad/MatMul_fused is not in the graph.
>>> classified = correct_prediction.eval(session=sess, feed_dict={
...     x: X,
...     t: Y
... })
2017-11-11 01:52:01.650931: W tensorflow/core/grappler/utils.cc:48] Node MatMul_fused is not in the graph.
>>> prob = y.eval(session=sess, feed_dict={
...     x: X
... })
2017-11-11 01:52:01.757437: W tensorflow/core/grappler/utils.cc:48] Node MatMul_fused is not in the graph.
>>> print('classified:')
classified:
>>> print(classified)
[[ True]
 [ True]
 [ True]
 [ True]]
>>> print()
()
>>> print('output probability:')
output probability:
>>> print(prob)
[[ 0.22355042]
 [ 0.91425949]
 [ 0.91425949]
 [ 0.99747413]]
>>> 
```
#Kerasインストール
Kerasを入れるのに[Keras Documentation/Installation](https://keras.io/#installation)通りに sudo pip install keras とするとscipyのコンパイルが終わらないので、先にh5pyとscipyをapt-getで入れておく。

```
sudo apt-get install python-h5py
sudo apt-get install python-scipy
```

これで、数分程度でKerasがインストールできる。

```
sudo pip install keras
```

注)下記Keras作者のサンプルを試すなら、Kerasのバージョンを2.0.0でインストールしないと怒られるものがあります。
参考) https://github.com/rcmalli/keras-squeezenet/issues/13

```
sudo pip install keras==2.0.0
```

Keras作者の[Trained image classification models for Keras](https://github.com/fchollet/deep-learning-models)中のExamples/Classify imagesを試してみる。


```
git clone https://github.com/fchollet/deep-learning-models
cd deep-learning-models/
```
注) 上記は[こっち](https://keras.io/applications/)に移設され、git cloneしなくても関数とかKerasのlibraryに取り込まれているみたい。

以下のimg_pathの画像は自分でどこからか持ってきて、カレントディレクトリに置いてください。

```
pi@raspberrypi:~/deep-learning-models $ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170124] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> 
>>> from resnet50 import ResNet50
Using TensorFlow backend.
>>> from keras.preprocessing import image
>>> from imagenet_utils import preprocess_input, decode_predictions
>>> 
>>> model = ResNet50(weights='imagenet')
2017-11-11 03:18:06.604538: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "ParallelInterleaveDataset" device_type: "CPU"') for unknown op: ParallelInterleaveDataset
2017-11-11 03:18:06.606494: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DenseToSparseBatchDataset" device_type: "CPU"') for unknown op: DenseToSparseBatchDataset
2017-11-11 03:18:06.608764: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "GroupByWindowDataset" device_type: "CPU"') for unknown op: GroupByWindowDataset
2017-11-11 03:18:06.611166: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "IgnoreErrorsDataset" device_type: "CPU"') for unknown op: IgnoreErrorsDataset
2017-11-11 03:18:06.613975: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DatasetToSingleElement" device_type: "CPU"') for unknown op: DatasetToSingleElement
2017-11-11 03:18:06.615980: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "SerializeIterator" device_type: "CPU"') for unknown op: SerializeIterator
2017-11-11 03:18:06.617237: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "DeserializeIterator" device_type: "CPU"') for unknown op: DeserializeIterator
2017-11-11 03:18:06.618451: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "MapAndBatchDataset" device_type: "CPU"') for unknown op: MapAndBatchDataset
2017-11-11 03:18:06.620052: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "SqlDataset" device_type: "CPU"') for unknown op: SqlDataset
2017-11-11 03:18:06.626449: E tensorflow/core/framework/op_kernel.cc:1142] OpKernel ('op: "ScanDataset" device_type: "CPU"') for unknown op: ScanDataset
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/nn_impl.py:664: calling reduce_mean (from tensorflow.python.ops.math_ops) with keep_dims is deprecated and will be removed in a future version.
Instructions for updating:
keep_dims is deprecated, use keepdims instead
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.py:1062: calling reduce_prod (from tensorflow.python.ops.math_ops) with keep_dims is deprecated and will be removed in a future version.
Instructions for updating:
keep_dims is deprecated, use keepdims instead
>>> 
>>> img_path = 'African_Bush_Elephant.jpg'
>>> img = image.load_img(img_path, target_size=(224, 224))
>>> x = image.img_to_array(img)
>>> x = np.expand_dims(x, axis=0)
>>> x = preprocess_input(x)
>>> 
>>> preds = model.predict(x)
2017-11-11 03:25:55.292233: W tensorflow/core/grappler/utils.cc:48] Node fc1000/MatMul_fused is not in the graph.
>>> print('Predicted:', decode_predictions(preds))
('Predicted:', [[(u'n02504458', u'African_elephant', 0.91709477), (u'n01871265', u'tusker', 0.041888889), (u'n02504013', u'Indian_elephant', 0.035944905), (u'n03743016', u'megalith', 0.0016836942), (u'n01704323', u'triceratops', 0.0011915577)]])
```
注1) 上記サイトのサンプルでは import numpy as np が抜けてます。
注2) model = ResNet50(weights='imagenet') 実行時に、Segmentation faultが起きたのですが、[RasPiでKeras/TensorFlowを動かす](http://qiita.com/kazunori279/items/1e23679c534a49c0e837)のswap領域の拡張すると治りました。

[ここ]( https://en.wikipedia.org/wiki/Elephant)の象は、さすがに9割方アフリカ象と認識されたようだ。
[これ](http://variety.com/2014/film/news/disney-developing-live-action-dumbo-movie-1201259284/)はpencil boxと認識された。。。

```
('Predicted:', [[(u'n03908618', u'pencil_box', 0.44221291), (u'n03291819', u'envelope', 0.15529086), (u'n07248320', u'book_jacket', 0.063755065), (u'n03485794', u'handkerchief', 0.053830493), (u'n06596364', u'comic_book', 0.037152626)]])
```