pytoch fine-tuneの事前訓練の模型の操作
一つ:
tochvisionには多くの予備訓練されたモデルが含まれています。そうすると、fine-tuneはとても簡単になります。この論文では、どのようにFine-tune tochvisionで事前に訓練されたモデルを紹介します。
インストール
resennt 18を例として:
ここではレレスを紹介します。model.fc=nn.linear(in_)フィーチャー=…、out_フィーチャー=100)の時にフレーム内で何が発生しましたか?
この時はnn.Moduleのソースコードの_u uを見るべきです。setattr部分的には、setattr時にはこの方法を呼び出すからです。
予備訓練のモデルにfcという名前のModuleがあります。
クラスの定義以外に、もう一つのModuleをfcに再割り当てしました。
クラス定義内のfc対応のModuleはモデルから削除されます。
その二:
前言
この文章は論壇PyTorch Forumsのパラメータ初期化とfinetuneに関するまとめであり、コードを書く際に私が使っているのも「最良の実践」と言えるでしょう。最後に、皆さんが大丈夫で、もっとフォーラムを見てください。質の高い答えがたくさんあります。
パラメータ初期化
パラメータの初期化は、実際にはパラメータの割り当てです。私たちが学ぶべきパラメータは実はすべてVarableであり、それは実際にTensorのパッケージであり、同時にdata、gradなどの言い訳を提供しています。これはこれらのパラメータを直接操作して評価することができるということです。これはPyTorchの簡潔で効率的なところです。
したがって、次のような操作で初期化ができます。もちろん他の方法がありますが、この方法はPyTorchの著者が推奨しています。
前トレーニングモデルのパラメータをロードした後に、異なる方法でfinetuneモデルが必要になります。
ローカル微調整
トレーニングモデルをロードした後、最後の層だけを調節したいです。他の層は訓練しません。実は訓練しないということは、勾配計算を行わないということです。PyTorchで提供されるrequires gau。gradは訓練に対する制御を非常に簡単にする。
時には全体に対してfinetuneを行う必要がありますが、私達は他の層と新しい層をoptimizerの中で別々に学習速度を与えることができます。たとえば:
その3:
pytoch finetuneモデル
記事は主に、pytouchで従来訓練されたモデルパラメータを読み取る方法、モデルの名前が変更された場合、モデルの一部パラメータをどのように読み取りますか?
pytochモデルの保存と読み込み
モデルの保存プロセスには、モデルとパラメータが一緒に記憶されています。また、モデルパラメータが別に記憶されています。
モデルパラメータを個別に記憶する
保存時に使用する:
保存:
fine-tuneのプロセスは元のモデルのパラメータを読み取ることですが、モデルの処理するデータセットが違って、最後のレイヤーのクラスの総数が違っていますので、モデルの最終層を修正する必要があります。このようなモデルで読み込むパラメータは、大きなデータセットでダウンロードを訓練するモデルパラメータとは形が違っています。私たちは自分で関数を書いてパラメータを読み取る必要があります。
pytochモデルパラメータの形式
モデルのパラメータは辞書として記憶されています。
モデルのパラメータを変更したいなら、該当するキーに値を付けてもいいです。
私たちは下記のアルゴリズムでモデルを読み取ることができます。
自分で対応関係を探します。一つのkeyは一つのkeyの割り当てに対応します。
以上は個人の経験ですので、参考にしていただければと思います。
tochvisionには多くの予備訓練されたモデルが含まれています。そうすると、fine-tuneはとても簡単になります。この論文では、どのようにFine-tune tochvisionで事前に訓練されたモデルを紹介します。
インストール
pip install torchvision
どのようにfine-tuneを使いますかresennt 18を例として:
from torchvision import models
from torch import nn
from torch import optim
resnet_model = models.resnet18(pretrained=True)
# pretrained True, ,
# , load , 。
# 100 ,
# 1. resnet
# 2. ( resnet self.fc = nn.Linear(512 * block.expansion, num_classes))
# 3.
resnet_model.fc= nn.Linear(in_features=..., out_features=100)
# , , 。
# , :
# 1. requires_grad False
# 2. optimizer, optimizer
# 3. backward, step
# ,
for para in list(resnet_model.parameters())[:-2]:
para.requires_grad=False
optimizer = optim.SGD(params=[resnet_model.fc.weight, resnet_model.fc.bias], lr=1e-3)
...
なぜですかここではレレスを紹介します。model.fc=nn.linear(in_)フィーチャー=…、out_フィーチャー=100)の時にフレーム内で何が発生しましたか?
この時はnn.Moduleのソースコードの_u uを見るべきです。setattr部分的には、setattr時にはこの方法を呼び出すからです。
def __setattr__(self, name, value):
def remove_from(*dicts):
for d in dicts:
if name in d:
del d[name]
まず目に映るのがレモブです。fromという関数は、この関数の目的は、同名の属性が現れたら古い属性を削除することです。先ほど挙げた例では、予備訓練のモデルにfcという名前のModuleがあります。
クラスの定義以外に、もう一つのModuleをfcに再割り当てしました。
クラス定義内のfc対応のModuleはモデルから削除されます。
その二:
前言
この文章は論壇PyTorch Forumsのパラメータ初期化とfinetuneに関するまとめであり、コードを書く際に私が使っているのも「最良の実践」と言えるでしょう。最後に、皆さんが大丈夫で、もっとフォーラムを見てください。質の高い答えがたくさんあります。
パラメータ初期化
パラメータの初期化は、実際にはパラメータの割り当てです。私たちが学ぶべきパラメータは実はすべてVarableであり、それは実際にTensorのパッケージであり、同時にdata、gradなどの言い訳を提供しています。これはこれらのパラメータを直接操作して評価することができるということです。これはPyTorchの簡潔で効率的なところです。
したがって、次のような操作で初期化ができます。もちろん他の方法がありますが、この方法はPyTorchの著者が推奨しています。
def weight_init(m):
# isinstance m
if isinstance(m, nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0, math.sqrt(2. / n))
elif isinstance(m, nn.BatchNorm2d):
# m weight,bias Variable,
m.weight.data.fill_(1)
m.bias.data.zero_()
Finetune前トレーニングモデルのパラメータをロードした後に、異なる方法でfinetuneモデルが必要になります。
ローカル微調整
トレーニングモデルをロードした後、最後の層だけを調節したいです。他の層は訓練しません。実は訓練しないということは、勾配計算を行わないということです。PyTorchで提供されるrequires gau。gradは訓練に対する制御を非常に簡単にする。
model = torchvision.models.resnet18(pretrained=True)
for param in model.parameters():
param.requires_grad = False
# , 100
# requires_grad True
model.fc = nn.Linear(512, 100)
#
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)
全体の微調整時には全体に対してfinetuneを行う必要がありますが、私達は他の層と新しい層をoptimizerの中で別々に学習速度を与えることができます。たとえば:
ignored_params = list(map(id, model.fc.parameters()))
base_params = filter(lambda p: id(p) not in ignored_params,
model.parameters())
optimizer = torch.optim.SGD([
{'params': base_params},
{'params': model.fc.parameters(), 'lr': 1e-3}
], lr=1e-2, momentum=0.9)
その中base_パラmsは1 e-3を使ってトレーニングします。model.fc.parametersは1 e-2を使ってトレーニングします。momenumは2つのものです。その3:
pytoch finetuneモデル
記事は主に、pytouchで従来訓練されたモデルパラメータを読み取る方法、モデルの名前が変更された場合、モデルの一部パラメータをどのように読み取りますか?
pytochモデルの保存と読み込み
モデルの保存プロセスには、モデルとパラメータが一緒に記憶されています。また、モデルパラメータが別に記憶されています。
モデルパラメータを個別に記憶する
保存時に使用する:
torch.save(the_model.state_dict(), PATH)
読み込み時:
the_model = TheModelClass(*args, **kwargs)
the_model.load_state_dict(torch.load(PATH))
モデルとパラメータを格納する保存:
torch.save(the_model, PATH)
読み込み:
the_model = torch.load(PATH)
モデルのパラメータfine-tuneのプロセスは元のモデルのパラメータを読み取ることですが、モデルの処理するデータセットが違って、最後のレイヤーのクラスの総数が違っていますので、モデルの最終層を修正する必要があります。このようなモデルで読み込むパラメータは、大きなデータセットでダウンロードを訓練するモデルパラメータとは形が違っています。私たちは自分で関数を書いてパラメータを読み取る必要があります。
pytochモデルパラメータの形式
モデルのパラメータは辞書として記憶されています。
model_dict = the_model.state_dict(),
for k,v in model_dict.items():
print(k)
すべてのキーが表示されます。モデルのパラメータを変更したいなら、該当するキーに値を付けてもいいです。
model_dict[k] = new_value
最後にモデルのパラメータを更新します。
the_model.load_state_dict(model_dict)
モデルのkey値と大きなデータセットでトレーニングしたときのkey値が同じであれば私たちは下記のアルゴリズムでモデルを読み取ることができます。
model_dict = model.state_dict()
pretrained_dict = torch.load(model_path)
# 1. filter out unnecessary keys
diff = {k: v for k, v in model_dict.items() if \
k in pretrained_dict and pretrained_dict[k].size() == v.size()}
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict and model_dict[k].size() == v.size()}
pretrained_dict.update(diff)
# 2. overwrite entries in the existing state dict
model_dict.update(pretrained_dict)
# 3. load the new state dict
model.load_state_dict(model_dict)
モデルのkey値と大きなデータセットでトレーニングしたときのkey値が異なる場合、順番は同じです。
model_dict = model.state_dict()
pretrained_dict = torch.load(model_path)
keys = []
for k,v in pretrained_dict.items():
keys.append(k)
i = 0
for k,v in model_dict.items():
if v.size() == pretrained_dict[keys[i]].size():
print(k, ',', keys[i])
model_dict[k]=pretrained_dict[keys[i]]
i = i + 1
model.load_state_dict(model_dict)
モデルのkey値と大きなデータセットでトレーニングしたときのkey値が違っていたら、順番は違っています。自分で対応関係を探します。一つのkeyは一つのkeyの割り当てに対応します。
以上は個人の経験ですので、参考にしていただければと思います。