我正在迈出深度学习和张量流的第一步。因此,我有一些问题。
根据教程和入门我创建了一个带隐藏层的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引起的。
答案 0 :(得分:1)
快速浏览数据集向我表明,我要做的第一件事是将其标准化(减去平均值,除以标准偏差)。也就是说,与MNIST相比,它仍然是一个非常小的数据集,所以不要指望一切都能完全相同。
如果您不确定输入管道,只需将所有数据加载到内存中,而不是使用输入管道。
一些一般性说明:
feed_dict
,但如果它很大,你最好删除占位符,只使用input_pipeline
的输出(并构建一个单独的图形)用于测试)。将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)
(你不会有相同的初始化,但你可以指定带有可选参数的那些。默认值是一个很好的起点。)
GradientDescentOptimizer
非常原始。我目前最喜欢的是AdamOptimizer
,但可以尝试其他人。如果这看起来过于复杂,MomentumOptimizer
通常会在复杂性和性能优势之间进行良好的权衡。查看tf.estimator.Estimator
API。它会使你做的很多事情变得更容易,并迫使你将数据加载与模型本身分开(这是一件好事)。
查看tf.contrib.data.Dataset
API进行数据预处理。队列已经在tensorflow中存在了一段时间,这就是大多数教程的编写方式,但{I} {{}}} API在我看来更直观/更容易。同样,对于这种情况,您可以轻松地将所有数据加载到内存中,这有点过分。有关如何从CSV文件开始使用Dataset
,请参阅this问题。