TensorflowバックエンドでKerasを使用していますが、バックプロパゲーション中にレイヤーをスキップして、フォワードパスで実行できるかどうか知りたいです。だからここに私が意味するものがあります
Lambda (lambda x: a(x))
フォワードパスで申請a
したいのですがx
、バックプロパゲーションが行われるときに派生に含まれたくありません。
私は何も見つからなかった解決策を見つけようとしていました。誰かがここで私を助けてくれますか?
更新2
に加えてtf.py_func
、カスタム操作を追加する方法に関する公式ガイドがあります。
更新
何も再構築せずに純粋にPythonでグラデーションを使用してカスタム操作を作成する例については、この質問を参照してください。メソッドにはいくつかの制限があることに注意してください(のドキュメントを参照tf.py_func
)。
問題の正確な解決策ではありませんが、それでも一種の答えであり、コメントするには長すぎます。
これはKerasの問題ではなく、TensorFlowの問題です。各操作は、バックプロパゲーション中に使用される独自の勾配計算を定義します。私は本当にそのようなことをしたかったのですが、TensorFlowにopを自分で実装し(簡単なことではありません)、必要なグラデーションを定義する必要があります-「グラデーションなし」にすることはできないため、1または0(それ以外の場合はバックプロパゲーションを続行できません)。tf.NoGradient
TensorFlowには、opにゼロを伝播させる関数がありますが、TensorFlow自体の内部から使用することを意図しているとは思いません。
更新
さて、もう少しコンテキストがあります。TensorFlowグラフは、カーネルによって実装されるopsで構成されています。これは基本的に1対1のマッピングですが、たとえば、操作用のCPUとGPUカーネルが存在する場合があるため、差別化されます。TensorFlowでサポートされるopsのセットは通常静的です。つまり、新しいバージョンで変更される可能性がありますが、グラフのopsはProtobufシリアル化形式になるため、原則として独自のopsを追加することはできません。したがって、独自のopsを作成した場合そうすると、グラフを共有できなくなります。次に、OpsはマクロREGISTER_OP
(たとえばここを参照)を使用してC ++レベルで定義され、カーネルはREGISTER_KERNEL_BUILDER
(たとえばここを参照)を使用して定義されます。
さて、グラデーションはどこで機能しますか?面白いことに、opの勾配はC ++レベルで定義されていません。そこにある他のOPSの勾配を実装OPS(およびカーネル)は、(あなたが以前のファイルを見ればあなたがで終わる名前のOPS /カーネルを見つけることができますGrad
これらは明示的ではありません(これまで私が承知しているとされる))が、このレベルで「リンク」されています。opsとそのグラデーションの間の関連付けは、Pythonで定義されているようです。通常は、tf.RegisterGradient
または前述の方法で定義されtf.NoGradient
ます(たとえば、ここを参照してください。で始まるPythonモジュールgen_
は、C ++マクロを使用して自動生成されます)。これらの登録は、グラフの勾配を計算する方法についてバックプロパゲーションアルゴリズムに通知します。
それで、実際にこれを解決する方法は?さて、フォワードパスに必要な計算を実装する対応するカーネルを使用して、C ++で少なくとも1つのopを作成する必要があります。次に、使用する勾配計算を既存のTensorFlow ops(最も可能性が高い)で表現できる場合はtf.RegisterGradient
、Pythonを呼び出して、そこで「標準」のTensorFlowで計算を行う必要があります。これは非常に複雑ですが、良いニュースはそれが可能であり、例さえありますそのため(彼らはその中の勾配登録部分をちょっと忘れたと思いますが)!ご覧のとおり、このプロセスでは、新しいオペコードをライブラリにコンパイルし(Windowsで機能するかどうかはわかりません)、Pythonからロードします(明らかに、これには手動コンパイルの面倒なプロセスが含まれます)。TensorFlowのでBazel)。おそらくより現実的な例は、TensorFlow Foldにあります。これは、を呼び出すマクロを介してここで1つのカスタム操作を(1つの時点で)登録する構造化データ用のTensorFlowの拡張であり、Pythonではライブラリをロードしてそのグラデーションを登録しますここにREGISTER_OP
ここで定義されている独自の登録関数を使用して、tf.NotDifferentiable
(の別名tf.NoGradient
)を呼び出すだけです。
tldr:それはかなり難しいですが、それは可能であり、そこにはいくつかの例さえあります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加