Tensorflow:最小化int64数据上的L2损失而不转换为float32,因为转换给出“无渐变”错误

时间:2016-10-27 21:11:59

标签: python tensorflow

当我将张量转换为float32时,我遇到了错误:“没有为任何变量提供渐变”。但是没有强制转换,我得到的错误是期望的类型是float而不是int。所以无论如何,我似乎无法找到继续前进的方法......

在我的设置中,我试图最小化两个张量差异的平方误差。

softmax_w = tf.Variable(tf.zeros([SIZE_LSTM_UNITS, NUM_CLASSES], dtype=tf.float32))
softmax_b = tf.Variable(tf.zeros([NUM_CLASSES], dtype=tf.float32))
logits = tf.matmul(out, softmax_w) + softmax_b

如果我用铸造计算损失如下:

predDiff = tf.cast(tf.sub(tf.arg_max(logits, 1), tf.arg_max(train_labels, 1)), tf.float32)
l2loss = tf.nn.l2_loss(predDiff)
trainStep = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(l2loss)

其中,logits和train_labels是1-hot向量,然后我得到以下错误:

  

trainStep =   tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(l2loss)文件   “/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py”   第198行,最小化名称=名称)文件   “/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py”   第309行,在apply_gradients(converted_grads_and_vars,)中)ValueError:   没有为任何变量提供渐变:((无,   < tensorflow.python.ops.variables.Variable对象位于0x7f2c7363bf90>),   (无,< tensorflow.python.ops.variables.Variable对象at   0x7f2ce284e9d0>),(无,< tensorflow.python.ops.variables.Variable   对象在0x7f2ce284e510>),(无,   < tensorflow.python.ops.variables.Variable对象位于0x7f2ce26cf050>),   (无,< tensorflow.python.ops.variables.Variable对象at   0x7f2ce26cf450>),(无,< tensorflow.python.ops.variables.Variable   对象在0x7f2ce2c9d510>),(无,   < tensorflow.python.ops.variables.Variable对象位于0x7f2ce287ae90>))

相反,如果我计算损失而不进行铸造,如下所示:

predDiff = tf.sub(tf.arg_max(logits, 1), tf.arg_max(train_labels, 1))

然后,我收到以下错误:

  

trainStep =   tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(l2loss)文件   “/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py”   第196行,最小化grad_loss = grad_loss)文件   “/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py”   第238行,在compute_gradients中self._assert_valid_dtypes([loss])文件   “/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py”   第379行,_assert_valid_dtypes dtype,t.name,[v for v in   valid_dtypes]))ValueError:L2Loss的类型为tf.int64:0,   预期:[tf.float32,tf.float64,tf.float16]。

但是,如果我像下面那样使用交叉熵,那么一切都会顺利。

crossEnt = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, train_labels))

但是,我想使用L2Loss,因为最终我正在计算RMSE来比较性能。我不确定我是否遗漏了一些明显的东西。任何帮助,将不胜感激。

2 个答案:

答案 0 :(得分:1)

网络中的所有权重都必须是可学习的。为了实现这一点,操作必须是可区分的 - 我们必须能够应用渐变。我们不能在x - y函数上应用从整数到整数的渐变,所以我认为问题出在你要浮动的位置。

而不是:

predDiff = tf.cast(tf.sub(tf.arg_max(logits, 1), tf.arg_max(train_labels, 1)), tf.float32)

在应用arg_maxsub之前尝试投射:

float_logits = tf.cast(logits, tf.float32)
float_labels = tf.cast(train_labels, tf.float32)
predDiff = tf.sub(tf.arg_max(float_logits, 1), tf.arg_max(float_labels, 1)))

这样,我们实际上可以计算并应用sub和arg_max的渐变。

答案 1 :(得分:0)

不确定这是否会有所帮助,但由于您的预测和目标已经整齐,这可能会起作用,因为tf.subtract和tf.multiply都可以使用整数:

self.diff = tf.subtract(self.predictions, self.targets) # Compute difference
self.diff = tf.multiply(self.diff,self.diff, name='diff') # Square the difference
self.loss = tf.reduce_sum(self.diff) # Compute the sum