Hi, I am using transfer learning to classify histological breast cancer images with VGG16 pre-trained. I have 7900 images y I separated in train, val and test. I have made a custom dataset to read the images and edit the train model function from https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html
My accuracy in train and val doesn´t change and I don´t know why, can you please chek it out, than you. Also, my loss it´s so high!
I´m pretty new in this
The code I use is here:
class BreakHistDataset(Dataset):
def __init__(self, csv_file, root_dir,transform=None):
self.df = pd.read_csv(csv_file)
self.root_dir = root_dir
self.transform = transform
def __len__(self):
return len(self.df)
def __getitem__(self, idx):
img_name = os.path.join(self.root_dir,self.df.iloc[idx, 3])
image = io.imread(img_name)
labels = self.df.iloc[idx, 4]
if self.transform:
image = self.transform(image)
return image,labels
transforme_train = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.7890, 0.6167, 0.7618],[0.1047, 0.1388, 0.0894])])
transforme_val = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.7890, 0.6167, 0.7618],[0.1047, 0.1388, 0.0894])])
transforme_test = transforms.Compose([
transforms.ToPILImage(),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.7890, 0.6167, 0.7618],[0.1047, 0.1388, 0.0894])])
bh_dataset_train = BreakHistDataset(csv_file='/content/gdrive2/My Drive/breakhis/train1.csv',root_dir='/content/gdrive2/My Drive/breakhis/BreaKHis_v1', transform = transforme_train)
bh_dataset_val = BreakHistDataset(csv_file='/content/gdrive2/My Drive/breakhis/val.csv',root_dir='/content/gdrive2/My Drive/breakhis/BreaKHis_v1', transform = transforme_val)
bh_dataset_test = BreakHistDataset(csv_file='/content/gdrive2/My Drive/breakhis/test.csv',root_dir='/content/gdrive2/My Drive/breakhis/BreaKHis_v1', transform = transforme_test)
train_loader = DataLoader(bh_dataset_train, batch_size=32,shuffle=True)
val_loader = DataLoader(bh_dataset_val, batch_size=32,shuffle=True)
test_loader = DataLoader(bh_dataset_test, batch_size=32,shuffle=True)
use_gpu = torch.cuda.is_available()
def train_model(model, criterion, optimizer, scheduler, num_epochs=10):
since = time.time()
best_model_wts = model.state_dict()
best_acc = 0.0
p_epoch = tqdm(range(num_epochs))
for epoch in p_epoch:
print('Epoch {}/{}'.format(epoch, num_epochs - 1))
print('-' * 10)
loss_train = 0.0
corrects_train = 0
loss_val = 0.0
corrects_val = 0
w = []
l = []
for img, labels in tqdm(train_loader):
if use_gpu:
img = img.cuda()
labels = labels.cuda()
else:
img, labels = img, labels
model.train(True)
optimizer.zero_grad()
outputs = model(img)
_, preds = torch.max(outputs.data, 1)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
scheduler.step()
loss_train += loss
l.append(loss_train)
corrects_train += (preds == labels.data).sum().item()
epoch_loss = loss_train / len(train_loader)
epoch_acc = corrects_train / len(train_loader)
w.append(epoch_acc)
plt.title('Loss vs Epocas')
plt.xlabel('Epocas')
plt.ylabel('Loss')
plt.plot(l,label = 'loss train')
plt.plot(figsize=(20, 10))
plt.legend()
print('{} Loss: {:.4f} Acc: {:.4f} RunCorr: {:.4f}'.format('train', epoch_loss,
epoch_acc,corrects_train))
r = []
m = []
for img, labels in tqdm(val_loader):
if use_gpu:
img = img.cuda()
labels = labels.cuda()
else:
img, labels = img, labels
model.train(False)
optimizer.zero_grad()
outputs = model(img)
_, preds = torch.max(outputs.data, 1)
loss = criterion(outputs, labels)
loss_val += loss
r.append(loss_val)
corrects_val += (preds == labels.data).sum().item()
epoch_loss_val = loss_val / len(val_loader)
epoch_acc_val = corrects_val / len(val_loader)
m.append( epoch_acc_val)
print('{} Loss: {:.4f} Acc: {:.4f}'.format('val', epoch_loss_val, epoch_acc_val))
if epoch_acc_val > best_acc:
best_acc = epoch_acc_val
best_model_wts = model.state_dict()
time_elapsed = time.time() - since
print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
print('Best val Acc: {:4f}'.format(best_acc))
# load best model weights
model.load_state_dict(best_model_wts)
return model
num_classes = 8
model_conv = torchvision.models.vgg16(pretrained=True)
for param in model_conv.parameters():
param.requires_grad = False
num_features = model_conv.classifier[6].in_features
features = list(model_conv.classifier.children())[:-1] # Remove last layer
features.extend([nn.Linear(num_features, num_classes)])# Add our layer with 4 outputs
model_conv.classifier = nn.Sequential(*features) # Replace the model classifier
print(model_conv)
if use_gpu:
model_conv = model_conv.cuda()
criterion = nn.CrossEntropyLoss()
optimizer_conv = optim.Adam(model_conv.classifier.parameters(), lr=0.0001,betas = [0.9,
0.999])
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1)
model_conv = train_model(model_conv ,criterion, optimizer_conv,exp_lr_scheduler )
Results for all the epochs
train Loss: 1.6865 Acc: 14.3810
val Loss: 1.6122 Acc: 15.5312