你如何在张量流中训练线性模型?

时间:2017-05-25 07:38:15

标签: python tensorflow

我已经在CSV中生成了一些输入数据,其中'awesomeness'是'age * 10'。它看起来像这样:

age, awesomeness
67, 670
38, 380
32, 320
69, 690
40, 400

编写一个可以从'age'预测'awesomeness'的张量流模型应该是微不足道的,但是我无法使它工作。

当我进行训练时,我得到的输出是:

accuracy: 0.0 <----------------------------------- What!??
accuracy/baseline_label_mean: 443.8
accuracy/threshold_0.500000_mean: 0.0
auc: 0.0
global_step: 6000
labels/actual_label_mean: 443.8
labels/prediction_mean: 1.0
loss: -2.88475e+09
precision/positive_threshold_0.500000_mean: 1.0
recall/positive_threshold_0.500000_mean: 1.0

请注意,这显然是一个完全人为的例子,但这是因为我得到了一个更复杂的有意义模型和更大数据集的相同结果; 0%准确度。

这是我尝试的最小可能的可重现测试用例,我可以做出哪些表现出相同的行为。

以下是我正在做的事情,基于来自tflearn的DNNC分类器的人口普查示例:

COLUMNS = ["age", "awesomeness"]
CONTINUOUS_COLUMNS = ["age"]
OUTPUT_COLUMN = "awesomeness"

def build_estimator(model_dir):
  """Build an estimator."""
  age = tf.contrib.layers.real_valued_column("age")
  deep_columns = [age]

  m = tf.contrib.learn.DNNClassifier(model_dir=model_dir,
                                     feature_columns=deep_columns,
                                     hidden_units=[50, 10])
  return m

def input_fn(df):
  """Input builder function."""
  feature_cols = {k: tf.constant(df[k].values, shape=[df[k].size, 1]) for k in CONTINUOUS_COLUMNS}
  output = tf.constant(df[OUTPUT_COLUMN].values, shape=[df[OUTPUT_COLUMN].size, 1])
  return feature_cols, output

def train_and_eval(model_dir, train_steps):
  """Train and evaluate the model."""
  train_file_name, test_file_name = training_data()
  df_train = pd.read_csv(...) # ommitted for clarity 
  df_test = pd.read_csv(...)

  m = build_estimator(model_dir)
  m.fit(input_fn=lambda: input_fn(df_train), steps=train_steps)

  results = m.evaluate(input_fn=lambda: input_fn(df_test), steps=1)
  for key in sorted(results):
    print("%s: %s" % (key, results[key]))

def training_data():
  """Return path to the training and test data"""
  training_datafile = path.join(path.dirname(__file__), 'data', 'data.training')
  test_datafile = path.join(path.dirname(__file__), 'data', 'data.test')
  return training_datafile, test_datafile

model_folder = 'scripts/model'  # Where to store the model
train_steps = 2000  # How many iterations to run while training
train_and_eval(model_folder, train_steps)

几点说明:

  • 这是基于https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/learn/wide_n_deep_tutorial.py

  • 的原始示例教程
  • 注意我正在使用DNNClassifier,而不是LinearClassifier,因为我想专门处理连续输入变量。

  • 很多例子只使用已知可用于实例的“预制”数据集;我的数据集已经手动生成,绝对不是随机的。

  • 我已经验证了csv加载程序正在以int64值正确加载数据。

  • 训练和测试数据的生成方式相同,但其中的值不同;但是,使用data.training 作为测试数据仍然返回0%的准确度,因此毫无疑问某些东西不起作用,这不仅仅是过度拟合

3 个答案:

答案 0 :(得分:1)

首先,您描述的是回归任务,而不是分类任务。因此,DNNClassifier和LinearClassifier都是错误的使用方法。这也使准确度成为错误的数量,用于判断您的模型是否有效。我建议你阅读这两个不同的背景,例如:在书中#34;统计学习要素&#34;

但这是对你的问题的简短回答。假设你有一个线性模型

awesomeness_predicted = slope * age

其中slope是您要从数据中学习的参数。假设您有数据age[0], ..., age[N]和相应的超棒值a_data[0],...,a_data[N]。为了指定您的模型是否运行良好,我们将使用均方误差,即

error = sum((a_data[i] - a_predicted[i])**2 for i in range(N))

您现在要做的是从随机猜测坡度开始,逐渐改善梯度下降。这是纯张量流中的完整工作示例

import tensorflow as tf
import numpy as np

DTYPE = tf.float32

## Generate Data
age = np.array([67, 38, 32, 69, 40])
awesomeness = 10 * age

## Generate model
# define the parameter of the model
slope = tf.Variable(initial_value=tf.random_normal(shape=(1,), dtype=DTYPE))
# define the data inputs to the model as variable size tensors
x = tf.placeholder(DTYPE, shape=(None,))
y_data = tf.placeholder(DTYPE, shape=(None,))
# specify the model
y_pred = slope * x
# use mean squared error as loss function
loss = tf.reduce_mean(tf.square(y_data - y_pred))
target = tf.train.AdamOptimizer().minimize(loss)

## Train Model
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    for epoch in range(100000):
        _, training_loss = sess.run([target, loss],
                                    feed_dict={x: age, y_data: awesomeness})
    print("Training loss: ", training_loss)
    print("Found slope=", sess.run(slope))

答案 1 :(得分:1)

我想说几件事。 假设您正确加载数据:

- 这看起来像一个回归任务,你正在使用一个分类器。我并不是说它根本不起作用,但是就像这样,你给每个年龄段的标签和整个批次的培训都是非常不稳定的。

- 您正在为损失获得巨大价值,您的渐变正在爆炸。有了这个玩具数据集,您可能需要调整超参数,如隐藏神经元,学习速率和时代数。尝试记录每个时期的损失值,看看是否可能是问题。

- 最后的建议,让您的数据使用更简单的模型,可能适合您的任务,如regression model,然后按比例扩大

答案 2 :(得分:0)

另请参阅https://github.com/tflearn/tflearn/blob/master/examples/basics/multiple_regression.py使用tflearn来解决此问题。

""" Multiple Regression/Multi target Regression Example

The input features have 10 dimensions, and target features are 2 dimension.

"""

from __future__ import absolute_import, division, print_function

import tflearn
import numpy as np

# Regression data- 10 training instances
#10 input features per instance.
X=np.random.rand(10,10).tolist()
#2 output features per instance
Y=np.random.rand(10,2).tolist()

# Multiple Regression graph, 10-d input layer
input_ = tflearn.input_data(shape=[None,10])
#10-d fully connected layer
r1 = tflearn.fully_connected(input_,10)
#2-d fully connected layer for output
r1 = tflearn.fully_connected(r1,2)
r1 = tflearn.regression(r1, optimizer='sgd', loss='mean_square',
                                        metric='R2', learning_rate=0.01)

m = tflearn.DNN(r1)
m.fit(X,Y, n_epoch=100, show_metric=True, snapshot_epoch=False)

#Predict for 1 instance
testinstance=np.random.rand(1,10).tolist()
print("\nInput features:  ",testinstance)
print("\n Predicted output: ")
print(m.predict(testinstance))