简体   繁体   English

为什么 TensorFlow estimator 无法进行这种简单的线性回归预测

[英]Why is TensorFlow estimator not able to make this simple linear regression prediction

I am learning tensorflow currently and cannot wrap my head around why tensorflow doesn't do proper prediction on following simple regression problem.我目前正在学习 tensorflow 并且无法理解为什么 tensorflow 没有对以下简单回归问题进行正确预测。

X are random numbers from 1000 to 8000 Y is X + 250 X 是从 1000 到 8000 的随机数 Y 是 X + 250

So if X is 2000, Y is 2250. This seems like a linear regression problem to me.所以如果 X 是 2000,Y 是 2250。这对我来说似乎是一个线性回归问题。 Yet, when I try making a predictions, it is nowhere near close to what I would expect, X of 1000 is giving me prediction of 1048 instead of 1250.然而,当我尝试进行预测时,它与我预期的相差甚远,1000 的 X 给了我 1048 而不是 1250 的预测。

Also loss and average loss are huge:损失和平均损失也是巨大的:

{'average_loss': 10269.81, 'loss': 82158.48, 'global_step': 1000}

Here is the complete code:这是完整的代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from sklearn.model_selection import train_test_split

x_data = np.random.randint(1000, 8000, 1000000)
y_true = x_data + 250

feat_cols = [tf.feature_column.numeric_column('x', shape=[1])]
estimator = tf.estimator.LinearRegressor(feature_columns=feat_cols)

x_train, x_eval, y_train, y_eval = train_test_split(x_data, y_true, test_size=0.3, random_state=101)

input_func = tf.estimator.inputs.numpy_input_fn({'x': x_train}, y_train, batch_size=8, num_epochs=None, shuffle=True)
train_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_train}, y_train, batch_size=8, num_epochs=1000, shuffle=False)
eval_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_eval}, y_eval, batch_size=8, num_epochs=1000, shuffle=False)

estimator.train(input_fn=input_func, steps=1000)

train_metrics = estimator.evaluate(input_fn=train_input_func, steps=1000)
eval_metrics = estimator.evaluate(input_fn=eval_input_func, steps=1000)

print(train_metrics)
print(eval_metrics)

brand_new_data = np.array([1000, 2000, 7000])
input_fn_predict = tf.estimator.inputs.numpy_input_fn({'x': brand_new_data}, shuffle=False)

prediction_result = estimator.predict(input_fn=input_fn_predict)

print(list(prediction_result))

Am I doing something wrong or am I misinterpreting what LinearRegression means?我做错了什么还是我误解了 LinearRegression 的意思?

i think it does when you tune some hyperparameters.我认为当您调整一些超参数时会发生这种情况。 I also changed the optimizer to AdamOptimizer .我还将优化器更改为AdamOptimizer

Mainly the batch size is 1 and epochs is None .主要是批量大小为1 , epochs 为None

train_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_train}, y_train, batch_size=1, num_epochs=None, shuffle=True) train_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_train}, y_train, batch_size=1, num_epochs=None, shuffle=True)

Code :代码 :

import tensorflow as tf
import numpy as np
from sklearn.model_selection import train_test_split

x_data = np.random.randint(1000, 8000, 10000)
y_true = x_data + 250


feat_cols = tf.feature_column.numeric_column('x')
optimizer = tf.train.AdamOptimizer(1e-3)

estimator = tf.estimator.LinearRegressor(feature_columns=[feat_cols],optimizer=optimizer)

x_train, x_eval, y_train, y_eval = train_test_split(x_data, y_true, test_size=0.3, random_state=101)


train_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_train}, y_train, batch_size=1, num_epochs=None,
                                                      shuffle=True)

eval_input_func = tf.estimator.inputs.numpy_input_fn({'x': x_eval}, y_eval, batch_size=1, num_epochs=None,
                                                     shuffle=True)

estimator.train(input_fn=train_input_func, steps=1005555)

train_metrics = estimator.evaluate(input_fn=train_input_func, steps=10000)
eval_metrics = estimator.evaluate(input_fn=eval_input_func, steps=10000)

print(train_metrics)
print(eval_metrics)

brand_new_data = np.array([1000, 2000, 7000])
input_fn_predict = tf.estimator.inputs.numpy_input_fn({'x': brand_new_data}, num_epochs=1,shuffle=False)

prediction_result = estimator.predict(input_fn=input_fn_predict)

for prediction in prediction_result:
    print(prediction['predictions'])

Metrics :指标:

{'average_loss': 3.9024353e-06, 'loss': 3.9024353e-06, 'global_step': 1005555} {'average_loss':3.9024353e-06,'loss':3.9024353e-06,'global_step':1005555}

{'average_loss': 3.9721594e-06, 'loss': 3.9721594e-06, 'global_step': 1005555} {'average_loss':3.9721594e-06,'loss':3.9721594e-06,'global_step':1005555}

[1250.003] [1250.003]

[2250.002] [2250.002]

[7249.997] [7249.997]

The reason of this slow convergence (you need to train for 1mln. steps, which is weird for such a seeming trivial problem) is that the data is not normalized.这种缓慢收敛的原因(你需要训练 100 万步,对于这样一个看似微不足道的问题来说很奇怪)是数据没有标准化。

Applying normalization I can train the model to predict the values accurately in 420 steps (I chose 420 because it's the number of memes) to get theses predictions:应用归一化,我可以训练模型以 420 步(我选择 420 因为它是模因的数量)准确预测值来获得这些预测:

[1250.387]
[2250.2046]
[7249.2915]

Code (done in TF 2.2):代码(在 TF 2.2 中完成):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from sklearn.model_selection import train_test_split

x_data = np.random.randint(1000, 8000, 1000000)
y_true = x_data + 250

tf.get_logger().setLevel('ERROR')

feat_cols = [tf.feature_column.numeric_column('size', shape=[1])]
estimator = tf.estimator.LinearRegressor(feature_columns=feat_cols, optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))

def normalize(arr):
    return (arr - arr.mean()) / arr.std()

x_data_norm = normalize(x_data)
y_true_norm = normalize(y_true)

x_train, x_eval, y_train, y_eval = train_test_split(x_data_norm, y_true_norm, test_size=0.3, random_state=101)

# numpy_input_fn is for when you have the full dataset available in an array already and want a quick way to do batching/shuffling/repeating
input_func = tf.compat.v1.estimator.inputs.numpy_input_fn({'size': x_train}, y_train, batch_size=1, num_epochs=None, shuffle=True)
train_input_func = tf.compat.v1.estimator.inputs.numpy_input_fn({'size': x_train}, y_train, batch_size=1, num_epochs=None, shuffle=True)
eval_input_func = tf.compat.v1.estimator.inputs.numpy_input_fn({'size': x_eval}, y_eval, batch_size=1, num_epochs=None, shuffle=True)

estimator.train(input_fn=input_func, steps=420)

train_metrics = estimator.evaluate(input_fn=train_input_func, steps=500)
eval_metrics = estimator.evaluate(input_fn=eval_input_func, steps=500)

print(train_metrics)
print(eval_metrics)

# brand_new_data = np.array([1000, 2000, 7000])
# input_fn_predict = tf.compat.v1.estimator.inputs.numpy_input_fn({'size': brand_new_data}, num_epochs=1, shuffle=False)
# prediction_result = estimator.predict(input_fn=input_fn_predict)
# print(list(prediction_result))

# predict w/ normalization
d1 = 1000 
d2 = 2000
d3 = 7000
brand_new_data = np.array([(d1 - x_data.mean()) / x_data.std(), (d2 - x_data.mean()) / x_data.std(), (d3 - x_data.mean()) / x_data.std()])

input_fn_predict = tf.compat.v1.estimator.inputs.numpy_input_fn({'size': brand_new_data}, num_epochs=1, shuffle=False)
prediction_result = estimator.predict(input_fn=input_fn_predict)

for res in prediction_result:
  print(res['predictions'] * y_true.std() + y_true.mean())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM