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'
すべてのレイヤーの重みとバイアスを取得したい場合は、単純に次のようにします。
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]
などがあります。
と書けば。
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()
もし、レイヤーの重みとバイアスが時間とともにどのように変化するかを見たい場合は、各トレーニングエポックの値を記録するコールバックを追加することができます。
例えばこんなモデルを使って。
numpyを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])
ここで、コールバックは次のように定義されます。
クラス GetWeights(Callback)。
エポック毎に重みとバイアスの値を収集する # Keras コールバック
def __init__(self):
super(GetWeights, self).__init__()
self.weight_dict = {}とする。
def on_epoch_end(self, epoch, logs=None):
# この関数は各エポックの終了時に実行される
# 各レイヤーをループし、重みとバイアスを取得する
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)))
# すべての重みとバイアスを辞書に保存する
if epoch == 0:
# 重みとバイアスを保持するための配列を作成する
self.weight_dict['w_'+str(layer_i+1)] = w
self.weight_dict['b_'+str(layer_i+1)] = b
さもないと
# 以前に作成した重みの配列に新しい重みを追加する
self.weight_dict['w_'+str(layer_i+1)] = np.dstack()です。
(self.weight_dict['w_'+str(layer_i+1)], w))
# 以前に作成した重みの配列に新しい重みを追加する
self.weight_dict['b_'+str(layer_i+1)] = np.dstack()です。
(self.weight_dict['b_'+str(layer_i+1)], b))
このコールバックは、すべてのレイヤーの重みとバイアスをレイヤー番号でラベル付けした辞書を構築するので、モデルが学習されるにつれてそれらがどのように変化するかを見ることができます。各重みとバイアスの配列の形状は、モデルのレイヤーの形状に依存することに気づくでしょう。重みの配列とバイアスの配列は、モデルの各レイヤーに1つずつ保存されます。3つ目の軸(深さ)は、その経時変化を示しています。
ここでは、10エポック、16、12、6、1ニューロンのレイヤーを持つモデルを使用しました。
gw.weight_dictのkeyに対して。
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形状。(16, 12, 10)
b_2形状。(1, 12, 10)
w_3形状。(12, 6, 10)
b_3形状。(1, 6, 10)
w_4形状。(6, 1, 10)
b_4形状。(1, 1, 10)