2017-05-25 96 views
0

我已经生成了一些CSV输入数据,其中'超棒'是'age * 10'。它看起来像这样:如何训练张量流中的线性模型?

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

它应该是微不足道的写tensorflow模型,可以预测由“时代”“迷死人”,但我不能使它发挥作用。

当我运行培训,输出我得到的是:

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的DNNClassifier普查例如:

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,因为我想专门处理连续的输入t变量。

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

  • 我已验证csv loader正在将数据正确加载为int64值。

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

回答

1

首先,您描述的是回归任务,而不是分类任务。因此,DNNClassifier和LinearClassifier都是错误的使用方法。这也会使准确性错误地用于判断模型是否正常工作。我建议你阅读这两种不同的情况,例如在“统计学习的元素”一书中

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

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)) 

你想现在做的是开始一个随机猜测斜率和使用梯度下降逐步改善。这里是纯tensorflow

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)) 
+0

唔...你能澄清可能如何推广到更复杂的模型?这似乎特定于拟合线性模块,其中I *已经知道* y = k * x;我知道这就是我所问的,非常公平,但是当你已经需要知道它是什么的时候,这似乎已经挫败了试图训练数据集的意义......? – Doug

+0

这就是机器学习的工作原理(有一些处理非参数模型的统计分支,但这是一个完全不同的野兽)。 这个模型与真实世界应用程序的唯一区别在于后者通常涉及更复杂和更富表现力的模型。但你说你想要一个线性模型,所以这就是你得到的;) – dseuss

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)) 
1

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

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

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

-Last建议,使您的数据的工作与简单的模型,可能适合你的任务,就像一个regression model,然后扩大规模

相关问题