Python 如何访问Keras层中张量形式的权重变量,以便按权重进行剪裁?

Python 如何访问Keras层中张量形式的权重变量,以便按权重进行剪裁?,python,tensorflow,deep-learning,keras,Python,Tensorflow,Deep Learning,Keras,我正在实现WGAN,需要裁剪权重变量 我目前正在使用Tensorflow和Keras作为高级API。因此,使用kera构建层以避免手动创建和初始化变量 问题是,一旦我得到了这些重量变量张量,就需要用tf.按值(x,v0,v1)剪裁重量变量,但我不知道如何安全地获得它们 一种可能的解决方案是使用tf.get_collection()获取所有可训练变量。但是我不知道如何只获取权重变量而不获取偏差变量 另一个解决方案是layer.get_weights(),但它可以获得numpy数组,尽管我可以使用n

我正在实现WGAN,需要裁剪权重变量

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

问题是,一旦我得到了这些重量变量张量,就需要用
tf.按值(x,v0,v1)
剪裁重量变量,但我不知道如何安全地获得它们

一种可能的解决方案是使用
tf.get_collection()
获取所有可训练变量。但是我不知道如何只获取权重变量而不获取偏差变量

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

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

是否有任何干净的方法可以仅在那些使用Tensorflow和Keras的
W
s上执行
clip\u by\u value

以下是如何轻松实现夹持权重并在模型中使用它

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_约束
将约束添加到
W
param,将b_约束添加到
b
(bias)param

可以使用constraints()类对参数实现新的约束

以下是如何轻松实现夹持权重并在模型中使用它

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_约束
将约束添加到
W
参数,并将b_约束添加到
b
(偏差)参数

谢谢您的回复。我已经在一个玩具问题上试过了,y=ax+b,效果非常好!使用Tensorflow实现它时存在问题。当使用model.fit时,它工作得很好,但是当使用sess.run(tran_step,…)和TF命令时,约束似乎不起作用。关于如何修复它有什么想法吗?您可能正在使用tensorflow中的optimizer对象。keras约束应用于keras中实现的优化器类。例如,对于SGD,以下是应用的约束:。因此,您需要使用keras优化器来获得训练步骤
tran\u step=model.optimizer.get\u更新(model.trainable\u权重、model.constraints、model.total\u损耗)
。否则,您可以使用
model.train\u on\u batch()
,它将处理所有keras内部构件和单个批次上的列车,就像
sess.run(tran\u step,…)
一样。非常感谢。我将尝试使用第一种解决方案。我将TF与Keras API一起使用而不是直接使用Kears的原因是我试图避免使用模型,因此我可以在将来向网络添加一些完整的体系结构(如PixelCNN中的GatedCNN)。顺便说一下,
keraslayers.W.name
似乎可以返回权重变量的名称。然而,我仍然不能将clip应用于
coulsion2d
层,因为TF报告称权重变量的形状没有明确给出。祝你好运。如果您还有其他疑问,请提出新问题。如果答案有帮助,请接受。谢谢你的回复。我已经在一个玩具问题上试过了,y=ax+b,效果非常好!使用Tensorflow实现它时存在问题。当使用model.fit时,它工作得很好,但是当使用sess.run(tran_step,…)和TF命令时,约束似乎不起作用。关于如何修复它有什么想法吗?您可能正在使用tensorflow中的optimizer对象。keras约束应用于keras中实现的优化器类。例如,对于SGD,以下是应用的约束:。因此,您需要使用keras优化器来获得训练步骤
tran\u step=model.optimizer.get\u更新(model.trainable\u权重、model.constraints、model.total\u损耗)
。否则,您可以使用
model.train\u on\u batch()
,它将处理所有keras内部构件和单个批次上的列车,就像
sess.run(tran\u step,…)
一样。非常感谢。我将尝试使用第一种解决方案。我将TF与Keras API一起使用而不是直接使用Kears的原因是我试图避免使用模型,因此我可以在将来向网络添加一些完整的体系结构(如PixelCNN中的GatedCNN)。顺便说一下,
keraslayers.W.name
似乎可以返回权重变量的名称。然而,我仍然不能将clip应用于
coulsion2d
层,因为TF报告称权重变量的形状没有明确给出。祝你好运。如果您还有其他疑问,请提出新问题。如果答案有帮助,请接受。