可視化
学習目標: 学習過程とモデルの振る舞いを可視化する方法を学ぶ
学習曲線の可視化
import matplotlib.pyplot as plt
# 学習履歴を記録
history = {'train_loss': [], 'val_loss': [], 'train_acc': [], 'val_acc': []}
for epoch in range(epochs):
train_loss, train_acc = train(...)
val_loss, val_acc = validate(...)
history['train_loss'].append(train_loss)
history['val_loss'].append(val_loss)
history['train_acc'].append(train_acc)
history['val_acc'].append(val_acc)
# 可視化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(history['train_loss'], label='Train')
ax1.plot(history['val_loss'], label='Val')
ax1.set_title('Loss')
ax1.legend()
ax2.plot(history['train_acc'], label='Train')
ax2.plot(history['val_acc'], label='Val')
ax2.set_title('Accuracy')
ax2.legend()
plt.show()
混同行列
from sklearn.metrics import confusion_matrix
import seaborn as sns
# 予測を収集
all_preds, all_labels = [], []
model.eval()
with torch.no_grad():
for data, labels in test_loader:
outputs = model(data)
preds = outputs.argmax(dim=1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())
# 混同行列を作成
cm = confusion_matrix(all_labels, all_preds)
# 可視化
plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.show()
特徴マップの可視化(CNN)
def visualize_feature_maps(model, image, layer_idx=0):
# フックで中間層の出力を取得
activations = []
def hook(module, input, output):
activations.append(output)
# 最初の畳み込み層にフックを登録
handle = list(model.features.children())[layer_idx].register_forward_hook(hook)
# 順伝播
model.eval()
with torch.no_grad():
model(image.unsqueeze(0))
handle.remove()
# 特徴マップを可視化
act = activations[0].squeeze()
fig, axes = plt.subplots(4, 8, figsize=(16, 8))
for i, ax in enumerate(axes.flat):
if i < act.shape[0]:
ax.imshow(act[i].cpu(), cmap='viridis')
ax.axis('off')
plt.show()
TensorBoard
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/experiment_1')
for epoch in range(epochs):
train_loss = train(...)
val_loss = validate(...)
writer.add_scalar('Loss/train', train_loss, epoch)
writer.add_scalar('Loss/val', val_loss, epoch)
writer.close()
# 実行: tensorboard --logdir=runs
理解度チェック
Q. 訓練損失は下がるが検証損失が上がる場合、何が起きている?