記事のディレクトリ
pytorchの基本(2つ)
活性化関数
pytorchのアクティベーション機能はnnモジュールにあります!
import torch
from torch import nn
tanh = nn.Tanh()
x = torch.tensor([1, 2, 3, 4], dtype=float)
tanh = nn.Tanh()
y = tanh(x)
print(y)
结果:
tensor([0.7616, 0.9640, 0.9951, 0.9993], dtype=torch.float64)
ReLu、Sigmoidなどはすべてnnであり、対応する関数はそれらを直接呼び出すことで取得できます。
SoftMax
import torch
from torch import nn
softmax = nn.Softmax(dim=1)
例:softmax(x)、xは、shape =(64、10)のデータです。10が配置されている次元である最初の次元でsoftmaxを実行します。つまり、グループとして10個のデータに対してsoftmax操作を実行します。
[[x0,x1,x2,x3,x4,x5,x6,x7,x8,x9],
[x0,x1,x2,x3,x4,x5,x6,x7,x8,x9],
...x61
[x0,x1,x2,x3,x4,x5,x6,x7,x8,x9]]
64ここにバッチサイズがあります!
別の例では、データバッチサイズは1です。つまり、サンプルが1つしかない場合は、次のようになります。
import torch
from torch import nn
x = torch.tensor([1, 2, 3, 4], dtype=float)
# 默认dim就是0,这里写不写都可以
sofrmax = nn.Softmax(dim=0)
y = softmax(x)
DataLoader
DataLoaderのデータセットは、リスト、テンソル(反復可能なタイプである限り)にすることができ、DataLoaderをトラバースするためにすべての要素を取得できます。
from torch.utils.data import DataLoader
x = torch.tensor([1, 2, 3, 4, 5, 6])
# 将y根据x编程独热向量,tolist是为了将y整个可以变成tensor类型(因为如果list中元素为tensor是变不成tensor类型的)
y = [torch.zeros((6,)).tolist() for i in x]
y = torch.tensor(y)
# 将x,y放到一个dataset中,以便转换成DataLoader后可以方便的取出数据
dataset = []
for i in range(len(x)):
# 转成独热向量
y[i][x[i]-1] = 1.0
# 将x,y对用元素变成元组,放到dataset中[(x0,y0),(x1,y1)...]
dataset.append((x[i], y[i]))
print(y)
print(dataset)
print()
batch_size = 2
train_loader = DataLoader(dataset=dataset,
batch_size=batch_size,
shuffle=True)
for x, y in train_loader:
print("x:", x)
print("y:", y)
结果:
tensor([[1., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1.]])
[(tensor(1), tensor([1., 0., 0., 0., 0., 0.])), (tensor(2), tensor([0., 1., 0., 0., 0., 0.])), (tensor(3), tensor([0., 0., 1., 0., 0., 0.])), (tensor(4), tensor([0., 0., 0., 1., 0., 0.])), (tensor(5), tensor([0., 0., 0., 0., 1., 0.])), (tensor(6), tensor([0., 0., 0., 0., 0., 1.]))]
x: tensor([4, 2])
y: tensor([[0., 0., 0., 1., 0., 0.],
[0., 1., 0., 0., 0., 0.]])
x: tensor([5, 1])
y: tensor([[0., 0., 0., 0., 1., 0.],
[1., 0., 0., 0., 0., 0.]])
x: tensor([3, 6])
y: tensor([[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 0., 1.]])
ワンホットエンコーディング(散布補間を使用)
上記のワンホットエンコーディングを作成することに加えて、テンソルが提供するワンホットエンコーディングの散布方法を使用することもできます。
# 这是一个batch为6,共有6类的一个分类任务
label = torch.tensor([1, 2, 3, 4, 5, 6])
# 变成二维标签,[[1], [2], ..., [6]]
label = label.reshape(-1, 1)
# tensor.scatter(dim, index, src)
# dim: 对哪个维度进行插入
# index: 对哪个位置插值
# src: 插得值是啥
one_hot = torch.zeros(label.shape[0], 6).scatter(1, label-1, 1)
# zeros得到的是一个shape=(6, 6)的一个全0 tensor
# 对这个tensor进行插值,对1维、每行插得位置分别对应label-1中的每个元素,插得值为1
结果:
tensor([[1., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1.]])
わからない場合は、サンプルを使用して次のことを行います。
label = torch.tensor([1])
one_hot = torch.zeros(6).scatter(0, label-1, 1)
结果:
tensor([1., 0., 0., 0., 0., 0.])
脱落
import torch
from torch import nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
# 隐藏层有500个节点,接收输入为784大小的数据
self.hidden = nn.Linear(784, 500)
# 将输入的数据50%变为0,也就变相的让向它提供数据的那一层丢弃50%的节点。
self.drop = nn.Dropout(p=0.5)
# 10个分类
self.out = nn.Linear(500, 10)
def forward(self, x):
x = self.hidden(x)
x = self.drop(x)
y_hat = self.out(x)
return y_hat
重量減衰
重みの減衰はトレーナーに配置されます(損失関数ではありません)。バックプロパゲーション時に古い損失関数を引き続き使用するため、勾配降下法がパラメーターを更新するときに更新メソッドに逆数の正則化項を追加し(ステップ)、パラメーターを直接取り込むことで重みの減衰を実現できます。
import torch
from torch import nn, optim
optimizer = optim.SGD(model.parameters(), lr, weight_decay=0.1)
- weight_decayは、正則化項のパラメーターです。(モデルのハイパーパラメーターである正則化項の重要性を判断します)
オプティマイザ
すべてのオプティマイザーの本質は最急降下法です!
SGD
SGDは基本的なアルゴリズムです。
- 短所:鞍点で下げることはできません(最悪の場合、実際に遭遇することは基本的に不可能です)
勢い
最急降下法の慣性を作成します。
- 利点:高速収束
- 短所:トレーニング回数が少ないと方向が正しくない場合がありますが(収束が速いため、方向を探すときにブレーキがかかりにくい)、トレーニング回数が多いと方向が正しくなりません。正しい方向に戻すように調整する
NAG
これは、Momentumの改良されたアルゴリズムです。
- 利点:勢いよりも正しい方向を見つけるのが速い
- 短所:トレーニングセッションの数が少ない場合でも、方向は正しくありません
アダム
確率的勾配降下法は、すべての重みを更新するために単一の学習率(つまり、アルファ)を維持し、学習率はトレーニングプロセス中に変化しません。また、Adamは、勾配の1次モーメント推定と2次モーメント推定を計算することにより、さまざまなパラメーターに対して独立した適応学習率Adamアルゴリズムを設計します。(つまり、Adam最適化アルゴリズムはトレーニングプロセス中にlr学習率を最適化します)
- 利点:SGDよりも優れて高速で、他の最適化アルゴリズムよりも安定しています(どちらを選択するかわからない場合は、Adamを使用してください)
import torch
from torch import nn, optim
optimizer = optim.Adam(model.parameters(), lr, weight_decay=0.1)
Adam最適化アルゴリズムを使用すると、lrを適切に調整できます。
方法はより安定しています(どちらを選択するかわからない場合は、Adamを使用してください)
import torch
from torch import nn, optim
optimizer = optim.Adam(model.parameters(), lr, weight_decay=0.1)
Adam最適化アルゴリズムを使用すると、lrを適切に調整できます。
モデルを保存してモデルをロードする
モデルを保存します
torch.save()
保存に使用
モデルを保存するには、モデルをディスクにシリアル化します。Pytorchは、シリアル化にPythonのpickleプログラムを使用します。
pytorchでは、モデル、テンソル、辞書をすべてディスクにシリアル化できます。
関数プロトタイプ:torch.save(obj, f, pickle_model=<module '...'>, pickle_protocol=2)
パラメータ | 説明 |
---|---|
obj | オブジェクトを保持します |
f | 保存されたファイル名の文字列(またはファイルのようなオブジェクト) |
pickle_module | メタデータとオブジェクトを選択するためのモジュール |
pickle_protocol | デフォルトのパラメータを上書きするには、pickleprotocalを指定します |
フォーマット.pt\.pth\.pkl
:モデルの。3つすべてが問題なく、形式に違いはなく、接尾辞だけが異なります
モデル全体を保存する
モデル全体の结构
ANDを参数
保存します。
モデル全体をロードする場合、モデルをリファクタリングする必要はなく、変数をモデルとして直接ロードします。
# 用 pt pth pkl ckpt都可以
torch.save(model, "model.pt")
モデルのパラメータのみを保存します
モデルのパラメーターのみを保存します。ロードするときは、モデルをインスタンス化して(構造を取得)、パラメーターをロードする必要があります。
これにはモデルクラスが必要です(モデルフォーム全体を保存する場合、モデルクラスは必要ありません)
# 用 pt pth pkl ckpt都可以
torch.save(model.state_dict(), "model_params.pt")
保存されたモデルファイルのハイパーパラメータ
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss
}, "model.pt")
# 加载
model = MyModel()
optimizer = optim.SGD(*args, **kwargs)
checkpoint = torch.load("model.pt")
model.load_state_dict(checkpoint["model_state_dict"])
optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
epoch = checkpoint["epoch"]
loss = checkpoint["loss"]
# 或model.train()
model.eval()
複数のモデルをファイルに保存
torch.save({
"modelA_state_dict": modelA.state_dict(),
"modelB_state_dict": modelB.state_dict()
}, "models_params.pt")
# 加载
checkpoint = torch.load("models_params.pt")
modelA = MyModelA()
modelB = MyModelB()
modelA.load_state_dict(checkpoint["modelA_state_dict"])
modelB.load_state_dict(checkpoint["modelB_state_dict"])
modelA.train()
modelB.train()
微調整を使用してモデルを事前トレーニングします
# 保存预训练模型A
torch.save(model.state_dict(), "model_param.pt")
# 加载预训练模型A到模型B中
model.load_state_dict("model_param.pt", strict=False)
この部分は、転移学習で非常に一般的に使用されます
事前トレーニングのためにいくつかのモデルパラメータをロードすると、キーの不一致が発生する可能性があります(モデルの重みは保存され、キーと値のペアの形式でロードされます)。したがって、キーの不足や過剰なキーに関係なく、load_state_dict()関数でstrictパラメーターをFalseに設定することにより、一致しないキーを無視できます。
特定のレイヤーのパラメーターを他のレイヤーにロードしたいが、一部のキーが一致しない場合は、state_dictのパラメーターのキーを変更して、この問題を解決します。
モデルをロードします
モデルをpytorchにロードするには、Pythonの選択解除ツールを使用して、ディスク上のモデルをメモリに逆シリアル化します。
モデル全体をロードする
関数プロトタイプ:torch.load(f, map_location=None, puckle_model=<module 'pickle' from '...'>)
パラメータ | 説明 |
---|---|
f | ファイル名(またはファイルのようなオブジェクト)を保存するための文字列 |
map_location | 関数または辞書は、ストレージデバイスをマップする方法を指定します |
puckle_module | メタデータとオブジェクトのピクル解除用モジュール(ファイルをシリアル化する必要がある場合はpickle_module) |
# 用 pt pth pkl 都可以
# 加载模型到cpu上
model = torch.load("model.pt")
# 加载模型到cpu上
model = torch.load("model.pt", map_location=torch.device('cpu'))
# 使用方法的形式,加载模型到cpu上
model = torch.load("model.pt", map_location=lambda storage, loc: storage)
# 加载模型到gpu1上
model = torch.load("model.pt", map_location=lambda storage, loc: storage.cuda(1))
# 将模型从gpu1映射到gpu0上
model = torch.load("model.pt", map_location={
'cuda:1': 'cuda:0'})
# 注意一定要使用model.eval()来固定dropout和归一化层,否则每次推理会生成不同的结果
# 或model.train()
model.eval()
モデルパラメータをロードします
関数プロトタイプ:torch.nn.Module.load_state_dict(state_dict, strict=True)
パラメータ | 説明 |
---|---|
state_dict | モデルを保存するための辞書 |
厳格 | state_dictのキーは、model.state_dict()によって返されるキーと一致していますか? |
model = MyModel()
# 模型将加载的权重复制到模型的权重中去
model.load_state_dict(torch.load("model_params.pt"))
# 注意一定要使用model.eval()来固定dropout和归一化层,否则每次推理会生成不同的结果
# 或model.train()
model.eval()
ドロップアウトと正規化レイヤーを修正するには、model.eval()を使用する必要があることに注意してください。そうしないと、推論ごとに異なる結果が生成されます。(または使用model.train()
)