演習問題
学習目標: 実際にコードを書いて、ディープラーニングのスキルを定着させる
演習1: シンプルな分類器
課題
以下の要件を満たすニューラルネットワークを実装してください:
- 入力サイズ: 20特徴量
- 隠れ層: 2つ(64, 32ユニット)
- 出力: 3クラス分類
- 活性化関数: ReLU
nn.Sequentialを使うと簡潔に書けます。
class SimpleClassifier(nn.Module):
def __init__(self):
super().__init__()
self.network = nn.Sequential(
nn.Linear(20, 64),
nn.ReLU(),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 3)
)
def forward(self, x):
return self.network(x)
演習2: CNN for CIFAR-10
課題
CIFAR-10(32×32 RGB画像)を分類するCNNを実装してください:
- 畳み込み層を3つ以上
- BatchNormalizationを使用
- Dropoutで正則化
class CIFAR10CNN(nn.Module):
def __init__(self):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Dropout(0.25),
nn.Conv2d(32, 64, 3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Dropout(0.25),
nn.Conv2d(64, 128, 3, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.MaxPool2d(2, 2),
)
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(128 * 4 * 4, 256),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(256, 10)
)
def forward(self, x):
x = self.features(x)
x = self.classifier(x)
return x
演習3: 学習ループの実装
課題
以下の機能を持つ学習関数を実装してください:
- 訓練ループと検証ループ
- 損失と精度の記録
- 早期終了(patience=5)
- 最良モデルの保存
def train_with_early_stopping(model, train_loader, val_loader, epochs=100, patience=5):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
best_val_loss = float('inf')
patience_counter = 0
history = {'train_loss': [], 'val_loss': [], 'val_acc': []}
for epoch in range(epochs):
# Training
model.train()
train_loss = 0
for data, target in train_loader:
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
train_loss += loss.item()
# Validation
model.eval()
val_loss = 0
correct = 0
with torch.no_grad():
for data, target in val_loader:
data, target = data.to(device), target.to(device)
output = model(data)
val_loss += criterion(output, target).item()
pred = output.argmax(dim=1)
correct += pred.eq(target).sum().item()
train_loss /= len(train_loader)
val_loss /= len(val_loader)
val_acc = correct / len(val_loader.dataset)
history['train_loss'].append(train_loss)
history['val_loss'].append(val_loss)
history['val_acc'].append(val_acc)
print(f"Epoch {epoch+1}: Train Loss={train_loss:.4f}, Val Loss={val_loss:.4f}, Val Acc={val_acc:.4f}")
# Early stopping
if val_loss < best_val_loss:
best_val_loss = val_loss
patience_counter = 0
torch.save(model.state_dict(), 'best_model.pth')
else:
patience_counter += 1
if patience_counter >= patience:
print(f"Early stopping at epoch {epoch+1}")
break
return history
チャレンジ課題
上級者向け
課題: 転移学習を使ってCIFAR-10で95%以上の精度を達成してください。
- 事前学習済みResNet18を使用
- Fine-tuningを適切に行う
- データ拡張を活用
おめでとうございます! ディープラーニングモジュールの学習を完了しました。次は「AIパズル」でインタラクティブに学習しましょう!