Keras成本函数尝试将预测张量舍入到最接近的整数时出错

时间:2017-09-12 04:25:32

标签: python machine-learning tensorflow keras

我在倒数第二层使用sigmoid激活,然后在最后一层使用tf.images.resize_images()调整大小。

目标张量的最大值为1.0。在骰子错误成本函数中。

def dice(y_true, y_pred):
    return 1.0-dice_coef(y_true, y_pred, 1e-5, 0.5)

def dice_coef(y_true, y_pred, smooth, thresh, axis = [1,2,3]):
    y_pred = K.round(y_pred)
    inse = K.sum(K.dot(y_true, K.transpose(y_pred)), axis=axis)
    l = K.sum(y_pred, axis=axis)
    r = K.sum(y_true, axis=axis)
    hard_dice = (2. * inse + smooth) / (l + r + smooth)
    hard_dice = K.mean(hard_dice)
    return hard_dice

当我运行代码时,我收到以下错误。但是,当我删除K.round(y_pred)时,错误消失了。关于如何解决这个问题的任何想法?

loss,acc,err = Final_Model.train_on_batch(Train_image,Label)
File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\keras\engine\training.py", line 1761, in train_on_batch
self._make_train_function()
  File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\keras\engine\training.py", line 960, in _make_train_function
loss=self.total_loss)
 File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\keras\legacy\interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
  File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\keras\optimizers.py", line 358, in get_updates
new_a = self.rho * a + (1. - self.rho) * K.square(g)
 File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\keras\backend\tensorflow_backend.py", line 1358, in square
return tf.square(x)
 File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\tensorflow\python\ops\math_ops.py", line 447, in square
return gen_math_ops.square(x, name=name)
 File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\tensorflow\python\ops\gen_math_ops.py", line 2591, in square
result = _op_def_lib.apply_op("Square", x=x, name=name)
 File "C:\local\Anaconda3-4.1.1-Windows-x86_64\envs\tensorflow-cpu\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 508, in apply_op
(input_name, err))
ValueError: Tried to convert 'x' to a tensor and failed. Error: None values not supported` 

1 个答案:

答案 0 :(得分:2)

神经网络使用梯度下降来训练:在高维参数空间中,您总是在最陡的负梯度方向上调整它们以找到最小值。为此,您的损失函数必须是可微分的。但是,舍入函数不是(image source)

Src.: http://mathworld.wolfram.com/NearestIntegerFunction.html

正如您所看到的,模具渐变在两个整数之间是完全未定义的,在其他任何地方都是零。因此,即使您手动定义不连续处的梯度,由于链规则,您的反向传播梯度也将始终为零。

我不知道您网络的确切用途。但是,尝试将网络从回归(您预测连续数字)问题转换为分类问题可能是值得的,您可以在其中预测每个可能整数的类别得分而不是舍入。

<强>更新

如果您进行屏蔽或分割,实值输出将为您提供一种“概率”(至少在最后一层使用softmax时),您的像素或体素属于您想要屏蔽的区域。如果您对结果进行舍入,则会丢失用于培训网络的重要细节。得分为0.4的像素将得到与0.1相同的得分。因此,改变一个小的重量变化不会改变您的网络损失和梯度下降将无法正常工作。 original paper引入骰子丢失进行分割,也不使用舍入。如果您想将每个像素映射到前景/背景以用于可视化目的,您应该在计算损失后执行此操作。

但是,您始终可以定义自己的“渐变”,因为渐变下降不是优化的唯一方法。有衍生自由优化技术。但要小心。

如果它在实践中没有尝试,那么这将是我的方法,当你真的不想没有圆函数时(不保证这将以任何方式产生合理的结果):使用分布理论,你可以定义圆函数的导数,作为许多heaviside functions的导数的总和,留下dirac comb。如果现在用具有小标准偏差的正态分布替换delta分布,则会得到这样的效果:整数之间的梯度将引导它们在最接近的整数的方向上(具有精确介于两者之间的导数,其中导数为正态分布是0)。

免责声明:我从来没有在任何地方看到过这样的东西,最好的解决办法就是放弃圆形功能,但如果你想尝试一下,你可以试试这个。如果有人,有任何争论,为什么这只是明显错误,请告诉我!