重みを修正し、一部のレイヤーの学習率を 0 に変更するにはどうすればよいですか?

PyTorchのソースコード解釈のtorch.autograd:勾配計算の詳細説明 ディープ
ニューラルネットワークを学習させる際、特定の層やパラメータを更新せずに修正する必要がある場合があります。PyTorch が提供する nn.Module のparameters() メソッドを使用して、学習する必要があるすべてのパラメータを取得できます。また、torch.optim.SGD() などのオプティマイザの param_groups パラメータを使用して、さまざまな層の学習率を制御できます。 。学習率を 0 に設定すると、特定のレイヤーまたはパラメーターの重みを固定できます。

たとえば、次の例では、ネットワークの最初の 3 つの畳み込み層の重みを固定し、これらの層の重みを更新しないとします。

import torch.optim as optim

model = MyModel()  # 这里定义自己的模型
optimizer = optim.SGD([{
    
    'params': model.fc.weight, 'lr': 0.01},
                       {
    
    'params': model.fc.bias, 'lr': 0.02},
                       {
    
    'params': model.conv1.parameters()},
                       {
    
    'params': model.conv2.parameters(), 'lr': 0}], lr=0.1)

for epoch in range(num_epochs):
    # 训练代码

上記のコードでは、最初の全接続層の重みを学習率 0.01 に設定し、最初の全接続層のバイアスを学習率 0.02 に設定します。また、最初の畳み込み層と 2 番目の畳み込み層の両方の重みを学習率 0 に設定します。これにより、最初の 3 つの畳み込み層の重みが固定され、全​​結合層の学習率が調整されます。トレーニング中に、完全に接続された層の重みのみが更新され、最初の 3 つの畳み込み層は更新されません。

さまざまなレイヤーの学習率を設定するもう 1 つの方法は、パラメーター グループを使用することです。PyTorch では、オプティマイザーのパラメーター グループを使用して、パラメーターごとに異なる学習率と異なる重み減衰を設定します。optim.SGD() などのオプティマイザーの param_groups パラメーターを使用して、さまざまなパラメーターをさまざまなグループに分割し、さまざまなレイヤーの学習率を設定できます。

たとえば、次の例では、ネットワークの最初の 3 つの畳み込み層の重みを重み減衰なしで固定し、全結合層の重みの学習率を 0.01 に設定し、重み減衰を 0.001 に設定するとします。

import torch.optim as optim

model = MyModel()  # 这里定义自己的模型
params = [{
    
    'params': model.conv1.parameters()},
          {
    
    'params': model.conv2.parameters()},
          {
    
    'params': model.conv3.parameters()},
          {
    
    'params': model.fc.parameters(), 'lr': 0.01, 'weight_decay': 0.001}]

optimizer = optim.SGD(params, lr=0.1)

for epoch in range(num_epochs):
    # 训练代码

この例では、まず最初の 3 つの畳み込み層のパラメーターを 1 つのグループにグループ化し、model.conv1.parameters() などのメソッドを使用してこれらのパラメーターを取得します。次に、全結合層のパラメーターを別のグループに分割し、lr パラメーターとweight_decay パラメーターを指定して、異なる学習率と重み減衰を設定します。最後に、これらを組み合わせて引数リストを作成し、optim.SGD() オプティマイザーに渡します。トレーニング プロセス中、最初の 3 つの畳み込み層の重みは固定され、重み減衰を受けませんが、完全に接続された層の重みは、設定した学習率と重み減衰に従って更新されます。

コード内のさまざまなレイヤーの学習率を手動で設定することに加えて、Adam、Adagrad、Adadelta などの適応学習率調整用のオプティマイザーを使用することもできます。これらのオプティマイザーは各パラメーターの学習率を自動的に調整できるため、さまざまなパラメーターが適切な学習率で更新され、パフォーマンスが向上します。

Adam を例に挙げると、学習率を動的に調整する方法は、勾配の二乗平均、勾配の一次モーメント推定、および勾配の二次モーメント推定に基づいて各パラメーターの学習率を計算することです。PyTorch では、torch.optim.Adam() を使用して Adam オプティマイザーを作成できます。

次の例は、トレーニングに Adam オプティマイザーを使用し、さまざまなパラメーターの学習率を自動的に調整する方法を示しています。

import torch.optim as optim

model = MyModel()  # 这里定义自己的模型
optimizer = optim.Adam(model.parameters(), lr=0.001)

for epoch in range(num_epochs):
    # 训练代码
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

この例では、 optim.Adam() を使用して Adam オプティマイザーを作成し、モデルのすべてのパラメーターを渡します。各エポックでは、最初に optimizer.zero_grad() を使用して勾配をクリアし、次に順伝播と逆伝播を実行して損失と勾配を計算し、最後に optimizer.step() を使用してすべてのパラメータを更新し、各パラメータの学習率を自動的に調整します。

適応学習率を備えたオプティマイザーを使用すると、さまざまなレイヤーの学習率を手動で設定する必要がなくなり、オプティマイザーが各パラメーターの状況に応じて自動的に調整されるため、優れた堅牢性と汎化パフォーマンスを備えていることに注意してください。

パイトーチ

PyTorch では、requires_grad属性を使用してモデル内のどのパラメータが勾配を計算する必要があるかを制御することができ、それによってどの層の重みがトレーニングに参加し、どの層の重みがトレーニングに参加しないかを制御できます。

具体的には、一部のレイヤーのウェイトを修正する必要がある場合は、対応するパラメーターのプロパティを False に設定できますrequires_grad。つまり、勾配を計算する必要はありません。こうすることで、これらの層の重みはモデルの逆伝播中に更新されません。

以下は、モデルの最初の 2 つの層の重みをトレーニングに参加しないように修正する方法を示すサンプル コードです。

import torch
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.layer1 = nn.Linear(10, 20)
        self.layer2 = nn.Linear(20, 30)
        self.layer3 = nn.Linear(30, 40)
        
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        return x

model = MyModel()

# 固定前两层的权重不参与训练
for param in model.layer1.parameters():
    param.requires_grad = False
for param in model.layer2.parameters():
    param.requires_grad = False

# 打印模型参数的requires_grad属性
for name, param in model.named_parameters():
    print(name, param.requires_grad)

上記のコードでは、最初に 3 つの完全に接続された層を持つモデルを定義しMyModel、次にモデルの最初の 2 つの層の重みのプロパティをrequires_gradFalse に設定し、最後にrequires_gradモデルのすべてのパラメータのプロパティを出力して、正常に接続されたことを確認しました。固定 最初の 2 つのレイヤーの重みはトレーニングに参加しません。

おすすめ

転載: blog.csdn.net/qq_44089890/article/details/130464164