“让Keras更酷一些!”:分层的学习率和自由的梯度( 七 )

其中方法中的第一句就是获取原始梯度的 , 后面则提供了两种梯度裁剪方法 。 不难想到 , 只需要重写优化器的 get_gradients 方法 , 就可以实现对梯度的任意操作了 , 而且这个操作不影响优化器的更新步骤(即不影响 get_updates 方法) 。

处处皆对象:覆盖即可

怎么能做到只修改 get_gradients 方法呢?这得益于 Python 的哲学——“处处皆对象” 。 Python \n是一门面向对象的编程语言 , Python 中几乎你能碰到的一切变量都是一个对象 。 我们说 get_gradients 是优化器的一个方法 , 也可以说 \nget_gradients 的一个属性(对象) , 既然是属性 , 直接覆盖赋值即可 。

我们来举一个最粗暴的例子(恶作剧):

其实这样做的事情很无聊 , 就是把所有梯度置零了(然后你怎么优化它都不动了) , 但这个恶作剧例子已经足够有代表性了——你可以将所有梯度置零 , 你也可以将梯度做任意你喜欢的操作 。 比如将梯度按照 l1 范数而非 l2 范数裁剪 , 又或者做其他调整 。

假如我只想操作部分层的梯度怎么办?那也简单 , 你在定义层的时候需要起一个能区分的名字 , 然后根据 params 的名字做不同的操作即可 。 都到这一步了 , 我相信基本是“一法通 , 万法皆通”的了 。

推荐阅读