【发布时间】:2019-09-10 14:06:09
【问题描述】:
我做了一个实验来比较 tf.keras 在转换为 estimator 前后的性能,得到了非常不同的损失: 1) tf.keras 模型(无估计器):1706.100 RMSE (+/- 260.064) 2) tf.keras 转换为估计器:3912.574 RMSE (+/- 132.833)
我确定我在估算器转换或数据集 API 中做错了,但我无法找出根本原因。任何帮助表示赞赏。
这与我的另一篇文章“Converting CNN-LSTM from keras to tf.keras down the accuracy”有关。
没有估算器的部分代码
import tensorflow as tf
from math import sqrt
from sklearn.metrics import mean_squared_error
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import ConvLSTM2D
from matplotlib import pyplot
import numpy as np
import pandas as pd
import warnings
def model_fit_convlstm(train_supv, config, first_round):
# train X shape = (48, 36)
train_x, train_y = train_supv[:, :-1], train_supv[:, -1]
# train X lstm shape = (48, 36, 1)
train_x_convlstm = train_x.reshape(train_x.shape[0], config['n_seq'], 1, config['n_steps'], config['n_feature'])
#
input_shape = (config['n_seq'], 1, config['n_steps'], config['n_feature'])
# relu = tf.nn.relu
relu = 'relu'
model = Sequential()
model.add(ConvLSTM2D(config['n_filters'], (1,config['n_kernel']), activation=relu, input_shape=input_shape))
model.add(Flatten())
model.add(Dense(config['n_nodes'], activation=relu))
model.add(Dense(1))
adam = tf.train.AdamOptimizer()
# adam = 'adam'
mse = tf.keras.losses.mean_squared_error
# mse = 'mse'
model.compile(optimizer=adam, loss=mse)
model.fit(train_x_convlstm, train_y, epochs=config['n_epochs'], batch_size=config['n_batch'], verbose=0)
return model
def model_predict_convlstm(model, test_supv, config, first_round):
test_x, test_y = test_supv[:, :-1], test_supv[:, -1]
test_x_convlstm = test_x.reshape(test_x.shape[0], config['n_seq'], 1, config['n_steps'], config['n_feature'])
if first_round.state:
print('test X shape = {}'.format(test_x.shape))
print('test X convlstm shape = {}'.format(test_x_convlstm.shape))
#
predictions = np.array([])
for row in test_x_convlstm:
test_x_convlstm_row = row.reshape(1, config['n_seq'], 1, config['n_steps'], config['n_feature'])
yhat = model.predict(test_x_convlstm_row, verbose=0)
# print(yhat)
predictions = np.append(predictions, yhat)
#
return predictions
带有估算器转换的部分代码
import tensorflow as tf
from math import sqrt
from sklearn.metrics import mean_squared_error
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import ConvLSTM2D
from matplotlib import pyplot
import numpy as np
import pandas as pd
import warnings
def model_fit_convlstm(train_supv, config, first_round):
# train X shape = (48, 36)
train_x, train_y = train_supv[:, :-1], train_supv[:, -1]
# train X lstm shape = (48, 36, 1)
train_x_convlstm = train_x.reshape(train_x.shape[0], config['n_seq'], 1, config['n_steps'], config['n_feature'])
#
input_shape = (config['n_seq'], 1, config['n_steps'], config['n_feature'])
# relu = tf.nn.relu
relu = 'relu'
model = Sequential()
model.add(ConvLSTM2D(config['n_filters'], (1,config['n_kernel']), activation=relu , input_shape=input_shape))
model.add(Flatten())
model.add(Dense(config['n_nodes'], activation=relu))
model.add(Dense(1))
adam = tf.train.AdamOptimizer()
# adam = 'adam'
mse = tf.keras.losses.mean_squared_error
# mse = 'mse'
model.compile(optimizer=adam, loss=mse)
print('model {}'.format(model))
#
with warnings.catch_warnings():
warnings.filterwarnings("ignore")
estimator = tf.keras.estimator.model_to_estimator(keras_model=model)
#
# train X lstm shape = (48, 36, 1)
# numpy_input_fn takes x: train_x_lstm shape
# print('model.input_names {}'.format(model.input_names))
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x = {model.input_names[0]: train_x_convlstm.astype(np.float32)},
y = train_y.astype(np.float32),
num_epochs = config['n_epochs'],
batch_size = config['n_batch'],
shuffle = True
)
estimator.train(input_fn=train_input_fn)
#
return model, estimator
def model_predict_convlstm(model, estimator, test_supv, config, first_round):
test_x, test_y = test_supv[:, :-1], test_supv[:, -1]
test_x_convlstm = test_x.reshape(test_x.shape[0], config['n_seq'], 1, config['n_steps'], config['n_feature'])
if first_round.state:
print('test X shape = {}'.format(test_x.shape))
print('test X convlstm shape = {}'.format(test_x_convlstm.shape))
#
predict_input_fn = tf.estimator.inputs.numpy_input_fn(
x = {model.input_names[0]: test_x_convlstm.astype(np.float32)},
y = None,
batch_size=1,
num_epochs=1,
shuffle=False
)
yhat_list = estimator.predict(input_fn=predict_input_fn)
# print('yhat_list {}'.format(yhat_list))
predictions = np.array([])
for yhat_dict in yhat_list:
for key, val in yhat_dict.items():
# print('yhat = {} {}'.format(key, val))
predictions = np.append(predictions, val)
#
return predictions
【问题讨论】:
-
我不是
Estimators的专家,但你的实验之间的学习率可能不同吗?我在您的代码中的任何地方都看不到它,Estimators的默认值可能不同。 -
我按照建议添加了学习率规范,但不幸的是,mse 差距仍然存在。
-
adam = tf.keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999) mse = tf.keras.losses.mean_squared_error model.compile(optimizer=adam, loss=mse )
-
我的更多观察。我尝试了另一种神经网络方法(MLP)。在那种情况下,keras 和 tf.keras 的预测非常接近。结论是估计器转换引入的差距只发生在某些 tf.keras 库和层上。
标签: tensorflow keras deep-learning tf.keras