简体   繁体   English

如何在keras自定义正则化器中使用初始化图层权重?

[英]How can I use initialized layer weights in a keras custom regularizer?

I'm trying to create a custom Keras regularizer that uses the distance of the layer's weights from its original weights, but what I used doesn't seem to work. 我正在尝试创建一个自定义Keras正则化器,它使用层的权重与其原始权重的距离,但我使用的似乎不起作用。 It seems that this regularizer has no effect at all on the training and on the loss function. 似乎这个正规化器对训练和损失函数没有任何影响。

Can you please help me find what I'm doing wrong? 你能帮我找一下我做错的事吗?

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)

(I'm using tensorflow as the backend) (我使用tensorflow作为后端)

Edit: After playing with this class a bit, I noted something strange: It's as if the regularizer object is being created over and over again in the training in each batch, which will explain why I'm getting zeros. 编辑:在玩了这个类之后,我注意到一些奇怪的事情:就好像在每个批次的训练中一遍又一遍地创建正规化对象,这将解释为什么我会得到零。 I got to this conclusion by changing the class to - 通过将课程改为 - 我得到了这个结论

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)

And seeing that the loss does, in fact, suffer the penalty that follows from _ugly_check being 1 throughout the training. 事实上,在整个训练过程中,看到损失确实会受到_ugly_check为1的惩罚。

I still don't fully understand all the nuts and bolts behind it, but here is where I got it wrong: 我仍然不完全理解它背后的所有细节和螺栓,但这里是我弄错了:

I assumed that the regularizer is used by the model during training, but it is in fact only used once when building the computational graph that the model will use. 我假设模型在训练期间使用了正则化器,但事实上它只在构建模型将使用的计算图时使用一次。 So what Keras learnt to do in its computational graph was "take the weights, subtract them from themselves, and return the coefficient times the norm". 因此,Keras在其计算图中学会做的是“获取权重,从自身中减去它们,并将系数返回到常数”。 After my edit, what it learnt to do was "take the weights, and return 10000". 在我编辑之后,它学会做的是“获取权重,并返回10000”。

So this is all fixed by changing the __call__ function to: 所以这一切都通过将__call__函数更改为:

def __call__(self, weight_matrix):
        diff_matrix = weight_matrix - K.eval(weight_matrix)
        return self._coeff * self._norm(diff_matrix)

What this does is that it now subtracts a concrete ndarray from the given weights and then computes the difference. 这样做的是它现在从给定的权重中减去一个具体的ndarray,然后计算差异。 This ndarray is, of course, the initial weights, since these are the first weights that this object encounters. 当然,这个ndarray是初始权重,因为这是这个对象遇到的第一个权重。

Feel free to correct me and give a more accurate answer. 随意纠正我,并给出一个更准确的答案。 As I said - I still don't understand this to its fullest. 正如我所说 - 我仍然不能完全理解这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM