Как улучшить производительность модели CNN для классификации изображений в PyTorch?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как улучшить производительность модели CNN для классификации изображений в PyTorch?

Сообщение Anonymous »

Я работаю над проектом классификации изображений с использованием PyTorch и реализовал модель сверточной нейронной сети (CNN). Хотя модель функциональна, я ищу способы улучшить ее производительность, особенно с точки зрения точности проверки и обобщения на новые данные. Как я могу улучшить этот код? Буду очень признателен, если вы мне поможете.
# Improved Model Definition with Batch Normalization and Additional Layers
class ImprovedCNNModel(nn.Module):
def __init__(self, num_classes):
super(ImprovedCNNModel, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.bn1 = nn.BatchNorm2d(32)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.bn2 = nn.BatchNorm2d(64)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.bn3 = nn.BatchNorm2d(128)
self.conv4 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
self.bn4 = nn.BatchNorm2d(256)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(256 * 8 * 8, 512)
self.fc2 = nn.Linear(512, num_classes)
self.dropout = nn.Dropout(0.5)

def forward(self, x):
x = torch.relu(self.bn1(self.conv1(x)))
x = self.pool(x)
x = torch.relu(self.bn2(self.conv2(x)))
x = self.pool(x)
x = torch.relu(self.bn3(self.conv3(x)))
x = self.pool(x)
x = torch.relu(self.bn4(self.conv4(x)))
x = self.pool(x)
x = x.view(-1, 256 * 8 * 8)
x = torch.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x

# Initialize the model, loss function, optimizer, and scheduler
num_classes = len(label_encoder.classes_)
model = ImprovedCNNModel(num_classes)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)

# Training and validation loop with early stopping
epochs = 50 # Number of epochs
best_val_acc = 0.0
patience = 5 # Number of epochs to wait for improvement
counter = 0 # Counter for early stopping

# Define the device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Move the model to the device
model.to(device)

for epoch in range(epochs):
# Training phase
model.train()
train_loss = 0.0
correct = 0
total = 0

for images, labels in train_loader:
# Move data to the device (e.g., GPU if available)
images, labels = images.to(device), labels.to(device)

# Zero the parameter gradients
optimizer.zero_grad()

# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)

# Backward pass and optimize
loss.backward()
optimizer.step()

train_loss += loss.item()
_, preds = torch.max(outputs, 1)
correct += (preds == labels).sum().item()
total += labels.size(0)

train_acc = correct / total
print(f"Epoch {epoch + 1}/{epochs}, Train Loss: {train_loss/len(train_loader):.4f}, Train Accuracy: {train_acc:.4f}")

# Validation phase
model.eval()
val_loss = 0.0
correct = 0
total = 0

with torch.no_grad():
for images, labels in val_loader:
images, labels = images.to(device), labels.to(device)

# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)
val_loss += loss.item()

_, preds = torch.max(outputs, 1)
correct += (preds == labels).sum().item()
total += labels.size(0)

val_acc = correct / total
print(f"Epoch {epoch + 1}/{epochs}, Validation Loss: {val_loss/len(val_loader):.4f}, Validation Accuracy: {val_acc:.4f}")

# Check for improvement and early stopping
if val_acc > best_val_acc:
best_val_acc = val_acc
counter = 0 # Reset counter if validation accuracy improves
torch.save(model.state_dict(), os.path.join('/kaggle/working', "best_model.pth"))
print(f"Model saved at epoch {epoch + 1}")
else:
counter += 1

if counter >= patience:
print(f"Early stopping at epoch {epoch + 1}")
break

# Step the scheduler
scheduler.step()

# Test Dataset
class TestDataset(Dataset):
def __init__(self, dataframe, directory, transform=None):
self.dataframe = dataframe
self.directory = directory
self.transform = transform

def __len__(self):
return len(self.dataframe)

def __getitem__(self, idx):
img_name = os.path.join(self.directory, "test/test", self.dataframe.iloc[idx]['filename'])
image = Image.open(img_name).convert("RGB")
if self.transform:
image = self.transform(image)
return image


Подробнее здесь: https://stackoverflow.com/questions/792 ... in-pytorch
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»