私は多くのブログやフォーラムをレビューしましたが、一般的にフリーズパラメータには2つのステップが含まれています。
- パラメータの属性をFalseに設定します。つまり、requires_grad = Falseです。
- オプティマイザが定義されると、勾配を更新しないパラメータが除外されます。これは一般的に当てはまります。
optimizer.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-3)
上記の詳細には立ち入りませんが、Baiduのほとんどはこのようなものです。
最初に私の仕事について話させてください:
エンコーダーとデコーダーで構成されるモデルがあります。デコーダーのパラメーターは事前トレーニング中に固定され、エンコーダーのパラメーターのみがトレーニングされます。次に、微調整中にすべてのパラメーターをトレーニングします。
問題:
上記の方法では、モデルをリロードすると、長さが一致しないエラーが報告されます。
ValueError:ロードされた状態のdictに、オプティマイザーのグループのサイズと一致しないパラメーターグループが含まれています
長い間デバッグしたところ、ロードしたモデルはエンコーダー部分のパラメーターしか保存されていませんでしたが、新しいモデルはエンコーダーとデコーダーのパラメーターです。したがって、事前にトレーニングされたパラメータを新しいモデルにロードすることはできません。
解決:
オプティマイザでパラメータをフィルタリングせずに、パラメータの属性をTrue / Falseに設定するだけで、長さが一定になります。
さらに、事前トレーニングプロセス中の固定パラメーターは実際には更新されず、すべてのパラメーターは微調整中に更新されます。これは、要件を満たしています。
私の調整プロセスを添付してください:
- 事前トレーニング:属性のみを変更し、パラメーターはフィルタリングしません
for param in model.parameters():
param.requires_grad = False
for param in model.encoder.parameters():
param.requires_grad = True
更新された2つのパラメーターを出力すると、エンコーダーのみが更新され、デコーダーは更新されていないことがわかります。
- 微調整:
for param in model.parameters():
param.requires_grad = True
また、更新されたパラメータを2回出力すると、デコーダのパラメータも更新されていることがわかります。以上!