カテゴリ:中級者向け / 過学習対策 / 画像分類
1. Mixupとは?
Mixup(ミックスアップ)は、2枚の画像とそのラベルを線形に合成して新たな学習データを作るシンプルなデータ拡張手法です。2018年に発表されて以来、ImageNetやCIFARなど様々なデータセットで有効性が報告されています。
目的:
- 過学習を防ぐ
- モデルのロバスト性(ノイズ耐性)を向上させる
- クラス間の境界をなめらかに学習する
2. Mixupの原理
2枚の画像 $x_i$, $x_j$ と、それぞれのラベル $y_i$, $y_j$ を以下の式で混合します:
x' = λ * x_i + (1 - λ) * x_j
y' = λ * y_i + (1 - λ) * y_j
ここで、$λ$(ラムダ)は [0,1] の範囲の実数で、通常は Beta分布(α, α) に従ってランダムにサンプリングされます。
このようにして「曖昧な画像と曖昧なラベル」のセットを大量に作り、モデルに柔軟な学習をさせます。
【GoogleColabにてすぐ実行可能なコード例】
# Mixup 実装例(Google Colab で ImageNet‑1k サイズの画像を使って可視化)
# ---------------------------------------------------------
# ▼ 使い方
# 1. Colab にこのセルを貼り付けて Shift+Enter で実行。
# 2. Mixup 後の合成画像を Matplotlib で表示します。
#
# ※ ネットワークの都合で画像が取得できない場合は、URL を手元の画像に差し替えてください。
# --- 必要ライブラリのインストール ---
!pip -q install torchvision requests pillow
# --- インポート ---
import torch, requests, io, numpy as np
import torchvision.transforms as T
import matplotlib.pyplot as plt
from PIL import Image
# --- Mixup 関数定義 ---
def mixup_data(x, y, cnt, alpha=0.4):
#lam = np.random.beta(alpha, alpha)
lam = 0.2 * cnt
batch_size = x.size(0)
index = torch.randperm(batch_size)
mixed_x = lam * x + (1 - lam) * x[index]
y_a, y_b = y, y[index]
return mixed_x, y_a, y_b, lam
# --- one‑hot 生成ヘルパー ---
def to_onehot(idx, num_classes=1000):
y = torch.zeros(num_classes)
y[idx] = 1.0
return y
# --- 224×224 サイズで取得可能な画像 URL ---
urls = [
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_2924_3-scaled.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2024/10/IMG_1974_2-2.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_2536.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_2537.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_2924_3-1-scaled.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_2535_2.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/IMG_1762.jpg",
"https://chatterboxvr.com/wordpress/wp-content/uploads/2025/07/image_123650291-1.jpg",
]
# 変換パイプライン
transform = T.Compose([
T.Resize((224, 224)),
T.ToTensor()
])
images, labels = [], []
for i, url in enumerate(urls):
try:
r = requests.get(url, timeout=10)
r.raise_for_status()
img = Image.open(io.BytesIO(r.content)).convert("RGB")
images.append(transform(img))
labels.append(to_onehot(i % 1000)) # ダミー one‑hot
except Exception as e:
print(f"[Warning] 画像取得失敗: {url} → {e}")
# バッチテンソル化
images = torch.stack(images) # (B,3,224,224)
labels = torch.stack(labels) # (B,1000)
print(f"Downloaded {images.size(0)} images for mixup demo.")
# --- Mixup 実行 ---
mixed_images, y_a, y_b, lam = mixup_data(images, labels, alpha=0.4)
# --- 可視化 ---
fig, axs = plt.subplots(1, 4, figsize=(12, 3))
for i in range(4):
img_np = mixed_images[i].permute(1, 2, 0).numpy()
axs[i].imshow(img_np)
axs[i].set_title(f"λ={lam:.2f}")
axs[i].axis("off")
plt.suptitle("Mixup sample(ImageNet 224×224)")
plt.show()
【出力結果】2枚の画像が重なって見える。これがMixup

4. 使用時の注意点
- Loss関数は通常、ラベルがone-hotであることを想定しています。Mixupではラベルが連続値になるため、
CrossEntropyLoss
の代わりにKLDivLoss
やBCEWithLogitsLoss
を使う必要があります。 - テスト時はMixupしない(純粋な画像で予測)
5. 他のデータ拡張との比較・併用
手法 | 特徴 |
---|---|
Cutout | 一部をランダムに隠す |
CutMix | 一部を他の画像と貼り替える |
Mixup | 画像全体を線形合成(なめらか) |
Mixupはシンプルで実装しやすく、特に少量データのタスクやラベルノイズの多いタスクで真価を発揮します。
まとめ
Mixupは、わずか数行のコード追加で過学習を防ぎ、モデルの汎化性能を高める便利なテクニックです。実務のプロジェクトでも、まずは alpha=0.2〜0.4
あたりから試してみると良いでしょう。