我正在尝试创建一个自定义 Keras 正则化器,它使用图层权重与其原始权重的距离,但我使用的似乎不起作用。似乎这个正则化器对训练和损失函数完全没有影响。你能帮我找出我做错了什么吗?class NormReg(): def __init__(self, coeff): self._coeff = coeff self._original_weights = None def _norm(self, weight_matrix): return K.sum(K.square(weight_matrix)) def __call__(self, weight_matrix): if self._original_weights is None: self._original_weights = weight_matrix diff_matrix = weight_matrix - self._original_weights return self._coeff * self._norm(diff_matrix)(我使用 tensorflow 作为后端)编辑: 在玩了这个类之后,我注意到了一些奇怪的事情:就好像正则化器对象在每批训练中一遍又一遍地创建,这将解释为什么我得到零。我通过将课程更改为 -class NormReg(): def __init__(self, coeff): self._ugly_check = 1 self._coeff = coeff self._original_weights = None def _norm(self, weight_matrix): return K.sum(K.square(weight_matrix)) def __call__(self, weight_matrix): if self._original_weights is None: self._original_weights = weight_matrix if self._ugly_check == 1: self._ugly_check = 0 return 10000 diff_matrix = weight_matrix - self._original_weights return self._coeff * self._norm(diff_matrix)事实上,损失确实会在整个训练过程中受到 _ugly_check 为 1 的惩罚。
1 回答
白衣非少年
TA贡献1155条经验 获得超0个赞
我仍然不完全理解它背后的所有细节,但这是我弄错的地方:
我假设模型在训练期间使用了正则化器,但实际上在构建模型将使用的计算图时只使用了一次。因此,Keras 在其计算图中学会了“获取权重,将它们从自身中减去,然后返回系数乘以范数”。在我编辑之后,它学会了“取权重,返回 10000”。
所以这一切都可以通过将__call__函数更改为:
def __call__(self, weight_matrix):
diff_matrix = weight_matrix - K.eval(weight_matrix)
return self._coeff * self._norm(diff_matrix)
这样做是它现在从给定的权重中减去一个具体的 ndarray,然后计算差异。当然,这个 ndarray 是初始权重,因为这些是该对象遇到的第一个权重。
请随时纠正我并给出更准确的答案。正如我所说 - 我仍然没有完全理解这一点。
添加回答
举报
0/150
提交
取消