1. なぜ形状を変えるのか
NumPy配列は「要素は同じまま、見え方(shape)を変える」操作を頻繁に行います。 なぜそんな操作が必要なのか、代表的なシーンを挙げてみます。
- 画像→ベクトル化:28×28 のグレースケール画像を 784次元の1次元ベクトルにしてAIモデルに入力する
- 軸の並び替え:画像の
(高さ, 幅, チャンネル)↔(チャンネル, 高さ, 幅)の変換 - バッチ次元追加:単一画像
(H, W)をモデル入力用に(1, H, W)に拡張する - 行列演算の準備:行ベクトル ↔ 列ベクトル変換
これらすべてが NumPy の 形状変形 操作で実現できます。 形状を変えても要素の中身(値)は変わらないのがポイントです。
2. reshape — 要素数を保って形を変える
reshape(新しいshape) は、配列の中身を変えずに形だけを変更します。
変形前後の要素数が同じであることが条件です(合わないとエラー)。
-1 を渡すと、その軸のサイズを NumPyが自動で計算してくれます。
「全部を1次元にしたい」「行数だけ指定して列数は任せたい」ときに便利です。
⚠ 要素数が合わないとエラー:
12要素の配列を (3, 5)(=15要素)に変形しようとすると ValueError になります。
変形前後の shape の積(=要素数)が一致することが必須です。
💡 -1 は1箇所まで:
reshape(-1, -1) のように -1 を複数指定するとエラーになります。
「ここはNumPyに自動計算してほしい」軸は1箇所だけにしましょう。
3. flatten / ravel — 多次元を1次元に
多次元配列を1次元に潰す専用メソッドが2つあります。
flatten() と ravel() です。
結果はほぼ同じに見えますが、「コピーか、ビューか」が違います。
| 戻り値 | 元の配列への影響 | 使い分け | |
|---|---|---|---|
flatten() | コピー | 変わらない(安全) | 元を保持したいとき・迷ったらこちら |
ravel() | ビュー(条件次第) | 変わる可能性あり | メモリ節約・読み取り専用 |
reshape(-1) | ビュー | 変わる可能性あり | 形状指定のついで |
🤖 AI用語メモ — 「画像をベクトル化する」とは?
画像認識の代表的なデータセット MNIST(手書き数字)は 28×28 のグレースケール画像です。
全結合層と呼ばれるシンプルなAIモデルに入れるときは、これを 784(= 28×28)要素の1次元ベクトルに変換します。
この変換が img.flatten() の正体です(このコースでは詳細は扱いません)。
4. transpose — 軸を入れ替える
transpose(または .T プロパティ)は、配列の軸の順序を入れ替えます。
2次元なら「行と列を入れ替える」、3次元以上では「軸の並び順を任意に指定」できます。
💡 .T と transpose の使い分け:
.T:2次元の行列を転置するときの省略形(軸の順序を完全に逆にする)transpose(2, 0, 1):「元の軸2を新しい軸0、元の軸0を新しい軸1、元の軸1を新しい軸2」と並べ替え
🩺 医療AI文脈:
医療画像のフォーマット問題でよく遭遇します。OpenCVや一般的な画像ライブラリは (H, W, C)(高さ・幅・チャンネル)の順、
PyTorchの画像モデルは (C, H, W)(チャンネル・高さ・幅)の順を要求します。
この変換に img.transpose(2, 0, 1) が頻出します。
5. newaxis / expand_dims — 次元を追加する
「形そのものは保ちつつ、次元数だけ増やしたい」場合に使うのが
np.newaxis と np.expand_dims です。
どちらも同じことができますが、書き方が違います。
🤖 AI用語メモ — 「バッチ次元」とは?
AIモデルは 複数のサンプルをまとめて処理するのが普通で、これを「ミニバッチ処理」と呼びます。
このため、モデルが期待する入力は常に 「先頭にバッチ数の軸がある」形(例: (バッチ数, H, W))になっています。
1枚の画像だけ予測したいときも、形を (1, H, W) に整える必要があり、その操作で np.newaxis や expand_dims が使われます。
💡 newaxis と expand_dims の使い分け:
arr[np.newaxis, :]:スライス記法と一緒に書ける。簡潔で実コードでよく見るnp.expand_dims(arr, axis=N):軸を数字で明示。挿入位置を変数で渡したいときに便利
どちらも結果は同じです。読みやすい方を使えばOK。
6. 練習問題
画像をベクトル化しよう
28×28 のダミー画像 img = np.arange(784).reshape(28, 28) を、
1次元ベクトル(784要素) に変換してください。
flatten・reshape(-1) どちらでもOKです。
ヒントを見る(答え+解説)
import numpy as np
img = np.arange(784).reshape(28, 28)
print("元 shape:", img.shape)
# 1次元ベクトル(784要素)に変換してください
v = img.flatten()
# または: v = img.reshape(-1)
# または: v = img.reshape(784)
print("変換後 shape:", v.shape) # (784,)
print("先頭10件:", v[:10])
flatten() は最も読みやすく、コピーを返すため安全。reshape(-1) も同じ結果になります(こちらはビュー)。「画像→ベクトル」変換はAIモデルの入力前処理で頻出のパターンです。
画像のチャンネル順を変換しよう
shape (高さ=8, 幅=10, チャンネル=3) のダミーカラー画像を、
(チャンネル=3, 高さ=8, 幅=10) に並び替えてください。transpose を使います。
ヒントを見る(答え+解説)
import numpy as np
img_hwc = np.zeros((8, 10, 3))
print("元 shape:", img_hwc.shape) # (8, 10, 3)
# (C, H, W) = (3, 8, 10) に並び替えてください
img_chw = img_hwc.transpose(2, 0, 1)
print("変換後 shape:", img_chw.shape) # (3, 8, 10)
transpose(2, 0, 1) は「元の軸2(チャンネル)を新しい軸0、元の軸0(高さ)を新しい軸1、元の軸1(幅)を新しい軸2」と並び替える指定です。PyTorchやTensorFlowの画像モデルでよく必要な変換です。
バッチ次元を追加しよう
shape (28, 28) の1枚の画像 img を、
AIモデルに入力できるように shape (1, 28, 28) に変換してください。
np.newaxis または np.expand_dims を使います。
ヒントを見る(答え+解説)
import numpy as np
img = np.zeros((28, 28))
print("元 shape:", img.shape)
# 先頭にバッチ次元を追加してください: (28, 28) → (1, 28, 28)
img_batch = img[np.newaxis, :, :]
# または: img_batch = np.expand_dims(img, axis=0)
# または: img_batch = img.reshape(1, 28, 28)
print("バッチ次元追加後 shape:", img_batch.shape) # (1, 28, 28)
3つとも結果は同じです。1枚の画像をAIモデルで予測したいときに、モデルが期待する shape (バッチ数, H, W) に整えるための定番操作です。
7. まとめ
このレッスンのポイント
reshape(新shape):要素数を保って形を変更(-1で自動計算)flatten():1次元化・コピーを返す(安全)/ravel():1次元化・ビューを返す(高速).T/transpose(順序):軸の入れ替え。(H,W,C) ↔ (C,H,W) で頻出np.newaxis/expand_dims:次元を追加。バッチ次元の追加で必須- 形状を変えても 要素の中身(値)は変わらない
自由に試してみましょう:
完了するとコース一覧に進捗が記録されます