变量初始化
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#sess.run(tf.initialize_all_variables())
Note:
1 init = tf.global_variables_initializer()和with tf.Session() as sess:两句必须在一起使用,不能分开。
2 有时候需要使用 sess.run(tf.local_variables_initializer())
不初始化/初始化时分开使用/local初始化写成global初始化 可能出现错误如:Attempting to use uninitialized value batch_normalization/beta。如下例:
init = tf.global_variables_initializer()
logits = tf.constant([[[0.3, 0.0, 0.5, 0.2],
[0.44, 0.32, 0.23, 0.01],
[-0.2, 0.6, 0.5, 0.1]],
[[0.4, 0.0, 0.0, 0.2],
[0.4, 0.2, 0.3, 0.01],
[0.2, -0.6, -0.5, 0.15]]])
a = tf.layers.batch_normalization(logits)
with tf.Session() as sess:
sess.run(init)
print(logits.eval())
print(a.eval())
RNN初始化
正交初始化(orthogonal initialize)
正交初始化:用以解决深度网络下的梯度消失、梯度爆炸问题,在RNN中经常使用的参数初始化方法。
实现代码
def orthogonal(shape):
flat_shape = (shape[0], np.prod(shape[1:]))
a = np.random.normal(0.0, 1.0, flat_shape)
u, _, v = np.linalg.svd(a, full_matrices=False)
q = u if u.shape == flat_shape else v
return q.reshape(shape)
[正交初始化(orthogonal initialize)]
解决梯度问题的分析
参数矩阵特征值λi
如果|λi|>1,则步数增加时λt超出浮点范围,发生梯度爆炸,优化无法收敛;
如果|λi|<1,步数增加时λt变为0,发生梯度消失,优化停滞不前。
理想的情况是,特征值绝对值为1。则无论步数增加多少,梯度都在数值计算的精度内。这样的参数矩阵W是单位正交阵。把转移矩阵初始化为单位正交阵,可以避免在训练一开始就发生梯度爆炸/消失现象,称为orthogonal initialization。
具体参考[RNN的梯度消失/爆炸与正交初始化]
梯度爆炸/消失在rnn参数矩阵的可视化展示[Explaining and illustrating orthogonal initialization for recurrent neural networks]
其他解决方法
除了正交初始化,在RNN类型网络训练中,还可以使用如下方法解决梯度消失/爆炸问题:
- 使用ReLU激活函数->解决梯度消失
- 对梯度进行剪切(gradient clipping)->解决梯度爆炸
- 引入更复杂的结构,例如LSTM、GRU->解决梯度消失
from: -柚子皮-
ref: