【问题标题】:Converting tf.keras model to estimator makes loss worst将 tf.keras 模型转换为估计器会使损失最严重
【发布时间】: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


【解决方案1】:

我的更多观察。我尝试了另一种神经网络方法(MLP)。在那种情况下,keras 和 tf.keras 的预测非常接近。结论是估计器转换引入的差距只发生在某些 tf.keras 库和层上。 罪魁祸首是 ConvLSTM2D 和 Flatten,我怀疑 tf.keras 可能有不同的默认值或略有不同的算法。 以下示例在预测性能上没有产生差距

tf.keras

import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
relu = tf.keras.activations.relu
model = Sequential()
model.add(Dense(config['n_nodes'], activation=relu, input_dim=config['n_input']))
model.add(Dense(1))
adam = tf.keras.optimizers.Adam()
mse = tf.keras.losses.mean_squared_error
model.compile(loss=mse, optimizer=adam, verbose=0)
# model.fit(train_x, train_y, epochs=config['n_epochs'], batch_size=config['n_batch'], verbose=0)
with warnings.catch_warnings():
  warnings.filterwarnings("ignore")
  estimator = tf.keras.estimator.model_to_estimator(keras_model=model)
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x = {model.input_names[0]: train_x.astype(np.float32)},
    y = train_y.astype(np.float32),
    num_epochs = config['n_epochs'],
    batch_size = config['n_batch'],
    shuffle = False
)
estimator.train(input_fn=train_input_fn)

keras

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(config['n_nodes'], activation='relu', input_dim=config['n_input']))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.fit(train_x, train_y, epochs=config['n_epochs'], batch_size=config['n_batch'], verbose=0)

【讨论】:

    猜你喜欢
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 2011-02-21
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2019-04-28
    相关资源
    最近更新 更多