最近我尝试使用float16在TF中训练CNN.令我惊讶的是,即使TF声称支持它一段时间,它仍以各种方式被打破.例如,无论网络如何,float16优化都会在第二步中导致NaN丢失.
import tensorflow as tf
import numpy as np
slim = tf.contrib.slim
dtype = tf.float16
shape = (4, 16, 16, 3)
inpt = tf.placeholder(dtype, shape, name='input')
net = slim.conv2d(inpt, 16, [3, 3], scope='conv',
weights_initializer=tf.zeros_initializer(),
# normalizer_fn=slim.batch_norm
)
loss = tf.reduce_mean(net)
opt = tf.train.AdamOptimizer(1e-3)
train_op = slim.learning.create_train_op(loss, opt)
val = np.zeros(shape)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(2):
print(sess.run(train_op, feed_dict={inpt: val}))
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这显然是一个错误:我在零输入上应用零卷积,我应该得到零梯度,不会改变零损失.它只是不能分歧.如果dtype是float32就行了.在CPU和GPU版本上都会发生NaN丢失.
然而,我被解雇了GH问题,一个随机的家伙关闭了这个问题,说它是打算行为:https://github.com/tensorflow/tensorflow/issues/7226
如果你用BN取消注释该线,它将在图形构建时间中断,因为BN假设移动平均线(和beta,gamma)总是float32并且不能正确地转换它们.这个问题也被关闭,显然被忽略了:https://github.com/tensorflow/tensorflow/issues/7164
我觉得我正在与ISP的第一线IT支持人员交谈.
当这样一个简单的"网络"失败时,有人可以解释我应该如何使用float16进行训练吗?现在报告错误的推荐方法是什么?
All*_*oie 14
看起来你需要一个略大的epsilon以避免在AdamOptimizer中零时刻的数值不稳定(默认值为1e-8).这适用于我的float16:
opt = tf.train.AdamOptimizer(1e-3, epsilon=1e-4)
Run Code Online (Sandbox Code Playgroud)
请求基于dtype设置epsilon是合理的(并且可能是这样的请求,或者更好的是拉取请求,将在GitHub上获得更积极的响应).请注意,GradientDescentOptimizer没有此类问题.
| 归档时间: |
|
| 查看次数: |
3551 次 |
| 最近记录: |