← Python and ROCm 教室へ戻る

第2章

数字を表として持ちたい

ここでは NumPy を使って、数字の並びを「表」として見る感覚を作ります。

今日は何をしたい?

AI や GPU の話では、数字は 1 個ずつよりも「まとまった表」で出てくることが多いです。まずは NumPy 配列を作って、shape を「表の大きさ」として読めるようにします。

なぜ Python リストではなく NumPy を使うの?(クリックで開く)

Python にはもともとリスト([[1,2,3],[4,5,6]])という書き方があります。しかし「表の大きさを一発で調べる」「GPU にデータを送る」「行列の足し算・掛け算を一度に計算する」といった操作はリストが苦手です。NumPy はこれらを得意とする専用ライブラリで、shape・dtype(数字の型)をひとまとめに管理できます。次章以降で使う PyTorch テンソルも、この shape と dtype の考え方をそのまま引き継いでいます。

確認コード

コードを見る前に — as np と dtype の意味(クリックで開く)
  • import numpy as npas np は「numpy を np という短縮名で使う」宣言です。np は世界中のコードで使われる慣習なので、自分で書くときも np にしておくと他の人のコードと読み合わせやすくなります。
  • dtype=np.float32 は「小数を 32 ビットで持つ型」の指定です。NumPy のデフォルトは 64 ビット(float64)ですが、GPU はメモリが有限で float32 を基本として最適化されているため、ROCm/GPU を使うコードでは最初から float32 を指定する習慣をつけておきます。
import numpy as np

x = np.array([[1, 2, 3],
              [4, 5, 6]], dtype=np.float32)

print("x:")
print(x)

print("shape:", x.shape)
print("dtype:", x.dtype)
print("rows:", x.shape[0])
print("cols:", x.shape[1])

このコードを chapter02.py として保存して、python chapter02.py と実行します。

この例では、2 行 3 列の表を 1 つのまとまりとして持っています。(2, 3) と見えたら、「2 行 3 列」と読めば大丈夫です。

shape = (2, 3) 2行 × 3列の表

下の図は見た目の補助です。数学の記号が分からなくても大丈夫です。「2行3列の表」として眺めるだけで十分です。

$$\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}$$

実行するとこう出ます

x: [[1. 2. 3.] [4. 5. 6.]] shape: (2, 3) dtype: float32 rows: 2 cols: 3
shape: (2, 3) が読めれば、この章の目標はほぼ達成です。行が先、列が後 — 数学の「m 行 n 列」と同じ順番です。
出力の読み方をもっとくわしく(クリックで開く)
  • shape: (2, 3) は「2 行 3 列」です。行(横の並び)が先、列(縦の並び)が後という順は数学の行列の書き方(「m 行 n 列行列」)からきています。
  • 数字が 1. 2. のように小数点付きで出るのは、dtype=float32 を指定したため整数が小数に変換されたからです。エラーではありません。
  • dtype: float32 はこのデータが GPU に送れる形であることを示しています。float64 だと GPU での処理速度が落ちたり、一部の操作が使えなくなる場合があります。
  • rowscols を別で出すと、行列の向きで混乱しにくくなります。

どこがROCm?

この章のコードは CPU 側ですが、ここで作る「shape を読む習慣」がそのまま PyTorch と GPU の章につながります。ROCm でも、まずは何行何列なのかを読めることが大事です。

第1章で確認した GPU は、次の章以降で「この形のデータをどう計算するか」に使います。つまり第2章は、GPU計算の前に必要な土台です。

NumPy → PyTorch テンソルへの橋渡し(クリックで開く)

次章から登場する PyTorch の「テンソル」は、NumPy 配列と非常によく似た構造です。x.shape で大きさを読む・dtype で型を管理する、という考え方はそのまま使えます。NumPy との大きな違いは「GPU に置ける」「自動微分(AI の学習に必要な計算)ができる」の2点だけです。この章で shape と dtype の読み方を身につけておけば、テンソルに移ったときに新しく覚えることが格段に減ります。

float32 と ROCm の関係(クリックで開く)

GPU のメモリは CPU より少なく、float32 は float64 の半分のサイズです。ROCm/AMD GPU は float32 演算を前提として最適化されており、AI モデルのほとんどが float32 または それより小さい型を使います。この章から float32 を使っているのは、その習慣を最初から身につけるためです。

ここで出てきたPython

もう少しくわしく(クリックで開く)
  • import numpy as np は「NumPy を np という短い名前で使う」宣言です。以降のコードで np.array() と書けるのは、この宣言があるからです。
  • 入れ子の [] で表の形を作ります(1行が1つの [])。
  • x.shape が返す (2, 3) は「タプル」という型です。リストに似ていますが変更できません。[0] で先頭の値(行数)、[1] で次の値(列数)を取り出せるのはリストと同じ書き方です。

うまくいかなかったら

結果パターン別の次の一手(クリックで開く)
  • パターンA: shape: (2, 3) と出た → この章はクリア。次章へ進んでOK。
  • パターンB: ModuleNotFoundError: No module named numpy → numpy未導入。pip install numpy 後に再実行。
  • パターンC: shape が想定と違う → よくある原因は2つです。① 行ごとの要素数がそろっていない(例: [[1,2,3],[4,5]] のように行によって列数が違う)、② 外側の [] を忘れて1次元になってしまった(例: np.array([1,2,3,4,5,6]) は shape が (6,) になる)。
  • パターンD: 実行はできたが意味が曖昧 → rowscols を必ず表示して確認します。

よくあるつまずき

dtype を指定しなかったときの注意(クリックで開く)

dtype を指定しないと NumPy のデフォルト(float64)になります。GPU を使うときは float32 を明示する習慣をつけましょう。

1分演習

次の順で試します。1) コードを見て shape実行前に予想 する。2) 実行して答え合わせする。3) rows/cols を print して確認する。

import numpy as np

y = np.array([[10, 20],
              [30, 40],
              [50, 60]], dtype=np.float32)
print("shape:", y.shape)

予想できたら実行して確かめましょう。
— 答えは実行結果で確認してください。ここを迷わず読めれば、第2章の到達目標は達成です。