自分のデータセットで事前トレーニングされたインセプションモデルを使用したいと思います。インセプションモデル自体の変数も微調整したいと思っています。TensorFlowのインセプションモデルを微調整する
私は、次のリンクからTensorFlowの事前訓練を受けたインセプションモデルをダウンロードした次のように私はインセプションモデルをロード
http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
:
APIのgraph = tf.Graph()
with graph.as_default():
with tf.gfile.FastGFile('classify_image_graph_def.pb', 'rb') as file:
graph_def = tf.GraphDef()
graph_def.ParseFromString(file.read())
tf.import_graph_def(graph_def, name='')
(サイドノート:これらの6つのネストされ複雑な行の代わりにgraph = tf.load_graph('inception.pb')
と書くだけでいいです。)
私はインセプションモデルのソフトマックス・分級前の最後の層のためのテンソルへの参照を取得します:
last_layer = graph.get_tensor_by_name('pool_3:0')
今、私は新しいソフトマックス・分類器を訓練することができるようにグラフに新しいソフトマックス・分類器を追加したいですInceptionモデルの変数の一部またはすべてを調整します。これは、新しいsoftmax分類器だけが私自身のデータセットで訓練されている学習を転送するのではなく、微調整であると理解しています。
私はその後(y_true
はプレースホルダ変数であることに注意してください)新しいソフトマックス・分類器を追加するPrettyTensorを使用します。
with pt.defaults_scope(activation_fn=tf.nn.relu):
y_pred, loss = pt.wrap(last_layer).\
flatten().\
softmax_classifier(class_count=10, labels=y_true)
しかし、これは最後の部分は読み長いエラー・メッセージが得られます。
ValueError: Tensor("flatten/reshape/Const:0", shape=(2,), dtype=int32) must be from the same graph as Tensor("pool_3:0", shape=(1, 1, 1, 2048), dtype=float32).
を
私はこのように2つのグラフを組み合わせることはできません。
次のように私も(インセプションモデルの最後の層が2048個の機能を持っている注意してください)reshape()
代わりのflatten()
を使用して試してみました:
with pt.defaults_scope(activation_fn=tf.nn.relu):
y_pred, loss = pt.wrap(last_layer).\
reshape([-1, 2048]).\
softmax_classifier(class_count=10, labels=y_true)
しかし、これは、ほぼ同じエラーを与える:
ValueError: Tensor("reshape/Const:0", shape=(2,), dtype=int32) must be from the same graph as Tensor("pool_3:0", shape=(1, 1, 1, 2048), dtype=float32).
私はまた、graph.as_default()
のようにそれをラップしようとしました:
with graph.as_default():
with pt.defaults_scope(activation_fn=tf.nn.relu):
y_pred, loss = pt.wrap(last_layer).\
reshape([-1, 2048]).\
softmax_classifier(class_count=10, labels=y_true)
しかし、これは同様のエラーを与える:
ValueError: Tensor("ArgMax_1:0", shape=(?,), dtype=int64) must be from the same graph as Tensor("cross_entropy/ArgMax:0", shape=(1,), dtype=int64).
私はインセプションモデルの微調整をどのように行うのでしょうか?私は新しいsoftmax-classifierを追加したいと思います。そして、Inceptionモデル自体の変数の一部またはすべてを微調整したいと思います。
ありがとうございます!
EDIT:
私は問題の部分的な解決策を持っています。
エラーメッセージは、with graph.as_default():
ブロック内にすべてのコードを入れなかったためです。ブロック内のすべてのコードを入れてエラーメッセージを修正し、上で説明したようにPrettyTensorを使ってInceptionモデルに新しいsoftmax-layerを追加できるようになりました。
しかし、インセプションモデルは明らかに、すべての変数が保存される前に定数に変換されたことを意味する「固定」グラフです。
私の質問は今、Inceptionモデルのグラフを何とか「フリーズ」することができるかどうかです。そのグラフの変数の一部または全部を引き続き習得できますか?どうすればいい?
代わりに、新しいMetaGraph機能を使用する必要がありますか?私はインセプションモデルの事前訓練を受けたメタグラフをダウンロードすることができ
https://www.tensorflow.org/versions/r0.11/how_tos/meta_graph/index.html
?
はい。望ましいレイヤーの出力をinception_model.inference()関数から戻し、必要なレイヤーを追加してトレーニングを続けることができます。必要なのはチェックポイントの復元だけです。トレーニングの後、ネットワークの新しい変更された重みと挿入されたレイヤーの新しい重みでチェックポイントを保存することができます。 – chrisrn
私がしたいのは、いくつかの初期レイヤーをフリーズし、上層レイヤーを微調整することです。それは可能ですか? –
はい。解決したい問題は、グラデーションと関係しています。オプティマイザを定義するときは、optimizer.compute_gradients、optimizer.apply_gradientsの順になります。最初のコマンドはリストを返します。このリストを印刷して、fine_tuneするレイヤの名前を確認することができます。次に、これらのレイヤーのグラデーションのみで新しいリストを作成し、このリストを引数として送信する2番目のコマンドを実行できます。 – chrisrn