Python 在 Keras 层中重置权重

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40496069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:36:14  来源:igfitidea点击:

Reset weights in Keras layer

pythonkeraskeras-layer

提问by Tor

I'd like to reset (randomize) the weights of all layers in my Keras (deep learning) model. The reason is that I want to be able to train the model several times with different data splits without having to do the (slow) model recompilation every time.

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

Inspired by this discussion, I'm trying the following code:

受此讨论的启发,我正在尝试以下代码:

# 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())

However, it only partly works.

但是,它仅部分起作用。

Partly, becuase I've inspected some layer.get_weights() values, and they seem to change. But when I restart the training, the cost values are much lower than the initial cost values on the first run. It's almost like I've succeeded resetting some of the weights, but not all of them.

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

Any tips on where I'm going wrong would be deeply appreciated. Thx..

任何关于我哪里出错的提示将不胜感激。谢谢..

回答by ezchx

Save the initial weights right after compiling the model but before training it:

在编译模型之后但在训练之前保存初始权重:

model.save_weights('model.h5')

and then after training, "reset" the model by reloading the initial weights:

然后在训练后,通过重新加载初始权重来“重置”模型:

model.load_weights('model.h5')

This gives you an apples to apples model to compare different data sets and should be quicker than recompiling the entire model.

这为您提供了一个苹果对苹果模型来比较不同的数据集,并且应该比重新编译整个模型更快。

回答by Mendi Barel

Reset all layers by checking for initializers:

通过检查初始值设定项来重置所有层:

def reset_weights(model):
    import keras.backend as K
    session = K.get_session()
    for layer in model.layers: 
        if hasattr(layer, 'kernel_initializer'): 
            layer.kernel.initializer.run(session=session)
        if hasattr(layer, 'bias_initializer'):
            layer.bias.initializer.run(session=session)     

Update: kernel_initializer is kernel.initializer now.

更新: kernel_initializer 现在是 kernel.initializer。

回答by BallpointBen

If you want to truly re-randomize the weights, and not merely restore the initial weights, you can do the following. The code is slightly different depending on whether you're using TensorFlow or Theano.

如果您想真正重新随机化权重,而不仅仅是恢复初始权重,您可以执行以下操作。根据您使用的是 TensorFlow 还是 Theano,代码略有不同。

from keras.initializers import glorot_uniform  # Or your initializer of choice
import keras.backend as K

initial_weights = model.get_weights()

backend_name = K.backend()
if backend_name == 'tensorflow': 
    k_eval = lambda placeholder: placeholder.eval(session=K.get_session())
elif backend_name == 'theano': 
    k_eval = lambda placeholder: placeholder.eval()
else: 
    raise ValueError("Unsupported backend")

new_weights = [k_eval(glorot_uniform()(w.shape)) for w in initial_weights]

model.set_weights(new_weights)

回答by Ashot Matevosyan

K.get_session().close()
K.set_session(tf.Session())
K.get_session().run(tf.global_variables_initializer())

回答by maz

Try set_weights.

试试set_weights

for example:

例如:

#!/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))

build a model with say, two convolutional layers

用两个卷积层构建模型

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)

then define your weights (i'm using a simple w, but you could use np.random.uniform or anything like that if you want)

然后定义你的权重(我使用的是一个简单的 w,但如果你愿意,你可以使用 np.random.uniform 或类似的东西)

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

Take a peek at what are the layers inside a model

看一看模型内部的层是什么

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

Set each weight for each convolutional layer (you'll see that the first layer is actually input and you don't want to change that, that's why the range starts from 1 not zero).

为每个卷积层设置每个权重(您会看到第一层实际上是输入并且您不想更改它,这就是范围从 1 开始而不是零的原因)。

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

Generate some input for your test and predict the output from your model

为您的测试生成一些输入并预测模型的输出

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

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

You could change it again if you want and check again for the output:

如果需要,您可以再次更改它并再次检查输出:

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))

Sample output:

示例输出:

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.]]]]

From your peek at .layers you can see that the first layer is input and the others your convolutional layers.

从您对 .layers 的一瞥中,您可以看到第一层是输入层,而其他层是您的卷积层。

回答by Andrew - OpenGeoCode

To "random" re-initialize weights of a compiled untrained model in TF 2.0 (tf.keras):

要在 TF 2.0 (tf.keras) 中“随机”重新初始化已编译的未训练模型的权重:

weights = [glorot_uniform(seed=random.randint(0, 1000))(w.shape) if w.ndim > 1 else w for w in model.get_weights()]

Note the "if wdim > 1 else w". You don't want to re-initialize the biases (they stay 0 or 1).

注意“if wdim > 1 else w”。您不想重新初始化偏差(它们保持 0 或 1)。