web-dev-qa-db-ja.com

Keras 2.x-レイヤーの重みを取得

Windows 10、Python 3.5、およびtensorflow 1.1.0を使用しています。次のスクリプトがあります。

import tensorflow as tf
import tensorflow.contrib.keras.api.keras.backend as K
from tensorflow.contrib.keras.api.keras.layers import Dense

tf.reset_default_graph()
init = tf.global_variables_initializer()
sess =  tf.Session()
K.set_session(sess) # Keras will use this sesssion to initialize all variables

input_x = tf.placeholder(tf.float32, [None, 10], name='input_x')    
dense1 = Dense(10, activation='relu')(input_x)

sess.run(init)

dense1.get_weights()

エラーが表示されます:AttributeError: 'Tensor' object has no attribute 'weights'

何が間違っているのですか?dense1の重みを取得するにはどうすればよいですか? this および this SO post)を見てきましたが、それでも動作させることはできません。

17
Toke Faurby

あなたが書く場合:

dense1 = Dense(10, activation='relu')(input_x)

_dense1_はレイヤーではなく、レイヤーの出力です。レイヤーはDense(10, activation='relu')です

だからあなたが意味したようです:

_dense1 = Dense(10, activation='relu')
y = dense1(input_x)
_

完全なスニペットは次のとおりです。

_import tensorflow as tf
from tensorflow.contrib.keras import layers

input_x = tf.placeholder(tf.float32, [None, 10], name='input_x')    
dense1 = layers.Dense(10, activation='relu')
y = dense1(input_x)

weights = dense1.get_weights()
_
17
Francois

すべてのレイヤーの重みとバイアスを取得する場合は、次を使用できます。

for layer in model.layers: print(layer.get_config(), layer.get_weights())

これにより、関連するすべての情報が出力されます。

重みをnumpy配列として直接返す場合、次を使用できます。

first_layer_weights = model.layers[0].get_weights()[0]
first_layer_biases  = model.layers[0].get_weights()[1]
second_layer_weights = model.layers[1].get_weights()[0]
second_layer_biases  = model.layers[1].get_weights()[1]

等.

38
Onno Kampman

レイヤーの重みとバイアスが時間とともにどのように変化するかを確認したい場合は、各トレーニングエポックで値を記録するコールバックを追加できます。

たとえば、このようなモデルを使用すると、

import numpy as np
model = Sequential([Dense(16, input_shape=(train_inp_s.shape[1:])), Dense(12), Dense(6), Dense(1)])

フィッティング中にコールバック** kwargを追加します。

gw = GetWeights()
model.fit(X, y, validation_split=0.15, epochs=10, batch_size=100, callbacks=[gw])

コールバックは

class GetWeights(Callback):
    # Keras callback which collects values of weights and biases at each Epoch
    def __init__(self):
        super(GetWeights, self).__init__()
        self.weight_dict = {}

    def on_Epoch_end(self, Epoch, logs=None):
        # this function runs at the end of each Epoch

        # loop over each layer and get weights and biases
        for layer_i in range(len(self.model.layers)):
            w = self.model.layers[layer_i].get_weights()[0]
            b = self.model.layers[layer_i].get_weights()[1]
            print('Layer %s has weights of shape %s and biases of shape %s' %(
                layer_i, np.shape(w), np.shape(b)))

            # save all weights and biases inside a dictionary
            if Epoch == 0:
                # create array to hold weights and biases
                self.weight_dict['w_'+str(layer_i+1)] = w
                self.weight_dict['b_'+str(layer_i+1)] = b
            else:
                # append new weights to previously-created weights array
                self.weight_dict['w_'+str(layer_i+1)] = np.dstack(
                    (self.weight_dict['w_'+str(layer_i+1)], w))
                # append new weights to previously-created weights array
                self.weight_dict['b_'+str(layer_i+1)] = np.dstack(
                    (self.weight_dict['b_'+str(layer_i+1)], b))

このコールバックは、レイヤー番号でラベル付けされたすべてのレイヤーの重みとバイアスでディクショナリを構築します。そのため、モデルのトレーニング中にそれらが時間とともにどのように変化するかを確認できます。各重みとバイアス配列の形状は、モデルレイヤーの形状に依存することに気付くでしょう。モデル内のレイヤーごとに1つの重み配列と1つのバイアス配列が保存されます。 3番目の軸(深さ)は、時間の経過に伴う進化を示しています。

ここでは、10個のエポックと、16、12、6、および1個のニューロンの層を持つモデルを使用しました。

for key in gw.weight_dict:
    print(str(key) + ' shape: %s' %str(np.shape(gw.weight_dict[key])))

w_1 shape: (5, 16, 10)
b_1 shape: (1, 16, 10)
w_2 shape: (16, 12, 10)
b_2 shape: (1, 12, 10)
w_3 shape: (12, 6, 10)
b_3 shape: (1, 6, 10)
w_4 shape: (6, 1, 10)
b_4 shape: (1, 1, 10)
1
Eric Muckley