Tensorflow を強化学習でversion2.1を使うとversion1.12よりも遅くなるので原因を確認しました。
結論から述べますと、version2.1は、バッチで学習させるときにはversion1.12よりも若干速いのですが、データを1つづつに分けて学習させる場合ではかなり遅くなるということです。今回のテストだと約6倍も時間がかかりました。
普通の教師あり学習で、後者の方法を使うことはないと思いますが、強化学習では使う場合があります。
modelをsequential で作るか、functional で作るかの違いでも試してみましたが、そこはあまり違いはありませんでした。
以下、私のPCで測定した結果です。batchが100個のデータをバッチで学習させたとき、eachが1つずつ100回学習させたときです。
python 3.7, Tensorflow 2.1
model = sequential, mode = batch: time 0.37 sec
model = sequential, mode = each: time 3.63 sec
model = functional, mode = batch: time 0.35 sec
model = functional, mode = each: time 3.81 sec
python 3.6, Tensorflow 1.12
model = sequential, mode = batch: time 0.48 sec
model = sequential, mode = each: time 0.59 sec
model = functional, mode = batch: time 0.51 sec
model = functional, mode = each: time 0.63 sec
以下、プログラムです。
import numpy as np
import tensorflow as tf
import time
import pdb
class NeuralNet:
def __init__(self,
n_output=2,
n_dense=16,
n_dense2=16,
input_size=(10,)
):
self.n_output = n_output
self.n_dense = n_dense
self.n_dense2 = n_dense2
self.input_size = input_size
def built(self, mode='sequential'):
if mode == 'sequential':
self.model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=self.input_size),
tf.keras.layers.Dense(self.n_dense, activation='relu'),
tf.keras.layers.Dense(self.n_dense2, activation='relu'),
tf.keras.layers.Dense(self.n_output, activation='linear'),
])
elif mode == 'functional':
inputs = tf.keras.Input(shape=(self.input_size))
x = tf.keras.layers.Flatten()(inputs) # 2次元の入力にも対応できるように入れている
x = tf.keras.layers.Dense(self.n_dense, activation='relu')(x)
x = tf.keras.layers.Dense(self.n_dense2, activation='relu')(x)
outputs = tf.keras.layers.Dense(self.n_output, activation='linear')(x)
self.model = tf.keras.Model(inputs=inputs, outputs=outputs)
else:
raise ValueError('modeが間違っています')
self.model.compile(
optimizer='adam',
loss='mean_squared_error',
metrics=['mse']
)
def learn(self, X, Y, mode='batch'):
if mode == 'batch':
# 全てまとめて
self.model.fit(X, Y, verbose=0, epochs=1)
elif mode == 'each':
# 一つずつ
for xx, yy in zip(X, Y):
self.model.fit(
xx.reshape((1,) + self.input_size),
yy.reshape((1, 2)),
verbose=0, epochs=1)
def predict(self, X):
Y = self.model.predict(X)
return Y
if __name__ == '__main__':
# データ
N = 100 # データ数
D = 10 # input の次元
M = 2 # output の次元
X = np.random.randn(N, D)
W = np.random.randn(D, M)
Y = X.dot(W)
print('TF version', tf.__version__)
for model in ['sequential', 'functional']:
for mode in ['batch', 'each']:
nn = NeuralNet(n_output=M, input_size=(D,))
nn.built(mode=model)
stime = time.time()
nn.learn(X, Y, mode=mode)
etime =time.time()
print('model = %s, mode = %s: time %.2f sec' % (model, mode, etime - stime))
コメントを残す