2017-07-03 91 views
2

我使用具有tensorflow后端的Keras。
Will Keras仍然会计算我设置的图层的梯度trainable = FalseKeras是否计算冻结层的梯度?

当我修复大部分图层时,我没有观察到深度网络(如Resnet-50)的加速。看起来梯度仍然是为固定层计算的,但它们的值是乘以0.任何人都可以肯定地告诉我这是真的吗?

这是一个小网络的例子,我修复了第一层。

import numpy as np 
import keras 
import keras.applications.resnet50 

x = keras.layers.Input(shape=(5,)) 
y = keras.layers.Dense(5)(x) 

z = keras.layers.Dense(5)(y) 
model = keras.models.Model(x, z) 
for layer in model.layers[:2]: 
    layer.trainable = False 

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

X = np.random.rand(100, 5) 

model.fit(X, X, epochs=100) 

回答

5

如果你看一下源代码,你可以看到梯度仅就计算为_trainable_weights

但是,请注意,要计算任何坡度,您无论如何都需要在网络上执行完整的正向传递。然后,ouou需要反向传播回第一个可训练层的输入。因此,收益可能确实不如您预期的那么大(如果您将一半的权重设置为不可训练,您将获得2倍的加速)。

在你的情况下,不可训练的最后一个重量可以为你节省四分之一的矩阵乘法(2个前向,2个后向)。如果我测量有或没有可训练第一层代码的运行时间,我会看到1.4s vs 1.15s差异(Tensorflow CPU)或13 vs 11s(Theano CPU纯Python),这对我来说看起来很合理。根据我对(Theano pure-Python)的测量结果,如果比较一个较长的网络(例如,在您的示例中添加10个图层),使所有图层可训练且仅最后一个图层的差异变为10s vs 50s, 。

请注意,您通常不会期望性能增益超过50%,因为您实质上只保存了一部分反向传输。由于Theano的优化,这个重5倍的胜利很可能是唯一可能的,它将所有不可训练的致密层组合成单个矩阵乘法。的确,在Tensorflow上我只能看到1.5s和2.0s的差别。