tf.contrib.learn.LinearRegressor 为具有一项功能的数据构建出乎意料的错误模型

tf.contrib.learn.LinearRegressor builds unexpectedly bad model for a data with one feature

我正在为来自 csv 的数据构建一个简单的线性回归量。数据包括某些人的体重和身高值。整体学习过程非常简单:

MAX_STEPS = 2000
# ...
features = [tf.contrib.layers.real_valued_column(feature_name) for feature_name in FEATURES_COL]
# ...
linear_regressor = tf.contrib.learn.LinearRegressor(feature_columns=features)
linear_regressor.fit(input_fn=prepare_input, max_steps=MAX_STEPS)

但是,回归器构建的模型出乎意料地不好。结果可以用下一张图来说明:

可视化代码(以防万一):

plt.plot(height_and_weight_df_filtered[WEIGHT_COL], 
         linear_regressor.predict(input_fn=prepare_full_input), 
         color='blue',
         linewidth=3)

这是来自 scikit-learn 的线性回归 class 的相同数据:

lr_updated = linear_model.LinearRegression()
lr_updated.fit(weight_filtered_reshaped, height_filtered)

以及可视化:

增加步数没有效果。我假设我以错误的方式使用了 TensorFlow 的回归器。

iPython notebook with the code.

看来您的 TF 模型确实有效,并且可以通过足够的步骤实现。不过,您需要将其提升 - 200K 显示出显着改善,几乎与 sklearn 默认值一样好。

我认为有两个问题:

  1. sklearn 看起来只是使用普通最小二乘法求解方程。 TF 的 LinearRegressor 使用 FtrlOptimizer。该论文表明它是非常大的数据集的更好选择。
  2. 模型的 input_fn 正在为每一步一次性注入整个训练集。这只是一种预感,但我怀疑如果 FtrlOptimizer 一次看到批次,它可能会做得更好。

除了将步数提高几个数量级之外,您还可以提高优化器的学习率(默认值为 0.2),仅需 4k 步即可获得类似的好结果:

linear_regressor = tf.contrib.learn.LinearRegressor(
    feature_columns=features, 
    optimizer=tf.train.FtrlOptimizer(learning_rate=5.0))

我遇到了类似的问题。解决方案是检查您的 input_fn 是否有足够的纪元。在多次迭代整个训练数据之前,训练可能不会收敛。