ニューロンの重みを前のエポックの重みに再割り当てしようとしています。これを行うために、古い重みを保存しようとしていますが、行列のコピーを作成するのに問題があります。
カスタムレイヤー内で熱心なテンソルをコピーする方法がわかりません。tf.identityとコピーライブラリを使用してみましたが、正しく実装しなかった可能性は確かにありますが、どちらもエラーが発生しました。何かアドバイスをいただければ幸いです。以下のエラーの1つを添付しました。これは、テンソルフロー2を使用しているため、熱心な実行がオンになっていると機能するはずであり、デフォルトで熱心な実行がオンになっているはずです。
class RevertWeightMatrixDenseLayer(keras.layers.Layer):
def __init__(self, units, prob, **kwargs):
super(RevertWeightMatrixDenseLayer, self).__init__(**kwargs)
self.units = units
self.prob = prob
def build(self, input_shape):
self.w = self.add_weight(
shape=(input_shape[-1], self.units),
initializer="random_normal",
trainable=True,
)
self.b = self.add_weight(
shape=(self.units,), initializer="random_normal", trainable=True
)
self.last_weight_1 = self.w
self.last_weight_2 = self.w
def call(self, inputs, training=False):
current_weights = self.w
if training:
if self.prob > random.random():
self.w.assign(self.last_weight_2) # Assign preserves tf.Variable
#deep copy all the weights here here before assignement
self.last_weight_2 = self.last_weight_1
self.last_weight_1 = current_weights
else:
pass #could think about multiplying all weights by a constant here
return tf.nn.relu(tf.matmul(inputs, self.w) + self.b)
model = make_base_model() #sets up a sequential model with some conv layers
model.add(ResetWeightMatrixDenseLayer(units=dense_units, prob=0.1)) #Custom layer
model.add(ResetWeightMatrixDenseLayer(units=dense_units, prob=0.1)) #Custom layer
model.add(layers.Dense(classes, activation='softmax'))
model.compile(loss = 'CategoricalCrossentropy',
optimizer = 'adam',
metrics=['accuracy'])
history = model.fit(train_dataset, validation_data=validation_dataset, epochs=epochs)
plot(history)
コメントした場所でディープコピーを実行しようとすると、次のエラーが発生します* NotImplementedError:ディープコピー()は、熱心な実行が有効になっている場合にのみ使用できます。*
レイヤーに状態を保持したい:それがまさにそのtf.Variable
目的です。(ガイド:変数の概要を参照してください)
をlast_weights
訓練不可能なものとして設定し、tf.Variable
assignを使用して値をコピーします。
class RevertWeightMatrixDenseLayer(keras.layers.Layer):
def __init__(self, units, prob, **kwargs):
super(RevertWeightMatrixDenseLayer, self).__init__(**kwargs)
self.units = units
self.prob = prob
def build(self, input_shape):
self.w = self.add_weight(
shape=(input_shape[-1], self.units),
initializer="random_normal",
trainable=True,
)
self.b = self.add_weight(
shape=(self.units,), initializer="random_normal", trainable=True
)
self.last_weight_1 = tf.Variable(self.w, trainable=False)
self.last_weight_2 = tf.Variable(self.w, trainable=False)
# we need an extra Variable to store the original value of w
# when shuffling around
self.tmp = tf.Variable(self.w, trainable=False)
def call(self, inputs, training=False):
self.tmp.assign(self.w)
if training:
if self.prob > random.random():
self.w.assign(self.last_weight_2) # Assign preserves tf.Variable
self.last_weight_2.assign(self.last_weight_1)
self.last_weight_1.assign(self.tmp)
else:
pass #could think about multiplying all weights by a constant here
return tf.nn.relu(tf.matmul(inputs, self.w) + self.b)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加