Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 中间层使tensorflow优化器停止工作_Python_Tensorflow_Machine Learning_Deep Learning_Autoencoder - Fatal编程技术网

Python 中间层使tensorflow优化器停止工作

Python 中间层使tensorflow优化器停止工作,python,tensorflow,machine-learning,deep-learning,autoencoder,Python,Tensorflow,Machine Learning,Deep Learning,Autoencoder,该图训练了一个简单的信号标识编码器,事实上显示了优化器正在进化权重: import tensorflow as tf import numpy as np initia = tf.random_normal_initializer(0, 1e-3) DEPTH_1 = 16 OUT_DEPTH = 1 I = tf.placeholder(tf.float32, shape=[None,1], name='I') # input W = tf.get_variable('W', shape=[

该图训练了一个简单的信号标识编码器,事实上显示了优化器正在进化权重:

import tensorflow as tf
import numpy as np
initia = tf.random_normal_initializer(0, 1e-3)

DEPTH_1 = 16
OUT_DEPTH = 1
I = tf.placeholder(tf.float32, shape=[None,1], name='I') # input
W = tf.get_variable('W', shape=[1,DEPTH_1], initializer=initia, dtype=tf.float32, trainable=True) # weights
b = tf.get_variable('b', shape=[DEPTH_1], initializer=initia, dtype=tf.float32, trainable=True) # biases
O = tf.nn.relu(tf.matmul(I, W) + b, name='O') # activation / output

#W1 = tf.get_variable('W1', shape=[DEPTH_1,DEPTH_1], initializer=initia, dtype=tf.float32) # weights
#b1 = tf.get_variable('b1', shape=[DEPTH_1], initializer=initia, dtype=tf.float32) # biases
#O1 = tf.nn.relu(tf.matmul(O, W1) + b1, name='O1')

W2 = tf.get_variable('W2', shape=[DEPTH_1,OUT_DEPTH], initializer=initia, dtype=tf.float32) # weights
b2 = tf.get_variable('b2', shape=[OUT_DEPTH], initializer=initia, dtype=tf.float32) # biases
O2 = tf.matmul(O, W2) + b2

O2_0 = tf.gather_nd(O2, [[0,0]])

estimate0 = 2.0*O2_0

eval_inp = tf.gather_nd(I,[[0,0]])
k = 1e-5
L = 5.0
distance = tf.reduce_sum( tf.square( eval_inp - estimate0 ) )

opt = tf.train.GradientDescentOptimizer(1e-3)
grads_and_vars = opt.compute_gradients(distance, [W, b, #W1, b1,
  W2, b2])
clipped_grads_and_vars = [(tf.clip_by_value(g, -4.5, 4.5), v) for g, v in grads_and_vars]

train_op = opt.apply_gradients(clipped_grads_and_vars)

saver = tf.train.Saver()
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
  sess.run(init_op)
  for i in range(10000):
    print sess.run([train_op, I, W, distance], feed_dict={ I: 2.0*np.random.rand(1,1) - 1.0})
  for i in range(10):
    print sess.run([eval_inp, W, estimate0], feed_dict={ I: 2.0*np.random.rand(1,1) - 1.0})
但是,当我取消注释中间隐藏层并训练生成的网络时,我看到权重不再变化:

import tensorflow as tf
import numpy as np
initia = tf.random_normal_initializer(0, 1e-3)

DEPTH_1 = 16
OUT_DEPTH = 1
I = tf.placeholder(tf.float32, shape=[None,1], name='I') # input
W = tf.get_variable('W', shape=[1,DEPTH_1], initializer=initia, dtype=tf.float32, trainable=True) # weights
b = tf.get_variable('b', shape=[DEPTH_1], initializer=initia, dtype=tf.float32, trainable=True) # biases
O = tf.nn.relu(tf.matmul(I, W) + b, name='O') # activation / output

W1 = tf.get_variable('W1', shape=[DEPTH_1,DEPTH_1], initializer=initia, dtype=tf.float32) # weights
b1 = tf.get_variable('b1', shape=[DEPTH_1], initializer=initia, dtype=tf.float32) # biases
O1 = tf.nn.relu(tf.matmul(O, W1) + b1, name='O1')

W2 = tf.get_variable('W2', shape=[DEPTH_1,OUT_DEPTH], initializer=initia, dtype=tf.float32) # weights
b2 = tf.get_variable('b2', shape=[OUT_DEPTH], initializer=initia, dtype=tf.float32) # biases
O2 = tf.matmul(O1, W2) + b2

O2_0 = tf.gather_nd(O2, [[0,0]])

estimate0 = 2.0*O2_0

eval_inp = tf.gather_nd(I,[[0,0]])

distance = tf.reduce_sum( tf.square( eval_inp - estimate0 ) )

opt = tf.train.GradientDescentOptimizer(1e-3)
grads_and_vars = opt.compute_gradients(distance, [W, b, W1, b1,
  W2, b2])
clipped_grads_and_vars = [(tf.clip_by_value(g, -4.5, 4.5), v) for g, v in grads_and_vars]

train_op = opt.apply_gradients(clipped_grads_and_vars)

saver = tf.train.Saver()
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
  sess.run(init_op)
  for i in range(10000):
    print sess.run([train_op, I, W, distance], feed_dict={ I: 2.0*np.random.rand(1,1) - 1.0})
  for i in range(10):
    print sess.run([eval_inp, W, estimate0], feed_dict={ I: 2.0*np.random.rand(1,1) - 1.0})
estimate0
的计算迅速收敛到某个固定值,该值与输入信号无关。我不知道为什么会这样

问题:

你知道第二个例子有什么问题吗


TL;DR:神经网络越深,你就越应该注意梯度流(参见“消失梯度”)。一种特殊情况是变量初始化


问题分析 我已将变量和梯度的tensorboard摘要添加到两个脚本中,并得到以下结果:

两层网络

三层网络

图表显示了
W:0
变量(第一层)的分布,以及它们如何从0历元更改为1000历元(可单击)。事实上,我们可以看到,在两层网络中,变化率要高得多。但我想注意梯度分布,在三层网络中,它更接近于0(第一个方差约为
0.005
,第二个方差约为
0.000002
,即小1000倍)。这就是消失梯度问题

以下是您感兴趣的帮助程序代码:

for g, v in grads_and_vars:
  tf.summary.histogram(v.name, v)
  tf.summary.histogram(v.name + '_grad', g)

merged = tf.summary.merge_all()
writer = tf.summary.FileWriter('train_log_layer2', tf.get_default_graph())

...

_, summary = sess.run([train_op, merged], feed_dict={I: 2*np.random.rand(1, 1)-1})
if i % 10 == 0:
  writer.add_summary(summary, global_step=i)
解决方案 所有深层网络都会在一定程度上受到这种影响 没有一个通用的解决方案可以自动神奇地修复任何网络。但是有一些技术可以把它推向正确的方向。初始化就是其中之一

我将您的正常初始化替换为:

W_init = tf.contrib.layers.xavier_initializer()
b_init = tf.constant_initializer(0.1)
有很多关于Xavier init的教程,你可以看看,例如。 请注意,我将bias init设置为略为正值,以确保ReLu输出对大多数神经元都为正值,至少在开始时是这样

这立即改变了局面:

权重的移动速度仍然没有以前快,但它们在移动(注意
W:0
值的比例),梯度分布在0处的峰值要小得多,因此更好


当然,这不是结束。为了进一步改进,您应该实现完整的自动编码器,因为当前损耗受
[0,0]
元素重建的影响,因此大多数输出不会用于优化。您还可以使用不同的优化器(Adam将是我的选择)和学习率。

这看起来非常令人兴奋。这个代码到底属于哪里?我最近才发现张力板

这是不是在回调中:

  for g, v in grads_and_vars:
  tf.summary.histogram(v.name, v)
  tf.summary.histogram(v.name + '_grad', g)

merged = tf.summary.merge_all()
writer = tf.summary.FileWriter('train_log_layer2', tf.get_default_graph())
这是在装修之后:

_, summary = sess.run([train_op, merged], feed_dict={I: 2*np.random.rand(1, 1)-1})
if i % 10 == 0:
  writer.add_summary(summary, global_step=i)

您如何验证权重是否在“演变”?在第二个示例中,EvanWeissburg值几乎没有变化,
距离不会变小,并且在推理循环中,
estimate0
使用不同的输入几乎没有变化值。在第一个示例中,
W
change,
distance
在一百个步骤中变成1e-5级,并且
estimate0
密切跟踪输入值下面的答案非常好。另一个提示:尝试其他一些优化器,比如Adam,而不是普通的梯度下降。你甚至可以尝试另一个激活功能,比如leaky relu。这就是为什么我使用keras而不是tensorflow直接-明智的默认感谢你的回复,它让我走上了正确的轨道你说的@denfromufa是什么意思。tensorflow中哪些是合理的默认值?你必须自己设置初始化器之类的东西,然后选择正确的优化器。@Maxim我真的看不出你在xavier初始化之后和之前的结果有什么不同。权重似乎是相同的,而梯度变化很小。但最大的区别在哪里?@thigi注意梯度分布的变化。它从
~0.000002
跳到
~0.1
。这对NN来说已经足够学习了