web-dev-qa-db-fra.com

Réinitialiser les poids dans la couche Keras

J'aimerais réinitialiser (aléatoirement) les poids de toutes les couches de mon modèle Keras (apprentissage en profondeur). La raison en est que je veux pouvoir entraîner le modèle plusieurs fois avec des fractionnements de données différents sans avoir à effectuer la recompilation (lente) du modèle à chaque fois.

Inspiré par cette discussion , j'essaie le code suivant:

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

Cependant, cela ne fonctionne que partiellement.

En partie, car j'ai inspecté certaines valeurs de layer.get_weights (), et elles semblent changer. Mais lorsque je reprends la formation, les valeurs de coût sont bien inférieures aux valeurs de coût initiales lors de la première exécution. C'est presque comme si j'avais réussi à réinitialiser certains des poids, mais pas tous.

Tous les conseils sur mes erreurs seraient grandement appréciés. THX..

15
Tor

Enregistrez les poids initiaux juste après la compilation du modèle mais avant de l’entraîner:

model.save_weights('model.h5')

puis, après l'entraînement, "réinitialisez" le modèle en rechargeant les poids initiaux:

model.load_weights('model.h5')

Cela vous donne un modèle de pommes à pommes pour comparer différents ensembles de données et devrait être plus rapide que la recompilation de l'ensemble du modèle.

15
ezchx

Si vous souhaitez vraiment re-randomiser les poids et ne pas simplement restaurer les poids initiaux, vous pouvez procéder comme suit. Le code est légèrement différent selon que vous utilisez TensorFlow ou 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)
11
BallpointBen

Réinitialisez toutes les couches en recherchant les initialiseurs:

def reset_weights(model):
    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)     
6
Mendi Barel
K.get_session().close()
K.set_session(tf.Session())
K.get_session().run(tf.global_variables_initializer())
2
Ashot Matevosyan

Essayez set_weights .

par exemple:

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

construire un modèle avec, disons, deux couches convolutives

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)

puis définissez vos poids (j'utilise un simple w, mais vous pouvez utiliser np.random.uniform ou quelque chose comme ça si vous voulez)

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

Jetez un coup d'oeil à ce que sont les couches à l'intérieur d'un modèle

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

Définissez chaque poids pour chaque couche convolutionnelle (vous verrez que la première couche est réellement entrée et que vous ne voulez pas changer cela, c'est pourquoi la plage commence entre 1 et zéro).

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

Générez des entrées pour votre test et prédisez les résultats de votre modèle

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

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

Vous pouvez le changer à nouveau si vous le souhaitez et vérifier à nouveau le résultat:

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

Exemple de sortie:

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

À partir de votre aperçu des couches, vous pouvez voir que la première couche est entrée et les autres vos couches convolutives.

1
maz