Hello, I’ve tried to create a CNN that classifies musical genres with GTZAN dataset. So my training loss decrease correctly but when I test my CNN with test data, the accuracy still about 50%-60%.
I tried to put dropout at each layer, change hyper-parameter like batch size, learning rate or number of epoch, and I tried so delete some layer, but accuracy still the same. I’ve no more idea.
I don’t think that overfit…
Thank you in advance.
My Network:
class Net(nn.Module):
def __init__(self):
"""Intitalize neural net layers"""
super(Net, self).__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3, stride=1, padding=0)
self.conv2 = nn.Conv2d(in_channels=8, out_channels=16, kernel_size=3, stride=1, padding=0)
self.conv3 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=0)
self.conv4 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=0)
self.conv5 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=0)
self.conv6 = nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=0)
self.fc1 = nn.Linear(in_features=256, out_features=128)
self.fc2 = nn.Linear(in_features=128, out_features=10)
self.batchnorm1 = nn.BatchNorm2d(num_features=8)
self.batchnorm2 = nn.BatchNorm2d(num_features=16)
self.batchnorm3 = nn.BatchNorm2d(num_features=32)
self.batchnorm4 = nn.BatchNorm2d(num_features=64)
self.batchnorm5 = nn.BatchNorm2d(num_features=128)
self.batchnorm6 = nn.BatchNorm2d(num_features=256)
self.dropout = nn.Dropout(p=0.3, inplace=False)
def forward(self, x):
# Conv layer 1.
x = self.conv1(x)
x = self.batchnorm1(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Conv layer 2.
x = self.conv2(x)
x = self.batchnorm2(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Conv layer 3.
x = self.conv3(x)
x = self.batchnorm3(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Conv layer 4.
x = self.conv4(x)
x = self.batchnorm4(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Conv layer 5.
x = self.conv5(x)
x = self.batchnorm5(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Conv layer 6.
x = self.conv6(x)
x = self.batchnorm6(x)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2)
# Fully connected layer 1.
x = torch.flatten(x, 1)
#x = self.dropout(x)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
My train loop:
model = Net()
# loss function
criterion = nn.CrossEntropyLoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=lr)
#training loop
for epoch in range(num_epochs):
for i, batch in enumerate(train_loader):
#forward
outputs = model(batch)
optimizer.zero_grad()
loss = criterion(outputs, train_label[i])
#backwards
loss.backward()
optimizer.step()
print(f'epoch {epoch + 1} / {num_epochs}, loss = {loss.item():.4f}')
print("End of training")
And my test loop:
with torch.no_grad():
n_correct = 0
n_samples = 0
n_class_correct = [0 for i in range(10)]
n_class_samples = [0 for i in range(10)]
for i, images in enumerate(test_loader):
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
n_samples += test_label[i].size(0)
n_correct += (predicted == test_label[i]).sum().item()
for j in range(batch_size):
label = test_label[i][j]
pred = predicted[j]
if (label == pred):
n_class_correct[label] += 1
n_class_samples[label] += 1
acc = 100.0 * n_correct / n_samples
print(f'Accuracy of the network on the {n_samples} test images: {acc} %')