我试图使用Keras来实现需要权重削减的算法的一部分,即在梯度更新后限制权重值。到目前为止,我还没有通过网络搜索找到任何解决方案。
对于后台,这与WGANs算法有关:
https://arxiv.org/pdf/1701.07875.pdf
如果你看一下第8页的算法1,你会看到以下内容:
我已经强调了我尝试在Keras中实现的线条:在计算用于更新网络权重的渐变之后,我想确保所有权重都在某些权重之间我可以设置的值[-c,c]。
我怎么能在Keras这样做呢?
作为参考,我使用的是TensorFlow后端。我现在不介意深入研究并加入凌乱的快速修复工具。
谢谢!
答案 0 :(得分:14)
创建优化器对象时设置参数clipvalue
。 它将完全符合您的要求。
# all parameter gradients will be clipped to
# a maximum value of 0.5 and
# a minimum value of -0.5.
rsmprop = RMSprop(clipvalue=0.5)
然后使用此对象进行模型编译
model.compile(loss='mse', optimizer=rsmprop)
有关更多参考检查:here。
此外,我更倾向于使用clipnorm
而不是clipvalue
因为clipnorm
优化保持稳定。例如,假设您有2个参数,渐变结果为[0.1, 3]
。通过使用clipvalue
,渐变将变为[0.1,0.5],即有可能最陡峭的方向可以大幅改变。虽然clipnorm
没有类似的问题,因为所有渐变都将被适当地缩放,并且方向将被保留,并且同时确保对梯度的大小的约束。
编辑:问题是权重裁剪而不是渐变裁剪:
权重的渐变剪切不是keras代码的一部分。但是maxnorm
对权重的限制是。检查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
参数和b_constraint
到b
(偏见)param