TensorFlow 2.2

2020.05.06
TensorFlow 2.2がリリースされました。
インストール手順は2.1のときと同じです。必要なツールのバージョンも同様です。

hmx.hatenablog.jp


すでにTwnsorFlow2.1をインストールしてしまった方はPowerShellから以下のように前のバージョンをアンインストールしてからインストールします。
> pip uninstall tensorflow
> pip uninstall tensorboard
> pip uninstall tensorflow-estimator

> pip install tensorflow

TF2.1でXOR回路

2020.04.26

TF2.1でモデル化

前回のAND回路と同じ単純な、y=x1*w1 + x2*w2 + bで判定させるモデルを作ります。

import numpy as np

import tensorflow as tf
from tensorflow.keras import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from tensorflow.keras.optimizers import SGD, Adam

trainX = np.array([
    [0.0, 0.0],
    [1.0, 0.0],
    [0.0, 1.0],
    [1.0, 1.0]])
trainY = np.array([
    0.0,
    1.0,
    1.0,
    0.0
    ])

x_in = Input(shape=(2,))
x = x_in
x = Dense(1, use_bias=True, activation=None)(x)
model = Model(x_in, x)

learning_rate = 0.1
sgd = SGD(lr=learning_rate)

model.compile(optimizer=sgd, loss='mean_squared_error')
model.summary()

batch_size = 4
history = model.fit(x=trainX, y=trainY,
                   epochs=1000, batch_size=batch_size, shuffle=False,
                   validation_split=0.0)

evaluate = model.evaluate(trainX, trainY)
print('Evaluate:', evaluate)

testX = trainX
output = model.predict(testX[0:batch_size])
print('Predict:', output)

結果、すべて出力は0.5となってしまいました。

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 2)]               0         
_________________________________________________________________
dense (Dense)                (None, 1)                 3         
=================================================================
Total params: 3
Trainable params: 3
Non-trainable params: 0
_________________________________________________________________
Epoch 1/1000
1/1 [==============================] - 0s 999us/step - loss: 1.1281
Epoch 2/1000
1/1 [==============================] - 0s 999us/step - loss: 0.8644
(略)
Evaluate: 0.25
Predict: [[0.49999982]
 [0.49999994]
 [0.49999994]
 [0.50000006]]

係数を表示させてみます。

def PrintWeights(model):
    print('-----Weights-----')
    for i, l in enumerate(model.layers):
        weights = l.get_weights()
        if len(weights) == 0:
            continue
        name = ['W', 'b']
        for j, c in enumerate(weights):
            print('{}:{}'.format(name[j], c))
    print('-----------------')
    
PrintWeights(model)
-----Weights-----
W:[[1.2831156e-07]
 [1.2877769e-07]]
b:[0.49999982]
-----------------

つまり、y=0.0*x1 + 0.0*x2 + 0.5が最適解となり、このモデルでの限界となりました。グラフで見ると以下のようになります。
f:id:hmxnet:20200514165733j:plain

このままだと使い物にならないので、ここでディープニューラルネットの登場です。
2層のネットワークに加えて非線形関数(ReLU)を入れてみます。前と違う点はDenseの部分です。

import numpy as np

import tensorflow as tf
from tensorflow.keras import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from tensorflow.keras.optimizers import SGD, Adam

trainX = np.array([
    [0.0, 0.0],
    [1.0, 0.0],
    [0.0, 1.0],
    [1.0, 1.0]])
trainY = np.array([
    0.0,
    1.0,
    1.0,
    0.0
    ])

x_in = Input(shape=(2,))
x = x_in
x = Dense(2, use_bias=True, activation='relu')(x)
x = Dense(1, use_bias=True, activation=None)(x)
model = Model(x_in, x)

learning_rate = 0.1
sgd = SGD(lr=learning_rate)

model.compile(optimizer=sgd, loss='mean_squared_error')
model.summary()

batch_size = 4
history = model.fit(x=trainX, y=trainY,
                   epochs=1000, batch_size=batch_size, shuffle=False,
                   validation_split=0.0)

evaluate = model.evaluate(trainX, trainY)
print('Evaluate:', evaluate)

testX = trainX
output = model.predict(testX[0:batch_size])
print('Predict:', output)

Predictを見るとかなりいい感じにフィッティング(学習)してくれました。

Model: "model_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_6 (InputLayer)         [(None, 2)]               0         
_________________________________________________________________
dense_6 (Dense)              (None, 2)                 6         
_________________________________________________________________
dense_7 (Dense)              (None, 1)                 3         
=================================================================
Total params: 9
Trainable params: 9
Non-trainable params: 0
_________________________________________________________________
Epoch 1/1000
1/1 [==============================] - 0s 2ms/step - loss: 0.4063
Epoch 2/1000
1/1 [==============================] - 0s 2ms/step - loss: 0.3359
(略)
Evaluate: 6.362464266378154e-13
Predict: [[1.0325746e-06]
 [9.9999923e-01]
 [9.9999923e-01]
 [5.2721737e-07]]
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

%matplotlib notebook

def ReLU(x):
    return np.maximum(0, x)

x1 = np.linspace(0, 1, 100)
x2 = np.linspace(0, 1, 100)
X1, X2 = np.meshgrid(x1, x2)

W1 = model.layers[1].get_weights()[0]
b1 = model.layers[1].get_weights()[1]

W2 = model.layers[2].get_weights()[0]
b2 = model.layers[2].get_weights()[1]

Y11 = ReLU(X1 * W1[0, 0] + X2 * W1[1, 0] + b1[0])
Y12 = ReLU(X1 * W1[0, 1] + X2 * W1[1, 1] + b1[1])

Y = Y11 * W2[0] + Y12 * W2[1] + b2

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X1, X2, Y, cmap=plt.cm.viridis)
ax.set_xlabel('X1')
ax.set_ylabel('X2')
ax.set_zlabel('Y')
ax.set_zlim([0,1])
plt.show()

f:id:hmxnet:20200514171810j:plain

意表を突いたフィッティングの仕方です。折り紙を対角上に折った形状です。確かに0,1のとき1、1,0のとき1が出力されています。これがディープニューラルネット威力です。
場合によっては、以下のように山折りではなく谷折りにした形も出力されることもあります。これは係数の初期値によるもので初期値が乱数で初期化されているからです。どちらも期待した出力は得ています。
f:id:hmxnet:20200514173752j:plain

TF2.1でAND回路

2020.04.26

Jupyter 起動

さっそくTensorflow 2.1を動かしてみます。PowerShellを起動して、Jupyterを起動させます。
> jupyter notebook

f:id:hmxnet:20200426151557j:plain

右上のNewからPython 3を選択。

バージョン情報

ノートブックの頭に使用したバージョンなどをメモしておくとバージョン変えた時に便利です。

import sys
import tensorflow as tf
import numpy as np

print('Python:', sys.version)
print('Tensorflow:', tf.__version__)
print('Keras:', tf.keras.__version__)
print('numpy:', np.__version__)

Shift+Enter キーを押して実行すると以下のように表示されます。

Python: 3.7.6 (default, Jan  8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)]
Tensorflow: 2.1.0
Keras: 2.2.4-tf
numpy: 1.18.1

TF2.1でモデル化

ここでは単純な、y=x1*w1 + x2*w2 + bで判定させるモデルを作ります。Denseで2次元のデータを1次元にします。
TF2.xからKerasがフロントエンドとなったのでplaceholderとかVariableがなくなります。TF1.xのときと比べるとimportの場所が若干変わってますね。kerasがtensorflowの中に組み込まれたのでtensorflow.kerasの中にモジュールが含まれています。
さて以下を実行してみましょう。loss(誤差)が徐々に減り期待した値に近づいていることがわかります。
(ここで実行できない人はインストールするツールのバージョンが合っていないかと思われます)

import numpy as np

import tensorflow as tf
from tensorflow.keras import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from tensorflow.keras.optimizers import SGD, Adam

trainX = np.array([
    [0.0, 0.0],
    [1.0, 0.0],
    [0.0, 1.0],
    [1.0, 1.0]])
trainY = np.array([
    0.0,
    0.0,
    0.0,
    1.0
    ])

x_in = Input(shape=(2,))
x = x_in
x = Dense(1, use_bias=True, activation=None)(x)
model = Model(x_in, x)

learning_rate = 0.1
sgd = SGD(lr=learning_rate)

model.compile(optimizer=sgd, loss='mean_squared_error')
model.summary()

batch_size = 4
history = model.fit(x=trainX, y=trainY,
                   epochs=1000, batch_size=batch_size, shuffle=False,
                   validation_split=0.0)

evaluate = model.evaluate(trainX, trainY)
print('Evaluate:', evaluate)

testX = trainX
output = model.predict(testX[0:batch_size])
print('Predict:', output)

以下のようになりました。(1, 1)のときに一番大きな値が出力されています。正確に1とならないのはy=x1*w1 + x2*w2 + bでは完全にモデル化できないからです。

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 2)]               0         
_________________________________________________________________
dense (Dense)                (None, 1)                 3         
=================================================================
Total params: 3
Trainable params: 3
Non-trainable params: 0
_________________________________________________________________
Train on 4 samples
Epoch 1/1000
4/4 [==============================] - 1s 143ms/sample - loss: 0.5787
Epoch 2/1000
4/4 [==============================] - 0s 749us/sample - loss: 0.3331
(略)
Evaluate: 0.0625
Predict: [[-0.25000072]
 [ 0.24999994]
 [ 0.24999994]
 [ 0.7500006 ]]

係数出力

係数を出力するには以下のようにします。

def PrintWeights(model):
    print('-----Weights-----')
    for i, l in enumerate(model.layers):
        weights = l.get_weights()
        if len(weights) == 0:
            continue
        name = ['W', 'b']
        for j, c in enumerate(weights):
            print('{}:{}'.format(name[j], c))
    print('-----------------')
    

PrintWeights(model)

結果は以下のようになりました。つまり、y=0.5*x1 + 0.5*x2 - 0.25がAND回路になるようにフィッティング(学習)されたということになります。

-----Weights-----
W:[[0.50000066]
 [0.50000066]]
b:[-0.25000072]
-----------------

さて、せっかくなのでy=0.5*x1 + 0.5*x2 - 0.25がどのような面をしているのか表示してみましょう。x1, x2は0,1以外の値も入れることができます(どういう風に解釈するかはお任せします)。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

%matplotlib notebook

x1 = np.linspace(0, 1, 100)
x2 = np.linspace(0, 1, 100)
X1, X2 = np.meshgrid(x1, x2)

W = model.layers[1].get_weights()[0]
b = model.layers[1].get_weights()[1]

Y = X1 * W[0, 0] + X2 * W[1, 0] + b

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X1, X2, Y, cmap=plt.cm.viridis)
ax.set_xlabel('X1')
ax.set_ylabel('X2')
ax.set_zlabel('Y')
plt.show()

f:id:hmxnet:20200514162120j:plain

ORにしたい人は次のようにしてみましょう。

trainX = np.array([
    [0.0, 0.0],
    [1.0, 0.0],
    [0.0, 1.0],
    [1.0, 1.0]])
trainY = np.array([
    0.0,
    1.0,
    1.0,
    1.0
    ])

次回はXOR回路を見てみます。

Tensorflow 2.1 インストール手順

2020.04.26

再セットアップしたメモ代わりに残しておきます。

インストール

2020年4月現在最新のWindows 10 Pro 1909にインストールする手順です。

ツールのバージョンが合っていないと動かないので注意です。新しいバージョンが出たからといってインストールすると動かなくなったりします。

用意するものは最新の以下のファイルです。Python 3.7系でも動作することを確認しました。Python単体で入れるよりも元々多くのライブラリが入っているAnacondaを入れておいた方が後々便利でしょう。

GPUを使いたいので、CUDAも入れてあります。Tensorflowには関係ないですが、VisualStudioのインストールを考えている方はCUDAよりもViualStudioを先にインストールしておくとCUDAインストール時に専用のツール類がインストールされるので先にインストールしておきましょう。

 

- Anaconda3 (Anaconda3-2020.02-Windows-x86_64.exe)

- CUDA 10.1 update2 (cuda_10.1.243_426.00_win10.exe)

- cuDNN v7.6.5 (cudnn-10.1-windows10-x64-v7.6.5.32.zip)

 

cuDNNは"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1"に上書きです。

 

システム環境変数

システム環境変数に以下を追加しておきます。

Anaconda関係
Path
C:\Users\hmxnet\anaconda3
C:\Users\hmxnet\anaconda3\Library\bin
C:\Users\hmxnet\anaconda3\Scripts

CUDAの環境変数はインストール時に自動的に追加されています。
CUDA_PATH
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
CUDA_PATH_V10_1
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
Path
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\libnvvp

 

Tensorflow 2.1インストール

最新のAnaconda をインストールしていればいらないかもしれませんが、PowerShellから以下を実行し、pipを最新にしておく。

> pip install --upgrade pip

環境変数 C:\Users\hmxnet\anaconda3\Library\bin を追加していないと次のようなエラーとなります。

> pip install tensorflow
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
(略)

 

grpcioが足りないといわれるので、以下をインストール。

> pip install grpcio

Tensorflow をインストール。

> pip install tensorflow

を実行すると、
> pip install tensorflow
Collecting tensorflow
Using cached tensorflow-2.1.0-cp37-cp37m-win_amd64.whl (355.8 MB)
Collecting protobuf>=3.8.0
Using cached protobuf-3.11.3-cp37-cp37m-win_amd64.whl (1.0 MB)
Collecting tensorflow-estimator<2.2.0,>=2.1.0rc0
Downloading tensorflow_estimator-2.1.0-py2.py3-none-any.whl (448 kB)
|████████████████████████████████| 448 kB 1.7 MB/s
Collecting keras-preprocessing>=1.1.0
Downloading Keras_Preprocessing-1.1.0-py2.py3-none-any.whl (41 kB)
|████████████████████████████████| 41 kB 3.2 MB/s

(略)

 Successfully installed absl-py-0.9.0 astor-0.8.1 cachetools-4.1.0 gast-0.2.2 google-auth-1.14.0 google-auth-oauthlib-0.4.1 google-pasta-0.2.0 keras-applications-1.0.8 keras-preprocessing-1.1.0 markdown-3.2.1 oauthlib-3.1.0 opt-einsum-3.2.1 protobuf-3.11.3 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-oauthlib-1.3.0 rsa-4.0 tensorboard-2.1.1 tensorflow-2.1.0 tensorflow-estimator-2.1.0 termcolor-1.1.0

 

これだけでセットアップ完了です。次回から使い方について解説していきます。