Hi! I am using Pytorch to build a convolutional neural network to classify some matrices into four labels. The input is 1644 matrices after one hot encoding. However, my loss almost stay unchanged after many epoches and my accuracy can’t increase as a result. Is there any problems with my model? or my loss function?
Here’s my model:
import os
os.environ[“CUDA_VISIBLE_DEVICES”]=‘0’
import torch
import torch.nn as nn
from torch.autograd import Variable
from torchvision import transforms
from torch.utils.data import Dataset,DataLoader
import matplotlib.pyplot as plt
import numpy as np
from dataConfig import MyDataset
from torchsummary import summary
root = “./”
FILTERS=128
EPOCH = 100
LR = 0.01
BATCH_SIZE = 128
train_data = MyDataset(txt =root+‘train11.txt’,transform = transforms.ToTensor())
#test_data = MyDataset(txt =root+‘test11.txt’,transform = transforms.ToTensor())
train_loader = DataLoader(dataset = train_data,batch_size = BATCH_SIZE, shuffle = True)
#test_Loader = DataLoader(dataset = test_data,batch_size = BATCH_SIZE)
class CNN256(nn.Module):
def init(self):
super(CNN256, self).init()
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels=16, out_channels=FILTERS, kernel_size=(4,1),stride=1, padding=0),
nn.BatchNorm2d(FILTERS),
nn.ReLU(),
nn.MaxPool2d(1) #14128
)
self.conv2 = nn.Sequential(
nn.Conv2d(in_channels=16, out_channels=FILTERS, kernel_size=(1,4), stride=1, padding=0),
nn.BatchNorm2d(FILTERS),
nn.ReLU(),
nn.MaxPool2d(1) #41128
)
self.conv3 = nn.Sequential(
nn.Conv2d(in_channels=16, out_channels=FILTERS, kernel_size=(2,2), stride=1, padding=0),
nn.BatchNorm2d(FILTERS),
nn.ReLU(),
nn.MaxPool2d(1) # outputsize[33128]
)
self.conv4 = nn.Sequential(
nn.Conv2d(in_channels=16, out_channels=FILTERS, kernel_size=(3,3), stride=1, padding=0),
nn.BatchNorm2d(FILTERS),
nn.ReLU(),
nn.MaxPool2d(1) # 22128
)
self.conv5 = nn.Sequential(
nn.Conv2d(in_channels=16, out_channels=FILTERS, kernel_size=(4,4), stride=1, padding=0), #outputsize[11128]
nn.BatchNorm2d(FILTERS),
nn.ReLU(),
nn.MaxPool2d(1)
)
self.fc1 = nn.Linear(2816,512)
self.fc2 = nn.Linear(512,128)
self.fc3 = nn.Linear(128,4)
def forward(self, x):
m = nn.ReLU()
conv41 = self.conv1(x)
conv41 = conv41.view(conv41.size(0), -1)
conv14 = self.conv2(x)
conv14 = conv14.view(conv14.size(0), -1)
conv22 = self.conv3(x)
conv22 = conv22.view(conv22.size(0), -1)
conv33 = self.conv4(x)
conv33 = conv33.view(conv33.size(0), -1)
conv44 = self.conv5(x)
conv44 = conv44.view(conv44.size(0), -1)
hidden=torch.cat((conv41,conv14,conv22,conv33,conv44),1)
fc1 = self.fc1(hidden)
fc1 = m(fc1)
fc2 = self.fc2(fc1)
fc2 = m(fc2)
output = self.fc3(fc2)
return output
cnn = CNN256()
summary(cnn,(16,4,4))
cnn.load_state_dict(torch.load(‘256cnn_params.pkl’))
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss()
for epoch in range(EPOCH):
print(‘epoch{}’.format(epoch+1))
#training--------------------------
train_loss = 0
train_acc = 0
for batch_x, batch_y in train_loader:
batch_x = Variable(batch_x)
batch_y = Variable(batch_y)
output = cnn(batch_x.float())
loss = loss_func(output,batch_y)
train_loss+=loss.item()
pred = torch.max(output,1)[1]
train_correct = (pred == batch_y).sum()
train_acc += train_correct.item()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(‘Train Loss: {:.6f}, Acc:{:.6f}’.format(train_loss/(len(train_data)), train_acc/(len(train_data))))
torch.save(cnn.state_dict(),“256cnn_params.pkl”)
‘’’
cnn.eval()
eval_loss = 0
eval_acc = 0
#evaluation--------------------------------
for batch_x,batch_y in test_Loader:
batch_x = Variable(batch_x)
batch_y = Variable(batch_y)
output = cnn(batch_x.float())
loss = loss_func(output,batch_y)
eval_loss+=loss.item()
pred = torch.max(output,1)[1]
eval_correct = (pred == batch_y).sum()
eval_acc += eval_correct.item()
print('Test Loss: {:.6f}, Acc:{:.6f}'.format(eval_loss/(len(test_data)), eval_acc/(len(test_data))))
‘’’
and here’s my DATASET:
import torch
import numpy as np
from numpy import *
from torch.utils.data import Dataset,DataLoader
root = “./”
map_table = {2**i: i for i in range(1,16)}
map_table[0] = 0
def OneHotEncoder(InputArr):
codearr = np.zeros((4,4,16),dtype=float)
for p in range(0,3):
for q in range(0,3):
codearr[p,q,map_table[InputArr[p,q]]] = 1
return codearr
class MyDataset(torch.utils.data.Dataset):
def init(self,txt, transform=None, target_transform=None):
fh = open(root + txt, ‘r’)
A = zeros((4,4),dtype = float)
imgs = []
lines = fh.readlines()
row = 0
for line in lines:
if(row!=4):
list = line.strip(’\n’).split(’ ‘)
A[row:] = list[0:4]
row = row+1
else:
direction = int(line.strip(’\n’))
row = 0
imgs.append((A,direction))
self.imgs = imgs
self.transform = transform
self.target_transform = target_transform
def __getitem__(self, index):
fn, label = self.imgs[index]
arr = OneHotEncoder(fn)
if self.transform is not None:
arr = self.transform(arr)
return arr,label
def __len__(self):
return len(self.imgs)