[f757a9]: / Classifier / Classes / Model.py

Download this file

151 lines (129 with data), 5.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import numpy as np
from sklearn import metrics
from sklearn.metrics import roc_auc_score, accuracy_score
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from Classifier.Classes.Helpers import Helpers
helper = Helpers("Model", False)
class LuekemiaNet(nn.Module):
""" Model Class
Model functions for the Acute Lymphoblastic Leukemia Pytorch CNN 2020.
"""
def __init__(self):
super(LuekemiaNet, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=1, padding=0),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.AdaptiveAvgPool2d(2))
self.conv2 = nn.Sequential(
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.AdaptiveAvgPool2d(2))
self.conv3 = nn.Sequential(
nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.AdaptiveAvgPool2d(2))
self.fc = nn.Sequential(
nn.Linear(128*2*2, 1024),
nn.ReLU(inplace=True),
nn.Dropout(0.2),
nn.Linear(1024, 512),
nn.Dropout(0.2),
nn.Linear(512, 2))
def forward(self, x):
"""Method for Forward Prop"""
out = self.conv1(x)
out = self.conv2(out)
out = self.conv3(out)
######################
# For model debugging #
######################
#print(out.shape)
out = out.view(x.shape[0], -1)
out = self.fc(out)
return out
###################
# Train model #
###################
def learn(model, loss_function, optimizer, epochs, train_loader,
valid_loader, scheduler, train_on_gpu=True):
""" """
trainset_auc = list()
train_losses = list()
valid_losses = list()
val_auc = list()
valid_auc_epoch = list()
train_auc_epoch = list()
for epoch in range(epochs):
train_loss = 0.0
valid_loss = 0.0
model.train_model()
for i, data in enumerate(train_loader):
inputs, labels = data
if train_on_gpu:
inputs, labels = inputs.cuda(), labels.cuda()
# first of all, set gradient of all optimized variables to zero
optimizer.zero_grad()
# forward pass: compute predicted outputs by passing inputs data to the model
outputs = model(inputs)
# compute batch loss(binary cross entropy
loss = loss_function(outputs[:,0], labels.float())
# Update Train loss and accuracies
train_loss += loss.item() * inputs.size(0)
# backward pass: compute gradient of the loss with respect to model parameters
loss.backward()
# perform one step of optimization
optimizer.step()
scheduler.step()
y_actual = labels.data.cpu().numpy()
prediction = outputs[:, 0].detach().cpu().numpy()
trainset_auc.append(roc_auc_score(y_true=y_actual, y_score=prediction))
model.eval()
for _, data in enumerate(valid_loader):
inputs, labels = data
# if CUDA GPU is available
if train_on_gpu:
inputs, labels = inputs.cuda(), labels.cuda()
# first of all, set gradient of all optimized variables to zero
optimizer.zero_grad()
# forward pass: compute predicted outputs by passing inputs data to the model
outputs = model(inputs)
# compute batch loss(binary cross entropy
loss = loss_function(outputs[:,0], labels.float())
# update average validation loss
valid_loss += loss.item() * inputs.size(0)
y_actual = labels.data.cpu().numpy()
predictionx = outputs[:, 0].detach().cpu().numpy()
val_auc.append(roc_auc_score(y_actual, predictionx))
# calculate average losses
train_loss = train_loss / len(train_loader.sampler)
valid_loss = valid_loss / len(valid_loader.sampler)
valid_auc = np.mean(val_auc)
train_auc = np.mean(trainset_auc)
train_auc_epoch.append(np.mean(trainset_auc))
valid_auc_epoch.append(np.mean(val_auc))
train_losses.append(train_loss)
valid_losses.append(valid_loss)
helper.logger.info(
'Epoch: {} | Training Loss: {:.6f} | Training AUC: {:.6f}| Validation Loss: {:.6f} | Validation AUC: {:.4f}'.format(
epoch, train_loss, train_auc, valid_loss, valid_auc))
torch.save(model.state_dict(), helper.config["classifier"]["model_params"]["weights"])
plt.plot(train_losses, label='Training loss')
plt.plot(valid_losses, label='Validation loss')
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend(frameon=False)
plt.savefig(helper.config["classifier"]["model_params"]["plot_loss"])
plt.show()
plt.plot(valid_auc_epoch, label='Validation AUC/Epochs')
plt.plot(train_auc_epoch, label='Training AUC/Epochs')
plt.legend("")
plt.xlabel("Epochs")
plt.ylabel("Area Under the Curve")
plt.legend(frameon=False)
plt.savefig(helper.config["classifier"]["model_params"]["plot_auc"])
plt.show()