了解张量板:为什么要将 12 个张量发送到优化器?
Understanding tensorboard: why 12 tensors sent to optimizer?
所以我做了我能做的最简单的模型(perceptron/autoencoder),其中(除了输入生成)如下:
N = 64 * 64 * 3
def main():
x = tf.placeholder(tf.float32, shape=(None, 64, 64, 3), name="x")
with tf.name_scope("perceptron"):
W = tf.Variable(tf.random_normal([N, N], stddev=1), name="W")
b = tf.Variable(tf.random_normal([], stddev=1), name="b")
y = tf.add(tf.matmul( tf.reshape(x, [-1,N]), W), b, name="y")
act = tf.nn.sigmoid(y, name="sigmoid")
yhat = tf.reshape(act, [-1, 64, 64, 3], name="yhat")
with tf.name_scope("mse"):
sq_error = tf.reduce_mean(np.square(x - yhat), axis=1)
cost = tf.reduce_mean( sq_error, name="cost" )
tf.summary.scalar("cost", cost)
with tf.name_scope("conv_opt"): #Should just be called 'opt' here
training_op = tf.train.AdamOptimizer(0.005).minimize(cost, name="train_op")
with tf.device("/gpu:0"):
config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
sess.run(tf.global_variables_initializer())
logdir = "log_directory"
if os.path.exists(logdir):
shutil.rmtree(logdir)
os.makedirs(logdir)
input_gen = input.input_generator_factory(...)
input_gen.initialize((64,64,3), 512)
merged = tf.summary.merge_all()
train_writer = tf.summary.FileWriter(logdir, sess.graph)
for i in range(10):
batch = input_gen.next_train_batch()
summary,_ = sess.run([merged, training_op], feed_dict={x : batch})
train_writer.add_summary(summary, i)
print("Iteration %d completed" % (i))
if __name__ == "__main__":
main()
这会产生以下 tensorboard graph。无论如何,我假设从 'perception' 到 'conv_opt' 的粗箭头(可能应该被称为 'opt',抱歉)对应于反向传播误差信号,(而 ?x64x64x3 箭头对应于推理).但是为什么 12 张量呢?我不明白这个数字是从哪里来的。我本以为会更少,实际上只对应 W
和 b
。有人可以解释一下这是怎么回事吗?
我认为原因是当您添加 tf.train.AdamOptimizer(0.005).minimize(cost)
操作时,它隐含地假设您优化了所有可训练变量(因为您没有另外指定)。
因此,您需要知道这些变量的值以及参与 cost
计算的所有中间张量的值,包括梯度(它们也是张量并隐式添加到计算图中)。现在让我们从 perceptron
:
计算变量和张量
W
b
tf.reshape(x, [-1,N])
tf.matmul( ..., W)
- 它相对于第一个参数的梯度。
- 它相对于第二个参数的梯度。
tf.add(..., b, name="y")
- 它相对于第一个参数的梯度。
- 它相对于第二个参数的梯度。
tf.nn.sigmoid(y, name="sigmoid")
- 它的梯度。
tf.reshape(act, [-1, 64, 64, 3], name="yhat")
实际上我并不是 100% 确定会计是这样进行的,但是您知道数字 12 可能来自哪里。
作为练习,我们可以看到这种会计也解释了数字 9 在您的图表中的来源:
x - yhat
- 它相对于第一个参数的梯度
- 它相对于第二个参数的梯度
np.square(...)
- 它的梯度
tf.reduce_mean(..., axis=1)
- 它的梯度
tf.reduce_mean( sq_error, name="cost" )
- 它的梯度
所以我做了我能做的最简单的模型(perceptron/autoencoder),其中(除了输入生成)如下:
N = 64 * 64 * 3
def main():
x = tf.placeholder(tf.float32, shape=(None, 64, 64, 3), name="x")
with tf.name_scope("perceptron"):
W = tf.Variable(tf.random_normal([N, N], stddev=1), name="W")
b = tf.Variable(tf.random_normal([], stddev=1), name="b")
y = tf.add(tf.matmul( tf.reshape(x, [-1,N]), W), b, name="y")
act = tf.nn.sigmoid(y, name="sigmoid")
yhat = tf.reshape(act, [-1, 64, 64, 3], name="yhat")
with tf.name_scope("mse"):
sq_error = tf.reduce_mean(np.square(x - yhat), axis=1)
cost = tf.reduce_mean( sq_error, name="cost" )
tf.summary.scalar("cost", cost)
with tf.name_scope("conv_opt"): #Should just be called 'opt' here
training_op = tf.train.AdamOptimizer(0.005).minimize(cost, name="train_op")
with tf.device("/gpu:0"):
config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
sess.run(tf.global_variables_initializer())
logdir = "log_directory"
if os.path.exists(logdir):
shutil.rmtree(logdir)
os.makedirs(logdir)
input_gen = input.input_generator_factory(...)
input_gen.initialize((64,64,3), 512)
merged = tf.summary.merge_all()
train_writer = tf.summary.FileWriter(logdir, sess.graph)
for i in range(10):
batch = input_gen.next_train_batch()
summary,_ = sess.run([merged, training_op], feed_dict={x : batch})
train_writer.add_summary(summary, i)
print("Iteration %d completed" % (i))
if __name__ == "__main__":
main()
这会产生以下 tensorboard graph。无论如何,我假设从 'perception' 到 'conv_opt' 的粗箭头(可能应该被称为 'opt',抱歉)对应于反向传播误差信号,(而 ?x64x64x3 箭头对应于推理).但是为什么 12 张量呢?我不明白这个数字是从哪里来的。我本以为会更少,实际上只对应 W
和 b
。有人可以解释一下这是怎么回事吗?
我认为原因是当您添加 tf.train.AdamOptimizer(0.005).minimize(cost)
操作时,它隐含地假设您优化了所有可训练变量(因为您没有另外指定)。
因此,您需要知道这些变量的值以及参与 cost
计算的所有中间张量的值,包括梯度(它们也是张量并隐式添加到计算图中)。现在让我们从 perceptron
:
W
b
tf.reshape(x, [-1,N])
tf.matmul( ..., W)
- 它相对于第一个参数的梯度。
- 它相对于第二个参数的梯度。
tf.add(..., b, name="y")
- 它相对于第一个参数的梯度。
- 它相对于第二个参数的梯度。
tf.nn.sigmoid(y, name="sigmoid")
- 它的梯度。
tf.reshape(act, [-1, 64, 64, 3], name="yhat")
实际上我并不是 100% 确定会计是这样进行的,但是您知道数字 12 可能来自哪里。
作为练习,我们可以看到这种会计也解释了数字 9 在您的图表中的来源:
x - yhat
- 它相对于第一个参数的梯度
- 它相对于第二个参数的梯度
np.square(...)
- 它的梯度
tf.reduce_mean(..., axis=1)
- 它的梯度
tf.reduce_mean( sq_error, name="cost" )
- 它的梯度