NumPyの基本演算で深層学習を学ぶ:+-*/**、比較、sum/mean/max/minaxis

1. なぜまず基本演算を押さえる必要があるのか?



深層学習でやることは結局、

  • 入力/重みを足し合わせる(+
  • 乗算(*、行列積)
  • 非線形関数を適用する(**relusigmoid など)
  • 損失(loss)を計算した後、 その値を 平均(mean したり 合計(sum したりする

という流れに集約されます。

PyTorch のテンソル演算は NumPy の基本演算スタイルをそのまま踏襲 しているため、NumPy で感覚を掴んでおけば、深層学習の数式がずっと見やすくなります。


2. 要素ごとの算術演算:+-*/**

NumPy 配列同士の基本演算は 要素ごと(element‑wise) に動作します。

import numpy as np

x = np.array([1, 2, 3])
y = np.array([10, 20, 30])

print(x + y)   # [11 22 33]
print(x - y)   # [ -9 -18 -27]
print(x * y)   # [10 40 90]
print(y / x)   # [10. 10. 10.]
print(x ** 2)  # [1 4 9]
  • 長さが同じ 1 次元配列同士は要素ごとに演算
  • 2 次元、3 次元配列も同様に同じ位置同士で演算

2.1 スカラーとの演算

スカラー(数値 1 個)との演算も自然に行えます。

x = np.array([1, 2, 3])

print(x + 10)   # [11 12 13]
print(x * 2)    # [2 4 6]
print(x / 2)    # [0.5 1.  1.5]

この「すべての要素に同じ値を足す/掛ける」は、 深層学習で 正規化、スケーリング、バイアス追加 などに頻繁に使われます。

PyTorch のテンソルも同じように動作します。 x_t + y_tx_t * 2x_t ** 2 などの表現はほぼそのまま使用可能です。


3. 比較演算:><>=<===!=



NumPy 配列同士の比較演算を行うと、結果は ブール(Boolean)配列 になります。

import numpy as np

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

print(x > 3)   # [False False False  True  True]
print(x == 2)  # [False  True False False False]

このブール配列は、

  • マスク(mask) として特定の要素を選択したり
  • 条件を満たす要素の個数を数える際に頻繁に使われます。

例:

x = np.array([1, -2, 3, 0, -5, 6])

mask = x > 0
print(mask)          # [ True False  True False False  True]

# 正の数だけ抽出
pos = x[mask]
print(pos)           # [1 3 6]

# 正の数の個数
num_pos = np.sum(mask)   # True を 1、False を 0 として合算
print(num_pos)           # 3

深層学習ではこうした手法で、

  • 予測が正しいサンプルの割合(accuracy)
  • 特定の条件を満たす位置だけを損失(loss)に含める

などを計算します。PyTorch でも同じパターンを使います。


4. 集計関数:np.sumnp.meannp.maxnp.min

4.1 axis を指定しない場合:全体に対して計算

基本形は「配列全体」に対して合計、平均、最大値、最小値を求めます。

import numpy as np

x = np.array([1, 2, 3, 4])

print(np.sum(x))   # 10
print(np.mean(x))  # 2.5
print(np.max(x))   # 4
print(np.min(x))   # 1

2 次元以上の配列でも同様です。

X = np.array([[1, 2, 3],
              [4, 5, 6]])

print(np.sum(X))   # 21
print(np.mean(X))  # 3.5

深層学習で使われる場面は、

  • 全バッチ/全データに対する平均損失値
  • 全データの平均/標準偏差を求めて正規化

などです。


5. axis の概念を理解する

axis は「どの軸を基準に演算するか」を決めるオプションです。

  • axis を指定しない → 全要素に対して計算
  • axis を指定する → その軸に沿って縮約(reduce)し、残りの軸を残す

5.1 2 次元例で見る axis

import numpy as np

X = np.array([[1, 2, 3],
              [4, 5, 6]])  # shape: (2, 3)

axis=0:列方向に計算(行を下に進む)

print(np.sum(X, axis=0))   # [5 7 9]
print(np.mean(X, axis=0))  # [2.5 3.5 4.5]
  • 結果 shape: (3,)
  • 各列(column)に対して合計/平均を計算
  • 深層学習で 各 feature の平均/標準偏差計算 に頻繁に使われます。

axis=1:行方向に計算(列を横に進む)

print(np.sum(X, axis=1))   # [ 6 15]
print(np.mean(X, axis=1))  # [2. 5.]
  • 結果 shape: (2,)
  • 各行(row)に対して合計/平均を計算
  • 深層学習で 各サンプルの合計/平均 計算と結びつきます。

5.2 深層学習でよく見る axis の例

バッチデータが次のようだとします。

# (batch_size, feature_dim)
X = np.random.randn(32, 10)  # 32 個のサンプル、10 次元特徴
  1. 各 feature ごとの平均(feature‑wise mean)
mean_per_feature = np.mean(X, axis=0)  # shape: (10,)
  • axis=0 → バッチ方向に縮約
  • 「各 column の平均」=各 feature の平均
  1. 各サンプルごとの平均(sample‑wise mean)
mean_per_sample = np.mean(X, axis=1)  # shape: (32,)
  • axis=1 → feature方向に縮約
  • 「各 row の平均」=各サンプルベクトルの平均値

5.3 画像バッチで axis を考える

画像バッチを PyTorch スタイル (N, C, H, W) と考えてみます。

NumPy でも同様の配列を作れます。

# N=32, C=3 (RGB), H=W=64
images = np.random.randn(32, 3, 64, 64)

例:

  1. バッチ全体に対するピクセル最大値
global_max = np.max(images)  # スカラー
  1. チャネルごとの平均(RGB チャネルごとに平均)
# axis=(0, 2, 3): バッチ、縦、横方向に縮約し、チャネルだけ残す
channel_mean = np.mean(images, axis=(0, 2, 3))  # shape: (3,)

これは実際に チャネルごとの正規化 を行う際に頻繁に使われるパターンです。


6. 集計関数 + 比較演算:よく使うパターン

6.1 正確度(accuracy)計算

例えば、二値分類で:

import numpy as np

# 予測(logit ではなく 0~1 の確率と仮定)
pred = np.array([0.2, 0.8, 0.9, 0.3])
# 正解ラベル(0 または 1)
target = np.array([0, 1, 1, 0])

# 0.5 を基準に予測クラスを作る
pred_label = (pred > 0.5).astype(np.int32)   # [0 1 1 0]

# 正解は True
correct = (pred_label == target)             # [ True True True True]

accuracy = np.mean(correct)                  # True=1, False=0 で平均
print(accuracy)  # 1.0
  • 比較演算 → ブール配列
  • mean を取ると正確度

PyTorch でもほぼ同じコードで書けます。

6.2 マスクを使った損失計算

loss = np.array([0.1, 0.5, 0.2, 0.9])
mask = np.array([True, False, True, False])

masked_loss = loss[mask]      # [0.1, 0.2]
mean_loss = np.mean(masked_loss)
print(mean_loss)              # 0.15000000000000002

条件を満たす位置だけを損失に含めたいとき、 NumPy + マスク + 集計関数を組み合わせて頻繁に使います。


7. まとめ:今日学んだ基本演算

今回見た内容を整理すると、

  1. 算術演算(+-*/** * 基本的に 要素ごと に演算 * スカラーとの演算も自然に行える
  2. 比較演算(><>=<===!= * 結果は ブール配列 * マスクとして活用 → フィルタリング、個数カウント、正確度計算など
  3. 集計関数(np.sumnp.meannp.maxnp.min * axis を指定しない場合は 全体 に対して計算 * axisどの軸を縮約するか を選択可能
  4. axis の概念 * 2D では axis=0 → 列単位、axis=1 → 行単位 * 深層学習で (batch, feature)(N, C, H, W) 構造で頻繁に使用 * feature‑wise、sample‑wise、channel‑wise の統計計算に不可欠

これらの基本演算に慣れれば、

  • 損失、正確度、統計量などを「数式のように」NumPy/PyTorch コードへ直ちに移行でき、
  • 複雑なテンソル演算もずっと馴染みやすく感じられるようになります。

image