← Python and ROCm 教室へ戻る

第10章

たたみこみを動かしてみたい

画像っぽい shape を持つデータが、畳み込みでどう流れるかを見てみます。

今日は何をしたい?

第6章では nn.Linear を使いましたが、画像のように「縦×横」の空間構造があるデータには Conv2d(たたみこみ)が使われます。たたみこみは、小さなフィルター(窓)をデータの上で滑らせて特徴を拾い出す操作です。

Conv2d という部品を動かして、入力 shape と出力 shape を読めるようにします。いきなり画像認識の話を全部やるのではなく、まずは形の流れをつかむ章です。

畳み込みの shape は 4 つの数字で書きます。並び順は N, C, H, W です。

記号意味この例の値
Nバッチ(何枚まとめて流すか)1
Cチャネル(色の層の数)1 → 2
H高さ5
W5

入力と出力の shape は、こう流れます。

入力 (1, 1, 5, 5) Conv2d(1, 2, 3, padding=1) 出力 (1, 2, 5, 5)

変わったのは 2 番目の数字(チャネル)だけです。Conv2d(1, 2, ...)2 が出力チャネル数になります。

確認コード

import torch
import torch.nn as nn

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

conv = nn.Conv2d(1, 2, kernel_size=3, padding=1).to(device)
x = torch.randn(1, 1, 5, 5, device=device)
y = conv(x)

print("入力 shape:", x.shape)
print("出力 shape:", y.shape)

kernel_size=3 は 3×3 の小窓でデータを走査します。padding=1 は端に 0 を埋めて、高さ・幅が変わらないようにしています。

入力 shape: torch.Size([1, 1, 5, 5]) 出力 shape: torch.Size([1, 2, 5, 5])

最初は 4 つの数字が並んでいると見られれば十分です。

変わったのは 2 番目の数字(チャネル)だけ — これが読めればこの章は OK です。

実行コマンド

ファイルを chapter10.py という名前で保存したら、ターミナルで次のコマンドを実行します。

python chapter10.py

どこがROCm?

畳み込みは、画像まわりでよく出る代表的な計算です。AMD GPU では MIOpen というたたみこみ専用の高速化エンジンが動いています(名前は覚えなくて大丈夫です)。第3章の行列積と同様に、ROCm の下ではこうした定番の処理を速く走らせるための専用経路が用意されています。

ここで出てきたPython

Conv2d の引数の意味(クリックで開く)

Conv2d(1, 2, kernel_size=3, padding=1) の 1 は入力チャネル。2 は出力チャネル。3 はフィルタの大きさ。padding=1 は端に 0 を足して高さ・幅を変えない設定です。

よくあるつまずき

たとえば入力のチャネルが 3 なのに Conv2d(1, ...) にすると、こうなります。

# in_channels が合わない例
conv_wrong = nn.Conv2d(1, 2, kernel_size=3, padding=1).to(device)
x_rgb = torch.randn(1, 3, 5, 5, device=device)  # チャネル 3

try:
    conv_wrong(x_rgb)
except RuntimeError as e:
    print(e)
Given groups=1, weight of size [2, 1, 3, 3], expected input[1, 3, 5, 5] to have 1 channels, but got 3 channels instead

エラーの「expected ... 1 channels, but got 3」が、入力チャネル数と in_channels のずれを教えてくれます。Conv2d(3, 2, ...) に直せば通ります。

1分演習

Conv2d(1, 2, ...) の 2 を 4 に変えて、出力 shape のどこが変わるかを見てみましょう。