
目次
こんにちは。sinyです。
最近Pytorchを学習し始めましたが、四苦八苦しております・・・
基本知識をまとめて効率よく学習するためにpytorchでよく使う基本知識のまとめ記事を作成しました。
継続してアップデートしていきます。
Linear 層
■nn.Linear 線形結合を計算するクラス
- nn.Linear(入力サイズ,出力サイズ)
例nn.Linear(64, 32)net = nn.Linear(in_features=3, out_features=1, bias=False)
損失関数
■nn.MSELoss 損失関数を計算するクラス
■optimizer = optim.SGD(net.parameters(), lr=0.1)
torch.nn.Module
すべてのニューラルネットワークモジュールの基本クラス。
モデルもこのクラスをサブクラス化する必要がある。
モジュールには他のモジュールを含めることもできる。
これにより、モジュールをツリー構造にネストできる。
サブモジュールを通常の属性として割り当てることもできる。
サンプルコード
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x)
add_module(name, module)
nn.Moduleクラスのメソッドで、現在のモジュールに子モジュールを追加するメソッド。
モジュールは、指定された名前を使用して属性としてアクセスできる。
パラメータは以下の2つ。
- name(string)
子モジュールの名前。 子モジュールは、指定された名前を使用してこのモジュールからアクセスできる。 - module(Module)
モジュールに追加される子モジュール。
学習モードと推論モード
pytorchには学習モードと推論モードがある。
- 学習モード:まず学習時にはmodel.train()を実行て学習モードにする(デフォルト)
- 推論時にはmodel.eval()を実行して、推論モードに切り替える。
※DropoutレイヤとBNレイヤをevaluationモードにするために必要。
Conv2D層
※設定例:COnv2d(256, 512, kernel_size=2, stride=2, padding=1)
画像処理の注意点
PytorchとPillowでは画像要素の順番が異なる。
- pytorch:(チャネル、高さ、幅)の順
- pillow:(高さ、幅、チャネル)の順
pytorchで生成されたテンソルをpillowで扱うには順番を変える必要がある。
→numpy().transpose((軸の順番を指定))
例:numpy().transpose((1, 2, 0))
※チャネル、高さ、幅 →高さ、幅、チャンネルに入れ替える。
np.clip() は,区間の最大値大きい入力はその最大値に,逆に最小値より小さい入力はその最小値にする関数。
Pytorchのネットワークに画像を入力する際の注意点
データをミニバッチの形にする必要があるので、unsqueeze_(0)を使って入力データにミニバッチの次元を追加する必要がある。
torch.Size([3, 224, 224]) → torch.Size([1, 3, 224, 224])
DatasetとDataLoader
Pytorchには特徴量XとラベルYをまとめたコンテナがあり、TensorDatasetという。
これは、Datasetを承継したクラス。
TensorDatasetにはTensorの見渡すことができる。
TensorDatasetをDataLoaderに渡すと、ループ処理で一部のデータだけを受け取ることができる。
前処理系
torchvision
Transforms:画像でよく使われる前処理は用意してくれています。
— Scale:大きさ変更
— CenterCrop:真ん中でクロッピング
— RandomCrop:ランダムにクロッピング
— RandomHorizontalFlip:ある確率でFlip
— Normalize:正規化
— ToTensor:PIL.ImageやnumpyをTensor化
Dropout
ドロップアウトの適用。
- nn.Dropout(0.5)
BatchNormalization
バッチ正規化の適用。
- nn.BatchNorm1d(k)
BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) - num_features:
input size (N, C, H, W)のから予測されるCの値 - momentum:
running_meanおよびrunning_varの計算に使用される値。 累積移動平均(つまり、単純平均)の場合、なしに設定できます。 デフォルト:0.1
torch.nn.Sequential(*args)
モジュールは、コンストラクターに渡された順序で追加されます。
あるいは、モジュールの順序付き辞書も渡すことができます。
サンプルコード
# Example of using Sequential
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
ちなみに、nn.Sequentialを承継すると、自動的にforwardメソッドが実装されるので改めてforwardを定義する必要がない。
(順伝搬を自動的に時やってくれる)
nn.Embedding
テキストデータのトークン化。
Embeddingの第1引数は、トークンの種類、第2引数がトークン化後の次元数を指定。
以下の例では、1万種類の単語で、10次元にベクトル化している例。
from torch import nn
embed = nn.Embedding(10000, 10, padding_idx=0)
# Embedding層への入力はint64のTensor
input = torch.tensor([1, 2, 5, 3, 7], dtype=torch.int64)
# 出力はfloat32のTensor
output = embed(input)
print(output)
#実行結果
torch.Size([5, 10])
Ttensor([[ 0.2863, -0.9933, -0.3370, 0.7446, 0.1270, 0.9122, 0.8053, 1.1777,
1.6362, 0.8427],
[ 0.3914, -0.5673, 0.1302, 1.5891, -0.3513, 0.4035, 0.5454, 1.1263,
0.1845, 2.2371],
[-0.2012, -0.4765, -1.2089, -0.4344, 0.5657, -0.1567, 0.6673, -2.2443,
0.5802, 0.3313],
[-0.0597, 0.5443, -0.4766, -0.3870, 1.8742, 0.3107, -0.2455, -0.3967,
0.7191, -0.3401],
[-1.2419, -0.3370, -0.1736, 1.8406, 0.7087, 0.8820, -0.1836, -0.3523,
0.4609, 0.4240]], grad_fn=<EmbeddingBackward>)
※padding_idxを指定することで、そのIDはすべて0のベクトルになる。
max関数
torchのMax関数の利用。
tensorデータ中のMAX値を返してくれる。
a = torch.randn(1, 3)
print(a)
print("=================================")
print(a.max(1))
print("=================================")
print(torch.max(a))
#実行結果
tensor([[ 0.8915, 0.2779, -0.1820]])
=================================
torch.return_types.max(
values=tensor([0.8915]),
indices=tensor([0]))
=================================
tensor(0.8915)
torch.max(input, dim, keepdim=False, out=None)
- dimを省略するとinputの中で一番大きい値を返す。
- dim=1を指定すると行方向で1番大きい値を返す。
- dim=0を指定すると列方向で1番大きい値を返す。
以下、参考例です。
a = torch.randn(4, 4)
print(a)
print(torch.max(a)) #最大値を1つ取得
print(torch.max(a, 1)) #行方向の最大値を取得
print(torch.max(a, 0)) #列方向の最大値を1つ取得
x,y = torch.max(a, 1) #行方向の最大値を取得
print(x)
print(y)
#出力結果
tensor([[ 1.2307, -0.4622, -0.7571, -0.7515],
[-1.0053, 0.1498, 0.5119, 0.1440],
[-0.6871, 1.4413, -0.4745, 1.4345],
[ 0.7839, -0.0550, 0.2228, 0.6828]])
tensor(1.4413)
torch.return_types.max(
values=tensor([1.2307, 0.5119, 1.4413, 0.7839]),
indices=tensor([0, 2, 1, 0]))
torch.return_types.max(
values=tensor([1.2307, 1.4413, 0.5119, 1.4345]),
indices=tensor([0, 2, 1, 2]))
tensor([2.4926, 0.6446, 1.8843, 1.3954]) #print(x)の結果
tensor([3, 2, 3, 2]) #print(y)の結果
x,y = torch.max(a, 1)のようにするとxに値、yにIndexを取得することができる。
ImageFolder
訓練、テストデータのフォルダ構成例
└─data
├─test
│ ├─bike
│ └─car
└─train
├─bike
└─car
ImageFolderを使うと、自動でクラス分けとラベル付けがされる。
フォルダ名をクラス名、各クラスにINDEXを割り当ててくれる。
from torchvision.datasets import ImageFolder
from torchvision import transforms
from torch.utils.data import TensorDataset, DataLoader
# ImageFolder関数を使用してDatasetを作成する
train_imgs = ImageFolder(
"./data/train",
transform=transforms.Compose([
transforms.ToTensor()]
print(train_imgs.classes)
print(train_imgs.class_to_idx)
#実行結果
['bike', 'car']
{'bike': 0, 'car': 1}
save_imageメソッド
save_image(tensor, filename, nrow=8, padding=2, normalize=False, range=None, scale_each=False, pad_value=0)
- tensor・・・4次元のミニバッチTensor:形状 (B x C x H x W)
※複数指定できるがすべて同一の形状でないとだめ。
※例:torch.Size([4, 3, 128, 128]) - filename・・・保存するファイル名
- nrow・・・グリッドの各行に表示される画像の数
※最終グリッドサイズは(B / nrow、nrow)
※デフォルトは8 - padding ・・・パディング数(デフォルトは2)
y1,y2,y3の形状がすべてtorch.Size([4, 3, 128, 128])とすると、以下のコードで4x4の画像ファイル(sample.jpg)が生成される。
from torchvision.utils import save_image
save_image(torch.cat([y1,y2,y3], 0), "sample.jpg", nrow=4)
from IPython.display import Image,display_jpeg
display_jpeg(Image('sample.jpg'))
torch.arange
連続値で初期化されたTensorオブジェクトを生成した場合はtorch.arangeが使える。
# 0から20までの数値で初期化された1次元のTensor
t = torch.arange(0, 10)
print(t)
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19])
torch.nn.ModuleList
pythonのリストのようにpytorchのモジュールを生成したい場合は、nn.ModuleListが便利。
以下は、全結合層を10個作成する例。
module_list = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
for i in module_list:
print(i)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)
Linear(in_features=10, out_features=10, bias=True)

