2016-11-08 224 views
3

我想重置(随机)Keras(深度学习)模型中所有图层的权重。原因是我希望能够以不同的数据分割多次训练模型,而不必每次都进行(慢速)模型重新编译。重置Keras图层中的权重

通过this discussion的启发,我想下面的代码:

# Reset weights 
for layer in KModel.layers: 
    if hasattr(layer,'init'): 
     input_dim = layer.input_shape[1] 
     new_weights = layer.init((input_dim, layer.output_dim),name='{}_W'.format(layer.name)) 
     layer.trainable_weights[0].set_value(new_weights.get_value()) 

然而,它只是部分有效。

部分原因,因为我检查了一些layer.get_weights()值,它们似乎发生了变化。但是,当我重新开始培训时,成本值远低于首次运行时的初始成本值。这几乎就像我成功地重新设置了一些权重,但不是全部。

任何有关我出错的提示都会深表谢意。 Thx ..

回答

4

如果你编译模型之后,但训练它以前保存的初始权重:

model.load_weights('model.h5') 

model.save_weights('model.h5') 

,然后训练结束后,通过重新加载初始权“复位”的模式

这给你一个苹果模型来比较不同的数据集,应该比重新编译整个模型更快。

+2

我最终做了类似的事情。保存到磁盘和加载需要很多时间,所以我只是将权重保存在一个变量中:weights = model.get_weights() 在运行第一次训练之前,我得到了像这样的初始权重。然后,在每次后续培训之前,我重新加载初始权重并运行jkleint的shuffle方法,如我发布的链接中所述。似乎工作顺利.. – Tor

0

好的,所以看起来有人有同样的问题。解决问题的一个很好的解决方案(针对所有实际用途)已发布在此处:https://gist.github.com/jkleint/eb6dc49c861a1c21b612b568dd188668

+0

该解决方案实际上并未重新初始化权重,只是对权重矩阵中的元素进行置换。这只会在某些条件下发挥作用(例如,所有维度的价值分配都是相同的),并且应该在更不确定的情况下避免。 – ldavid

+0

注意:当使用训练开始之前获得的权重调用'shuffle_weights(weights = initial_weights)'时,我上面的评论是错误的。 – ldavid

1

尝试set_weights

例如:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
from __future__ import print_function 
import numpy as np 
np.random.seed(1234) 
from keras.layers import Input 
from keras.layers.convolutional import Convolution2D 
from keras.models import Model 

print("Building Model...") 
inp = Input(shape=(1,None,None)) 
x = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(inp) 
output = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(x) 
model_network = Model(input=inp, output=output) 

w = np.asarray([ 
    [[[ 
    [0,0,0], 
    [0,2,0], 
    [0,0,0] 
    ]]] 
    ]) 

for layer_i in range(len(model_network.layers)): 
    print (model_network.layers[layer_i]) 

for layer_i in range(1,len(model_network.layers)): 
    model_network.layers[layer_i].set_weights(w) 



input_mat = np.asarray([ 
    [[ 
    [1.,2.,3.,10.], 
    [4.,5.,6.,11.], 
    [7.,8.,9.,12.] 
    ]] 
    ]) 

print("Input:") 
print(input_mat) 
print("Output:") 
print(model_network.predict(input_mat)) 

w2 = np.asarray([ 
    [[[ 
    [0,0,0], 
    [0,3,0], 
    [0,0,0] 
    ]]] 
    ]) 


for layer_i in range(1,len(model_network.layers)): 
    model_network.layers[layer_i].set_weights(w2) 

print("Output:") 
print(model_network.predict(input_mat)) 

构建有发言权的模型中,两个卷积层

print("Building Model...") 
inp = Input(shape=(1,None,None)) 
x = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(inp) 
output = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(x) 
model_network = Model(input=inp, output=output) 

然后定义权(我用一个简单的W,但你可以使用np.random .uniform或类似的东西,如果你想的话)

w = np.asarray([ 
    [[[ 
    [0,0,0], 
    [0,2,0], 
    [0,0,0] 
    ]]] 
    ]) 

看一看模型中的层是什么

for layer_i in range(len(model_network.layers)): 
    print (model_network.layers[layer_i]) 

设置每个自重每卷积层(你会看到第一层实际上是输入,你不想改变这种状况,这就是为什么范围为1不是从零开始)。

for layer_i in range(1,len(model_network.layers)): 
    model_network.layers[layer_i].set_weights(w) 

生成测试一些输入,并从你的模型预测输出

input_mat = np.asarray([ 
    [[ 
    [1.,2.,3.,10.], 
    [4.,5.,6.,11.], 
    [7.,8.,9.,12.] 
    ]] 
    ]) 

print("Output:") 
print(model_network.predict(input_mat)) 

,如果你愿意,你可以再次更改和输出再次检查:

w2 = np.asarray([ 
    [[[ 
    [0,0,0], 
    [0,3,0], 
    [0,0,0] 
    ]]] 
    ]) 

for layer_i in range(1,len(model_network.layers)): 
    model_network.layers[layer_i].set_weights(w2) 

print("Output:") 
print(model_network.predict(input_mat)) 

样品输出:

Using Theano backend. 
Building Model... 
<keras.engine.topology.InputLayer object at 0x7fc0c619fd50> 
<keras.layers.convolutional.Convolution2D object at 0x7fc0c6166250> 
<keras.layers.convolutional.Convolution2D object at 0x7fc0c6150a10> 
Weights after change: 
[array([[[[ 0., 0., 0.], 
     [ 0., 2., 0.], 
     [ 0., 0., 0.]]]], dtype=float32)] 
Input: 
[[[[ 1. 2. 3. 10.] 
    [ 4. 5. 6. 11.] 
    [ 7. 8. 9. 12.]]]] 
Output: 
[[[[ 4. 8. 12. 40.] 
    [ 16. 20. 24. 44.] 
    [ 28. 32. 36. 48.]]]] 
Output: 
[[[[ 9. 18. 27. 90.] 
    [ 36. 45. 54. 99.] 
    [ 63. 72. 81. 108.]]]] 

从您在.layers中的视图中,您可以看到第一层是输入,其他层是卷积层。

相关问题