Loading...
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
# CNNモデル
class CNNModel(nn.Module):
def __init__(self):
super(CNNModel, self).__init__()
# 第一の畳み込み層 + ReLU + プーリング層
self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 第二の畳み込み層 + ReLU + プーリング層
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, padding=1)
# 全結合層
self.fc1 = nn.Linear(32 * 7 * 7, 128) # 畳み込み後に画像が7x7に縮小
self.fc2 = nn.Linear(128, 2) # 出力クラスが2(猫、非猫)
def forward(self, x):
# 畳み込み + ReLU + プーリング
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
# フラット化
x = x.view(-1, 32 * 7 * 7)
# 全結合層 + ReLU
x = F.relu(self.fc1(x))
# 出力層
x = self.fc2(x)
return x
# データ変換の定義
transform = transforms.Compose([
transforms.Resize((28, 28)), # サイズ変更
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# ここでは ImageFolder でカスタムデータセットのパスを指定します
# ディレクトリは以下のような構成にします。
# dataset/
# ├── cat/
# └── not_cat/
data_dir = './cat_not_cat_dataset/'
train_dataset = ImageFolder(root=data_dir, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
# モデル、損失関数、最適化関数の定義
model = CNNModel()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 学習ループ
num_epochs = 5
for epoch in range(num_epochs):
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
# 順伝播
outputs = model(inputs)
loss = criterion(outputs, labels)
# 逆伝播と重み更新
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch + 1}, Loss: {running_loss / len(train_loader)}')
# モデルの学習が完了しました
print("Training Finished")