Tensorflow随机值

时间:2017-08-29 22:23:43

标签: python tensorflow deep-learning

我正在迈出深度学习和张量流的第一步。因此,我有一些问题。

根据教程和入门我创建了一个带隐藏层的DNN以及一些简单的softmax模型。我使用了来自https://archive.ics.uci.edu/ml/datasets/wine的数据集,并将其拆分为训练和测试数据集。

from __future__ import print_function
import tensorflow as tf


num_attributes = 13
num_types = 3


def read_from_cvs(filename_queue):
    reader = tf.TextLineReader()
    key, value = reader.read(filename_queue)
    record_defaults = [[] for col in range(
        num_attributes + 1)]
    attributes = tf.decode_csv(value, record_defaults=record_defaults)
    features = tf.stack(attributes[1:], name="features")
    labels = tf.one_hot(tf.cast(tf.stack(attributes[0], name="labels"), tf.uint8), num_types + 1, name="labels-onehot")
    return features, labels


def input_pipeline(filename='wine_train.csv', batch_size=30, num_epochs=None):
    filename_queue = tf.train.string_input_producer([filename], num_epochs=num_epochs, shuffle=True)
    features, labels = read_from_cvs(filename_queue)

    min_after_dequeue = 2 * batch_size
    capacity = min_after_dequeue + 3 * batch_size
    feature_batch, label_batch = tf.train.shuffle_batch(
        [features, labels], batch_size=batch_size, capacity=capacity,
        min_after_dequeue=min_after_dequeue)
    return feature_batch, label_batch


def train_and_test(hidden1, hidden2, learning_rate, epochs, train_batch_size, test_batch_size, test_interval):
    examples_train, labels_train = input_pipeline(filename="wine_train.csv", batch_size=train_batch_size)
    examples_test, labels_test = input_pipeline(filename="wine_train.csv", batch_size=test_batch_size)

    with tf.name_scope("first layer"):
        x = tf.placeholder(tf.float32, [None, num_attributes], name="input")
        weights1 = tf.Variable(
            tf.random_normal(shape=[num_attributes, hidden1], stddev=0.1), name="weights")
        bias = tf.Variable(tf.constant(0.0, shape=[hidden1]), name="bias")
        activation = tf.nn.relu(
            tf.matmul(x, weights1) + bias, name="relu_act")
        tf.summary.histogram("first_activation", activation)

    with tf.name_scope("second_layer"):
        weights2 = tf.Variable(
            tf.random_normal(shape=[hidden1, hidden2], stddev=0.1),
            name="weights")
        bias2 = tf.Variable(tf.constant(0.0, shape=[hidden2]), name="bias")
        activation2 = tf.nn.relu(
            tf.matmul(activation, weights2) + bias2, name="relu_act")
        tf.summary.histogram("second_activation", activation2)

    with tf.name_scope("output_layer"):
        weights3 = tf.Variable(
            tf.random_normal(shape=[hidden2, num_types + 1], stddev=0.5), name="weights")
        bias3 = tf.Variable(tf.constant(1.0, shape=[num_types+1]), name="bias")
        output = tf.add(
            tf.matmul(activation2, weights3, name="mul"), bias3, name="output")
        tf.summary.histogram("output_activation", output)

    y_ = tf.placeholder(tf.float32, [None, num_types+1])

    with tf.name_scope("loss"):
        cross_entropy = tf.reduce_mean(
            tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=output))
        tf.summary.scalar("cross_entropy", cross_entropy)
    with tf.name_scope("train"):
        train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)

    with tf.name_scope("tests"):
        correct_prediction = tf.equal(tf.argmax(output, 1), tf.argmax(y_, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        tf.summary.scalar("accuracy", accuracy)

    summary_op = tf.summary.merge_all()
    sess = tf.InteractiveSession()
    writer = tf.summary.FileWriter("./wineDnnLow", sess.graph)
    tf.global_variables_initializer().run()
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord, sess=sess)


    try:
        step = 0
        while not coord.should_stop() and step < epochs:
            #  train
            ex, lab = sess.run([examples_train, labels_train])
            _ = sess.run([train_step], feed_dict={x: ex, y_: lab})
            #  test
            if step % test_interval == 0:
                ex, lab = sess.run([examples_test, labels_test])
                summery, test_accuracy = sess.run([summary_op, accuracy], feed_dict={x: ex, y_: lab})
                writer.add_summary(summery, step)
                print("accurary= {0:f} on {}".format(test_accuracy, step))
            step += 1
    except tf.errors.OutOfRangeError:
        print("Done training for %d steps" % (step))

    coord.request_stop()
    coord.join(threads)
    sess.close()



def main():
    train_and_test(10, 20, 0.5, 700, 30, 10, 1)


if __name__ == '__main__':
    main()

问题是,准确不会收敛,似乎得到随机值。 但是,当我尝试tf.contrib.learn.DNNClassifier时,我的数据得到了很好的分类。 那么,任何人都可以给我一些提示,问题出在我自己创建的DNN上吗?

此外,我还有第二个问题。在训练中,我在session.run()上提供train_step,而不是在测试中提供。这是否确保权重不受影响,因此图表不通过测试来学习?

编辑:如果我使用MNIST数据集及其批量处理,我的网络表现良好。因此,我认为问题是由input_pipeline引起的。

1 个答案:

答案 0 :(得分:1)

快速浏览数据集向我表明,我要做的第一件事是将其标准化(减去平均值,除以标准偏差)。也就是说,与MNIST相比,它仍然是一个非常小的数据集,所以不要指望一切都能完全相同。

如果您不确定输入管道,只需将所有数据加载到内存中,而不是使用输入管道。

一些一般性说明:

  1. 您的输入管道无法随时保存。你的数据集很小,所以我只使用feed_dict,但如果它很大,你最好删除占位符,只使用input_pipeline的输出(并构建一个单独的图形)用于测试)。
  2. tf.layers API用于常见图层类型。例如,您的推理部分可以通过以下三行有效减少。

    activation = tf.layers.dense(x, hidden1, activation=tf.nn.relu)
    activation2 = tf.layers.dense(x, hidden2, activation=tf.nn.relu)
    output = tf.layers.dense(activation2, num_types+1)
    
  3. (你不会有相同的初始化,但你可以指定带有可选参数的那些。默认值是一个很好的起点。)

    1. GradientDescentOptimizer非常原始。我目前最喜欢的是AdamOptimizer,但可以尝试其他人。如果这看起来过于复杂,MomentumOptimizer通常会在复杂性和性能优势之间进行良好的权衡。
    2. 查看tf.estimator.Estimator API。它会使你做的很多事情变得更容易,并迫使你将数据加载与模型本身分开(这是一件好事)。

    3. 查看tf.contrib.data.Dataset API进行数据预处理。队列已经在tensorflow中存在了一段时间,这就是大多数教程的编写方式,但{I} {{}}} API在我看来更直观/更容易。同样,对于这种情况,您可以轻松地将所有数据加载到内存中,这有点过分。有关如何从CSV文件开始使用Dataset,请参阅this问题。