目次
こんにちは。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)