python - Keras 损失仅在纪元结束时变为 nan
问题描述
我正在观察 Keras 的一些奇怪行为。我正在训练一个小模型,其中训练损失仅在第一个时期结束时变为 nan。
因此,如果我有 100 个批次,并且我在第 99 个批次处终止训练,然后再继续进行 99 个批次,它训练得很好。否则,一旦它到达一个 epoch 的末尾,它总是返回 nan。
我正在使用自定义损失函数:
def corr(x, y):
xc = x - K.mean(x)
yc = y - K.mean(y)
r_num = K.mean(xc*yc)
r_den = K.std(x)*K.std(y)
return r_num/r_den
我已经尝试了所有标准技巧,比如降低学习率、削减梯度的范数和值以及增加批量大小。只有在将批量大小增加到不切实际的情况下,例如 100,000(我有 100 万个数据点),它实际上会持续超过一个时期,但我想了解导致这种奇怪行为的最后发生的事情。我还尝试了不同的优化器(目前使用 Adam),并在不同的系统上进行了尝试,以确保在我的一台计算机上没有问题。
我的输入和输出是一维的,我的模型总结如下。
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_7 (InputLayer) (None, 1) 0
_________________________________________________________________
dense_7 (Dense) (None, 100) 200
_________________________________________________________________
dense_8 (Dense) (None, 100) 10100
_________________________________________________________________
dense_9 (Dense) (None, 1) 101
=================================================================
Total params: 10,401
Trainable params: 10,401
Non-trainable params: 0
_________________________________________________________________
Keras 在一个时代结束时有什么特别之处吗?除了标准的记录器回调之外,我找不到任何东西。我还编写了一个自定义回调,它每批评估我的模型并存储输出,当我随着时间的推移绘制它时,它似乎不会爆炸或做任何奇怪的事情。看起来它正在慢慢改善,然后训练就结束了。
解决方案
可能它是由损失函数中除以零引起的。通过向其添加一个小常数来确保分母始终为正。您可以K.epsilon()
为此目的使用:
return r_num / (r_den + K.epsilon())
推荐阅读
- swift - 滚动后,我的计时器标签占用了一个新数字
- javascript - Javascript:if else 语句
- java - Spring Data 对 NamedNativeQuery (JPA-Hibernate-MySql) 进行分页和排序
- python - 张量流内存SIGABRT
- javascript - 添加到列表
使用 jQuery - r - 基于R中的小数子集数据框行?
- regex - 正则表达式拾取包含 2 个破折号的字符串
- python - 使用 Tab 键正确切换到 ttk.TreeView
- bash - rsync diff,但仅对某些文件扩展名进行过滤
- excel - Excel VBA中的连接值