我在训练一个卷积神经网络(CNN),我认为使用sess.run()
导致我的训练速度非常慢。
本质上,我使用的是mnist
数据集…
from tensorflow.examples.tutorials.mnist import input_data......features = input_data.read_data_sets("/tmp/data/", one_hot=True)
问题在于,CNN的第一层必须接受形式为[batch_size, 28, 28, 1]
的图像,这意味着我必须在将图像输入CNN之前进行转换。
我在脚本中做了如下处理…
x = tf.placeholder(tf.float32, [None, 28, 28, 1])y = tf.placeholder(tf.float32, [None, 10]) ......with tf.Session() as sess: for epoch in range(25): total_batch = int(features.train.num_examples/500) avg_cost = 0 for i in range(total_batch): batch_xs, batch_ys = features.train.next_batch(10) # 注意这一行。 _, c = sess.run([train_op, loss], feed_dict={x:sess.run(tf.reshape(batch_xs, [10, 28, 28, 1])), y:batch_ys}) avg_cost += c / total_batch if (epoch + 1) % 1 == 0: print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(avg_cost))
注意注释的那一行。我从训练集中取出第一个批次,并将其重塑为正确的格式[batch_size, 28, 28, 1]
。我必须每次都调用sess.run()
,我认为这是导致训练速度变慢的原因。
我该如何避免这种情况?我尝试在另一个脚本中使用numpy
重新格式化数据,但仍然遇到问题,因为我无法在不运行sess.run()
的情况下输入numpy
数组。有人能告诉我如何在训练会话之外格式化数据吗?也许我可以在另一个脚本中格式化数据,然后加载到包含我的CNN的脚本中?
回答:
你绝对不应该在每次迭代时在新的操作上使用内部的sess.run()
(尽管我不确定这真的会让你慢下来多少)。你应该做以下之一:
- 设置一个与你的输入形状相同的占位符,例如
[None, 28*28*1]
,然后在网络开始时使用tf.reshape([None, 28, 28, 1])
(而不是你的tf.placeholder([None, 28, 28, 1])
)
或者
- 保留你的神经网络,使用numpy的reshape而不是tensorflow进行重新格式化:
_, c = sess.run([train_op, loss], feed_dict={x:batch_xs.reshape( [-1, 28, 28, 1]), y:batch_ys})
如果你只是写_, c = sess.run([train_op, loss], feed_dict={x:tf.reshape(batch_xs, [10, 28, 28, 1]), y:batch_ys})
,这可能也行得通,但你不应该这样做,因为这会在每次迭代时在你的图中创建一个新的操作。