I’m trying to implement VGG13 from scratch, but my model just won’t improve, and gives same accuracy for epochs. Can someone look into my code and help me?
class VGG13(nn.Module):
def __init__(self):
super(VGG13, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(64, 64, kernel_size=3, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.conv4 = nn.Conv2d(128, 128, kernel_size=3, padding=1)
self.conv5 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
self.conv6 = nn.Conv2d(256, 256, kernel_size=3, padding=1)
self.conv7 = nn.Conv2d(256, 512, kernel_size=3, padding=1)
self.conv8 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
self.conv9 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
self.conv10 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(512*2*2, 4096)
self.fc2 = nn.Linear(4096, 4096)
self.fc3 = nn.Linear(4096, 3)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.relu(self.conv2(x))
x = self.pool(x)
x = F.relu(self.conv3(x))
x = F.relu(self.conv4(x))
x = self.pool(x)
x = F.relu(self.conv5(x))
x = F.relu(self.conv6(x))
x = self.pool(x)
x = F.relu(self.conv7(x))
x = F.relu(self.conv8(x))
x = self.pool(x)
x = F.relu(self.conv9(x))
x = F.relu(self.conv10(x))
x = self.pool(x)
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
# x = self.drop(x)
x = F.relu(self.fc2(x))
# x = self.drop(x)
x = self.fc3(x)
# return self.soft(x)
return x
vgg = VGG13()
if torch.cuda.is_available():
vgg.to('cuda')
print(vgg)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(vgg.parameters(), lr=1e-2)
This is how I’m trying to analyze the performance :-
import h5py
loss_train = []
accuracy_train = []
loss_val = []
accuracy_val = []
for epoch in range(10):
# Train
vgg.train()
current_loss_train = 0.0
count_train = 0
train_num = 0
for i, data in enumerate(trainloader, 0):
X, y = data
if torch.cuda.is_available():
X = X.to('cuda')
y = y.to('cuda')
optimizer.zero_grad()
pred = vgg(X)
# Loss Calculate
loss = criterion(pred, y.long())
loss.backward()
optimizer.step()
current_loss_train += loss.item()
# Calculate Average Loss and Accuracy
for c in range(len(pred)):
if torch.argmax(pred[c]) == y[c]:
count_train += 1
train_num += len(y)
loss_train.append(float(current_loss_train / len(trainloader)))
accuracy_train.append(count_train * 100.0 / train_num)
# Validate
vgg.eval()
current_loss_val = 0.0
count_val = 0
val_num = 0
with torch.no_grad():
for i, data in enumerate(valloader, 0):
X, y = data
if torch.cuda.is_available():
X = X.to('cuda')
y = y.to('cuda')
pred = vgg(X)
# Loss Calculate
loss = criterion(pred, y.long())
current_loss_val += loss.item()
for c in range(len(pred)):
if torch.argmax(pred[c]) == y[c]: count_val += 1
val_num += len(y)
# Calculate Average Loss and Accuracy
loss_val.append(float(current_loss_val / len(valloader)))
accuracy_val.append(count_val * 100.0 / val_num)
print(f"[{epoch}], Train Loss: {loss_train[epoch]}, Validation Loss: {loss_val[epoch]}")
print(f"[{epoch}], Train Accuracy: {accuracy_train[epoch]}, Validation Accuracy: {accuracy_val[epoch]}")
if(epoch > 0):
if(loss_val[epoch] < loss_val[(epoch-1)] and loss_val[epoch] <= min(loss_val)):
print("Saving Best Model yet...")
torch.save(vgg.state_dict(), './best_ILSVRC_model.pth')
with h5py.File("./best_ILSVRC_model.h5","w") as file:
for i,j in vgg.named_parameters():
file.create_dataset(i,data=j.cpu().data.numpy())
else:
print(f"(Current Loss) :- {loss_val[epoch]} > (Previous Loss) :- {loss_val[(epoch - 1)]}")
print("Validation Loss didn't improve, decreasing learning rate...")
for g in optimizer.param_groups:
g['lr'] /= 10.0
# break
The inputs for this model is a dataset of 30,000 images of dimensions [3, 64, 64] and three classes each having 10,000 images