TF 1.xでは、カスタム変数を使用してレイヤーを構築することが可能でした。次に例を示します。
import numpy as np
import tensorflow as tf
def make_custom_getter(custom_variables):
def custom_getter(getter, name, **kwargs):
if name in custom_variables:
variable = custom_variables[name]
else:
variable = getter(name, **kwargs)
return variable
return custom_getter
# Make a custom getter for the dense layer variables.
# Note: custom variables can result from arbitrary computation;
# for the sake of this example, we make them just constant tensors.
custom_variables = {
"model/dense/kernel": tf.constant(
np.random.Rand(784, 64), name="custom_kernel", dtype=tf.float32),
"model/dense/bias": tf.constant(
np.random.Rand(64), name="custom_bias", dtype=tf.float32),
}
custom_getter = make_custom_getter(custom_variables)
# Compute hiddens using a dense layer with custom variables.
x = tf.random.normal(shape=(1, 784), name="inputs")
with tf.variable_scope("model", custom_getter=custom_getter):
Layer = tf.layers.Dense(64)
hiddens = Layer(x)
print(Layer.variables)
構築された稠密層の出力される変数は、custom_variables
辞書で指定したカスタムテンソルになります。
[<tf.Tensor 'custom_kernel:0' shape=(784, 64) dtype=float32>, <tf.Tensor 'custom_bias:0' shape=(64,) dtype=float32>]
これにより、custom_variables
で提供されたテンソルを重みとして直接使用するレイヤー/モデルを作成できるため、custom_variables
が依存する可能性のあるすべてのテンソルに関してレイヤー/モデルの出力をさらに区別できます(特に modulating sub-nets 、 parameter generation 、 meta-learning などに機能を実装するのに役立ちます)。
変数スコープを使用すると、スコープ内のすべてのグラフ作成をカスタムゲッターにネストし、パラメーターとして提供されたテンソルの上にモデルを作成することが簡単になります。セッションと変数のスコープはTF 2.0では推奨されなくなったため(そしてその低レベルのものがすべてtf.compat.v1
に移動されました)、ベストプラクティスKerasとTF 2.0を使用して上記を実装するには?
(関連 GitHubの問題 )
あなたが持っているとすると:
_kernel = createTheKernelVarBasedOnWhatYouWant() #shape (784, 64)
bias = createTheBiasVarBasedOnWhatYouWant() #shape (64,)
_
Dense
からコードをコピーする簡単な関数を作成します。
_def custom_dense(x):
inputs, kernel, bias = x
outputs = K.dot(inputs, kernel)
outputs = K.bias_add(outputs, bias, data_format='channels_last')
return outputs
_
Lambda
レイヤーで関数を使用します。
_layer = Lambda(custom_dense)
hiddens = layer([x, kernel, bias])
_
警告:
kernel
およびbias
は、Kerasレイヤーから生成するか、kernel = Input(tensor=the_kernel_var)
およびbias = Input(tensor=bias_var)
から生成する必要があります
上記の警告が適切でない場合は、次のようにkernel
およびbias
"from outside"をいつでも使用できます。
_def custom_dense(inputs):
outputs = K.dot(inputs, kernel) #where kernel is not part of the arguments anymore
outputs = K.bias_add(outputs, bias, data_format='channels_last')
return outputs
layer = Lambda(custom_dense)
hiddens = layer(x)
_
この最後のオプションでは、モデルの保存/読み込みが少し複雑になります。
おそらく、Keras Denseレイヤーを使用し、標準的な方法で重みを設定する必要があります。
_layer = tf.keras.layers.Dense(64, name='the_layer')
layer.set_weights([np.random.Rand(784, 64), np.random.Rand(64)])
_
これらの重みをトレーニングできないようにする必要がある場合は、設定したケラスモデルをコンパイルする前に:
_model.get_layer('the_layer').trainable=False
_
テンソルとして変数に直接アクセスする場合は、次のとおりです。
_kernel = layer.kernel
bias = layer.bias
_
他にもたくさんのオプションがありますが、それはあなたの正確な意図に依存しますが、質問では明確ではありません。