Tensorflowでバッチノルムを使用してモデルをトレーニングしました。モデルを保存して、さらに使用できるように復元したいと思います。バッチノルムはによって行われます
def batch_norm(input, phase):
return tf.layers.batch_normalization(input, training=phase)
ここで、フェーズはトレーニング中はTrue
、テスト中はFalse
です。
単に電話するようです
saver = tf.train.Saver()
saver.save(sess, savedir + "ckpt")
モデルを復元すると、最初は正常に復元されたと表示されるため、うまく機能しません。また、Attempting to use uninitialized value batch_normalization_585/beta
グラフで1つのノードを実行した場合。これは、モデルを適切に保存しないこと、または私が見逃した他の何かに関連していますか?
また、「初期化されていない値batch_normalization_585/betaを使用しようとしています」というエラーが発生しました。これは、次のように空の角かっこでセーバーを宣言することによって発生します。
saver = tf.train.Saver()
セーバーは、バッチ正規化の移動平均を含まないtf.trainable_variables()に含まれる変数を保存します。この変数を保存されたckptに含めるには、次のことを行う必要があります。
saver = tf.train.Saver(tf.global_variables())
これはすべての変数を保存するので、非常にメモリを消費します。または、移動する平均または分散を持つ変数を識別し、次のように宣言して保存する必要があります。
saver = tf.train.Saver(tf.trainable_variables() + list_of_extra_variables)
これを説明する必要があるかどうかはわかりませんが、念のため(および他の潜在的な視聴者のために)。
TensorFlowで操作を作成するたびに、新しいノードがグラフに追加されます。グラフ内の2つのノードに同じ名前を付けることはできません。作成する任意のノードの名前を定義できますが、名前を指定しない場合、TensorFlowは決定論的な方法でノードを選択します(つまり、ランダムではなく、常に同じシーケンスで)。 2つの数値を加算すると、おそらくAdd
になりますが、別の加算を行うと、2つのノードに同じ名前を付けることはできないため、Add_2
のようになります。グラフにノードが作成されると、その名前は変更できません。多くの関数は、いくつかのサブノードを順番に作成します。たとえば、tf.layers.batch_normalization
はいくつかの内部変数beta
とgamma
を作成します。
保存と復元は次のように機能します。
save
を呼び出して、変数の値をファイルに保存します。restore
を呼び出して、変数の値を取得します。これが機能するためには、最初と2番目のグラフの変数の名前がまったく同じである必要があります。
あなたの例では、TensorFlowは変数batch_normalization_585/beta
について文句を言っています。同じグラフでtf.layers.batch_normalization
を600回近く呼び出したようです。そのため、多くのbeta
変数がぶら下がっています。実際にこれだけの数が必要かどうかは疑わしいので、APIを試しているだけで、最終的にはその数のコピーが作成されたと思います。
これが機能するはずのドラフトです:
import tensorflow as tf
def make_model():
input = tf.placeholder(...)
phase = tf.placeholder(...)
input_norm = tf.layers.batch_normalization(input, training=phase))
# Do some operations with input_norm
output = ...
saver = tf.train.Saver()
return input, output, phase, saver
# We work with one graph first
g1 = tf.Graph()
with g1.as_default():
input, output, phase, saver = make_model()
with tf.Session() as sess:
# Do your training or whatever...
saver.save(sess, savedir + "ckpt")
# We work with a second different graph now
g2 = tf.Graph()
with g2.as_default():
input, output, phase, saver = make_model()
with tf.Session() as sess:
saver.restore(sess, savedir + "ckpt")
# Continue using your model...
繰り返しますが、典型的なケースは、2つのグラフを並べるのではなく、1つのグラフを作成し、後で別のPythonセッションで再作成しますが、最終的には両方とも同じです。重要な部分は、どちらの場合もモデルが同じ方法で(したがって、同じノード名で)作成されることです。