第10章
たたみこみを動かしてみたい
画像っぽい shape を持つデータが、畳み込みでどう流れるかを見てみます。
今日は何をしたい?
第6章では nn.Linear を使いましたが、画像のように「縦×横」の空間構造があるデータには Conv2d(たたみこみ)が使われます。たたみこみは、小さなフィルター(窓)をデータの上で滑らせて特徴を拾い出す操作です。
Conv2d という部品を動かして、入力 shape と出力 shape を読めるようにします。いきなり画像認識の話を全部やるのではなく、まずは形の流れをつかむ章です。
畳み込みの shape は 4 つの数字で書きます。並び順は N, C, H, W です。
| 記号 | 意味 | この例の値 |
|---|---|---|
| N | バッチ(何枚まとめて流すか) | 1 |
| C | チャネル(色の層の数) | 1 → 2 |
| H | 高さ | 5 |
| W | 幅 | 5 |
入力と出力の shape は、こう流れます。
変わったのは 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 を埋めて、高さ・幅が変わらないようにしています。
最初は 4 つの数字が並んでいると見られれば十分です。
実行コマンド
ファイルを chapter10.py という名前で保存したら、ターミナルで次のコマンドを実行します。
python chapter10.pyどこがROCm?
畳み込みは、画像まわりでよく出る代表的な計算です。AMD GPU では MIOpen というたたみこみ専用の高速化エンジンが動いています(名前は覚えなくて大丈夫です)。第3章の行列積と同様に、ROCm の下ではこうした定番の処理を速く走らせるための専用経路が用意されています。
ここで出てきたPython
- kernel_size=3 — キーワード引数を書く
- 4 つの数字を shape として読む
Conv2d の引数の意味(クリックで開く)
Conv2d(1, 2, kernel_size=3, padding=1) の 1 は入力チャネル。2 は出力チャネル。3 はフィルタの大きさ。padding=1 は端に 0 を足して高さ・幅を変えない設定です。
よくあるつまずき
- 入力は 4 次元です。高さと幅だけでなく、枚数とチャネルも入ります。
- in_channels が合わないと止まります。ここでは入力の 2 番目の数字が 1 なので、Conv2d(1, ...) にしています。
- 画像そのものを理解する前に、まず shape の並び順だけ押さえると入りやすいです。
たとえば入力のチャネルが 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)エラーの「expected ... 1 channels, but got 3」が、入力チャネル数と in_channels のずれを教えてくれます。Conv2d(3, 2, ...) に直せば通ります。
1分演習
Conv2d(1, 2, ...) の 2 を 4 に変えて、出力 shape のどこが変わるかを見てみましょう。