我用Keras做了一些实验,我只是监视了一个简单的mlp模型的重量更新:
# model contains one input layer in the format of dense,
# one hidden layer and one output layer.
model=mlp()
weight_origin=model.layers[0].get_weights()[0]
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(.....) # with adam optimizer
weight_updated=model.layers[0].get_weights()[0]
print weight_origin-weight_updated
对于第一个稠密层,我得到了一个零矩阵。我以为训练不会改变体重。但是,其他层中的权重会更改。所以我很困惑,为什么第一层是不变的? 我检查了源代码,但仍然没有得到答案,然后我尝试监视:
model.layers[0].get_weights()[1] # get_weight() returns a list of weights
这次,体重确实变了。所以我想知道哪种体重才是训练中起作用的“真正”体重?为什么重量表中有两个元素?
mlp()
的定义:
def mlp():
model=Sequential()
model.add(Dense(500, input_dim=784))
model.add(Dense(503,init='normal',activation='relu'))
model.add(Dense(503,init='normal',activation='relu'))
model.add(Dense(10, activation='softmax'))
return model
有一种方法可以准确地看到所有权重和偏差的值随时间的变化。您可以使用Keras回调方法,该方法可用于记录每个训练时期的权重值。例如,使用这样的模型
安装期间添加回调**kwarg:
其中回调由
这个回调函数构建了一个包含所有层权重和偏移量的字典,这些层权重和偏移量由层编号标记,因此您可以看到它们随着时间的推移是如何随着模型的训练而变化的。您会注意到,每个权重和偏移数组的形状取决于模型层的形状。为模型中的每个层保存一个权重数组和一个偏移数组。第三轴(深度)显示了它们随时间的演变。
在这里,我们使用了10个时代和一个由16、12、6和1个神经元组成的模型:
关于
layer.get_weights()
的问题:我对这个问题进行了一些测试并检查了源代码。我发现
Dense
层是Layer
的一个子类,它的权重是python的一种类型list
有两个元素,层的权重存储在layer.get_weights()[0]
,而bias
存储在layer.get_weights()[1]
。有一点需要注意,在定义层时,
bias
可以被禁用:model.add(Dense(503,init='normal',activation='relu',
bias=False
))
。在这种情况下,列表layer.get_weights()
只有一个元素。如果在定义后将bias
属性设置为False
,则仍会有一个用于bias
的元素,并且在拟合模型后会对其进行更新。对于不更新的问题:
我建立了一个只有一个致密层的序贯模型:
def mlp_2(): model=Sequential() model.add(Dense(10, input_dim=784, activation='softmax', bias =False)) return model
然后我用同样的方法来编译和安装它。这就是我得到的:
它似乎仍然没有更新的重量,但是,我们可以告诉重量是明确的变化。因为精确度在提高。我认为唯一的解释是第一个
dense
层(您定义的input_dim
)的更新太小,Keras无法打印出来。我没有检查更精确的重量值,如果有人能确认的话会更好。这是一个有效的例子。
相关问题 更多 >
编程相关推荐