如何以张量形式访问Keras图层中的权重变量clip_by_weight?

时间:2017-03-01 11:13:20

标签: python tensorflow deep-learning keras

我正在实施WGAN,需要剪辑权重变量。

我目前正在使用 Tensorflow Keras 作为高级API。因此,使用Keras构建图层以避免手动创建和初始化变量。

问题是WGAN需要剪辑重量变量,这可以在我获得那些重量变量张量后使用tf.clip_by_value(x, v0, v1)完成,但我不知道如何安全地获取它们。

一种可能的解决方案可能是使用tf.get_collection()来获取所有可训练的变量。但我不知道如何在没有偏见变量的情况下只获得 weight 变量。

另一种解决方案是layer.get_weights(),但它获得numpy个数组,虽然我可以使用numpy API剪切它们并使用layer.set_weights()设置它们,但这可能需要CPU- GPU公司,可能不是一个好的选择,因为需要在每个列车步骤上执行剪辑操作。

我知道的唯一方法是使用精确变量名称直接访问它们,我可以从TF低级API或TensorBoard获取这些变量名称,但这可能不安全,因为Keras的命名规则无法保证保持稳定。

是否有任何干净的方法只能在使用Tensorflow和Keras的clip_by_value上执行W

1 个答案:

答案 0 :(得分:4)

您可以使用约束(here)类来实现对参数的新约束。

以下是如何轻松实现权重剪辑并在模型中使用它。

from keras.constraints import Constraint
from keras import backend as K

class WeightClip(Constraint):
    '''Clips the weights incident to each hidden unit to be inside a range
    '''
    def __init__(self, c=2):
        self.c = c

    def __call__(self, p):
        return K.clip(p, -self.c, self.c)

    def get_config(self):
        return {'name': self.__class__.__name__,
                'c': self.c}

import numpy as np
from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(30, input_dim=100, W_constraint = WeightClip(2)))
model.add(Dense(1))

model.compile(loss='mse', optimizer='rmsprop')

X = np.random.random((1000,100))
Y = np.random.random((1000,1))

model.fit(X,Y)

我已经测试了上面代码的运行,但没有测试约束的有效性。您可以通过使用model.get_weights()model.layers[idx].get_weights()训练后获取模型权重并检查其是否遵守约束来实现此目的。

注意:约束不会添加到所有模型权重中..而只是添加到其使用的特定图层的权重,W_constraint也会将W param和b_constraint的约束添加到{{1 (偏见)param