Pytorchを学習する中で分からなくて調べた知識をまとめました。随時追加していきます。
ネットワーク関連
torch.nn.Conv2d
畳み込み層の定義
torch.nn.Conv2d(入力チャネル数, 出力チャネル数, カーネルサイズ)
torch.nn.Linear
線形層($y=Wx+b$)の定義
torch.nn.Linear(in_features, out_features, bias=True)
例えば, 次元数3のデータを2つ用意してこれを5次元に変換する場合
x = torch.randn(2, 3)
W = torch.nn.Linear(3, 5, False)
y = m(x)
print(y.size()) #torch.Size([2, 5])
x=
\begin{bmatrix}
x_{11} & x_{12} & x_{13}\\
x_{21} & x_{22} & x_{23}
\end{bmatrix},\\
W=
\begin{bmatrix}
w_{11} & w_{12} & w_{13} & w_{14} & w_{15}\\
w_{21} & w_{22} & w_{23} & w_{24} & w_{25}\\
w_{31} & w_{32} & w_{33} & w_{34} & w_{35}
\end{bmatrix},\\
y=xW =
\begin{bmatrix}
y_{11} & y_{12} & y_{13} & y_{14} & y_{15}\\
y_{21} & y_{22} & y_{23} & y_{24} & y_{25}
\end{bmatrix}\\
torch.nn.functional.max_pool2d
プーリング処理を行う関数1
torch.nn.functional.max_pool2d(入力, カーネルサイズ)
勾配
net.zero_grad()
netの各パラメータの勾配を0で初期化
(初期化するのは, 勾配がイテレーション毎に加算される仕様であるため)
backward()
出力や損失に対する各パラメータの勾配を計算する.
y.backward()
backward()
はbackward(torch.Tensor([1]))
の省略形である.
そのため, 例えば出力が[1,10]次元のベクトルである場合
y.backward(torch.randn(1, 10))
のようにする.
requires_grad="FLAG"
計算グラフを保持することで, そのTensorの全ての演算を追跡する.
これにより, backward()を使って全ての勾配を自動的に計算できる
x = torch.ones(2,2,requires_grad=True)
print(x)
# tensor([[1., 1.],
# [1., 1.]], requires_grad=True)
属性grad_fn
演算によって生成されたvariableには属性grad_fnが付与される(独立変数のrequires_gradフラグがTrueだった場合).
これは, どの演算によってvariableが生成されたかを知るものである
x = torch.randn(2,2)
y = x + 2
print(y.grad_fn)#None / xのrequires_gradがFalseである(演算が追跡されていない)ため
x = torch.randn(2,2,requires_grad=True)
y = x + 2
print(y.grad_fn)#<AddBackward0 object at 0x101b40e48>
z = x/2
print(z.grad_fn)#<DivBackward0 object at 0x10432beb8>
損失
nn.MSELoss()
平均二乗誤差関数
criterion=nn.MSELoss()
loss=criterion(output,target)
Tensor関連
torch.empty()
Tensorを作成する. 作成したTensorは初期化されておらず何らかの値が入っている.
x = torch.empty(5, 3)
print(x)
# tensor([[ 0.0000e+00, 1.5846e+29, -2.6611e-27],
# [-3.6902e+19, -2.6884e-27, 1.5849e+29],
# [ 0.0000e+00, 1.5846e+29, 5.6052e-45],
# [ 0.0000e+00, 0.0000e+00, 1.5846e+29],
# [ 0.0000e+00, 1.5846e+29, -2.6615e-27]])
どうやって決まるのか何の値かは謎…
torch.rand()
ランダムなTensorを作成する.
x = torch.rand(5, 3)
print(x)
# tensor([[0.5934, 0.8821, 0.2641],
# [0.3726, 0.3678, 0.2573],
# [0.2761, 0.6679, 0.7228],
# [0.9908, 0.5877, 0.5313],
# [0.4664, 0.1699, 0.0252]])
torch.zeros()
要素が0で初期化されたTensorを作成する.
x = torch.zeros(5, 3, dtype=torch.long)
print(x)
# tensor([[0, 0, 0],
# [0, 0, 0],
# [0, 0, 0],
# [0, 0, 0],
# [0, 0, 0]])
torch.tensor()
値を直接指定してTensorを作成する.
x = torch.tensor([5.5, 3])
print(x)
# tensor([5.5000, 3.0000])
new_*
既存のTensorを上書きする. ちなみに元のshapeと揃える必要は無い.
x = torch.tensor([5.5, 3])
x = x.new_ones(5, 3, dtype=torch.double)
print(x)
# tensor([[1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.],
# [1., 1., 1.]], dtype=torch.float64)
- new_zeros, new_ones, new_emptyは動いた.
- new_randはエラー
torch.randn_like()
Tensorの値をランダムに書き換え, 型を変換する
下の例では53のゼロ行列を, 53の値がランダムなフロート型に変換
x = x.new_zeros(5, 3, dtype=torch.double)
print(x)
# tensor([[0, 0, 0],
# [0, 0, 0],
# [0, 0, 0],
# [0, 0, 0],
# [0, 0, 0]])
x = torch.randn_like(x, dtype=torch.float)
print(x)
# tensor([[ 0.4074, -0.4801, -1.7652],
# [ 0.9456, -0.8796, -0.5751],
# [-1.5125, -2.3049, 0.7683],
# [ 0.8419, -0.6031, -0.2340],
# [ 0.7071, 0.8503, 0.5636]])
transpose
転置
x = torch.randn(4,3) #4行3列
torch.transpose(x)#3行4列
view
サイズ変更
x = torch.randn(4,3) #4行3列
x.view(12,1) #12行1列
x.view(-1,2) #n行2列(この場合n=6)
size
tensorのサイズを取得
x = torch.randn(4,3)
x.size() #torch.Size([4,3])
numpy()
Tensorをndarrayに変換
a = torch.ones(5)
print(a) #tensor([1., 1., 1., 1., 1.])
b = a.numpy()
print(b) #[1. 1. 1. 1. 1.]
ちなみに
a.add_(1)
print(a)
print(b)
# tensor([2., 2., 2., 2., 2.])
# [2. 2. 2. 2. 2.]
aの値の変更がbにも反映される.
torch.from_numpy()
ndarrayをTensorに変換
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
# [2. 2. 2. 2. 2.]
# tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
その他用語
- Affine(アフィン) : 全結合層, 線型層
-
プーリング層を定義するクラス(torch.nn.MaxPool2d)もある ↩