Reputation: 1
I have this model for brain tumor detection project. I want to add Grad-Cam, but Most of implantations are in TensorFlow and the ones that are in Pytorch are in known models not customs. I want to apply it on my trained custom model.
Here's my model:
# Define Architecture For CNN_TUMOR Model
class CNN_TUMOR(nn.Module):
# Network Initialisation
def __init__(self, params):
super(CNN_TUMOR, self).__init__()
Cin,Hin,Win = params["shape_in"]
init_f = params["initial_filters"]
num_fc1 = params["num_fc1"]
num_classes = params["num_classes"]
self.dropout_rate = params["dropout_rate"]
# Convolution Layers
self.conv1 = nn.Conv2d(Cin, init_f, kernel_size=3)
h,w=findConv2dOutShape(Hin,Win,self.conv1)
self.conv2 = nn.Conv2d(init_f, 2*init_f, kernel_size=3)
h,w=findConv2dOutShape(h,w,self.conv2)
self.conv3 = nn.Conv2d(2*init_f, 4*init_f, kernel_size=3)
h,w=findConv2dOutShape(h,w,self.conv3)
self.conv4 = nn.Conv2d(4*init_f, 8*init_f, kernel_size=3)
h,w=findConv2dOutShape(h,w,self.conv4)
# compute the flatten size
self.num_flatten=h*w*8*init_f
self.fc1 = nn.Linear(self.num_flatten, num_fc1)
self.fc2 = nn.Linear(num_fc1, num_classes)
def forward(self,X):
# Convolution & Pool Layers
X = F.relu(self.conv1(X));
X = F.max_pool2d(X, 2, 2)
X = F.relu(self.conv2(X))
X = F.max_pool2d(X, 2, 2)
X = F.relu(self.conv3(X))
X = F.max_pool2d(X, 2, 2)
X = F.relu(self.conv4(X))
X = F.max_pool2d(X, 2, 2)
X = X.view(-1, self.num_flatten)
X = F.relu(self.fc1(X))
X = F.dropout(X, self.dropout_rate)
X = self.fc2(X)
return F.log_softmax(X, dim=1)
params_model={
"shape_in": (3,256,256),
"initial_filters": 8,
"num_fc1": 100,
"dropout_rate": 0.25,
"num_classes": 2}
loss_func = nn.NLLLoss(reduction="sum")
opt = optim.Adam(cnn_model.parameters(), lr=3e-4)
lr_scheduler = ReduceLROnPlateau(opt, mode='min',factor=0.5, patience=20,verbose=1)
And the rest of the code
# Function to get the learning rate
def get_lr(opt):
for param_group in opt.param_groups:
return param_group['lr']
# Function to compute the loss value per batch of data
def loss_batch(loss_func, output, target, opt=None):
loss = loss_func(output, target) # get loss
pred = output.argmax(dim=1, keepdim=True) # Get Output Class
metric_b=pred.eq(target.view_as(pred)).sum().item() # get performance metric
if opt is not None:
opt.zero_grad()
loss.backward()
opt.step()
return loss.item(), metric_b
# Compute the loss value & performance metric for the entire dataset (epoch)
def loss_epoch(model,loss_func,dataset_dl,opt=None):
run_loss=0.0
t_metric=0.0
len_data=len(dataset_dl.dataset)
# internal loop over dataset
for xb, yb in dataset_dl:
# move batch to device
xb=xb.to(device)
yb=yb.to(device)
output=model(xb) # get model output
loss_b,metric_b=loss_batch(loss_func, output, yb, opt) # get loss per batch
run_loss+=loss_b # update running loss
if metric_b is not None: # update running metric
t_metric+=metric_b
loss=run_loss/float(len_data) # average loss value
metric=t_metric/float(len_data) # average metric value
return loss, metric
def Train_Val(model, params,verbose=False):
# Get the parameters
epochs=params["epochs"]
loss_func=params["f_loss"]
opt=params["optimiser"]
train_dl=params["train"]
val_dl=params["val"]
lr_scheduler=params["lr_change"]
weight_path=params["weight_path"]
# history of loss values in each epoch
loss_history={"train": [],"val": []}
# histroy of metric values in each epoch
metric_history={"train": [],"val": []}
# a deep copy of weights for the best performing model
best_model_wts = copy.deepcopy(model.state_dict())
# initialize best loss to a large value
best_loss=float('inf')
# Train Model n_epochs (the progress of training by printing the epoch number and the associated learning rate. It can be helpful for debugging, monitoring the learning rate schedule, or gaining insights into the training process.)
for epoch in tqdm(range(epochs)):
# Get the Learning Rate
current_lr=get_lr(opt)
if(verbose):
print('Epoch {}/{}, current lr={}'.format(epoch, epochs - 1, current_lr))
# Train Model Process
model.train()
train_loss, train_metric = loss_epoch(model,loss_func,train_dl,opt)
# collect losses
loss_history["train"].append(train_loss)
metric_history["train"].append(train_metric)
# Evaluate Model Process
model.eval()
with torch.no_grad():
val_loss, val_metric = loss_epoch(model,loss_func,val_dl)
# store best model
if(val_loss < best_loss):
best_loss = val_loss
best_model_wts = copy.deepcopy(model.state_dict())
# store weights into a local file
torch.save(model.state_dict(), weight_path)
if(verbose):
print("Copied best model weights!")
# collect loss and metric for validation dataset
loss_history["val"].append(val_loss)
metric_history["val"].append(val_metric)
# learning rate schedule
lr_scheduler.step(val_loss)
if current_lr != get_lr(opt):
if(verbose):
print("Loading best model weights!")
model.load_state_dict(best_model_wts)
if(verbose):
print(f"train loss: {train_loss:.6f}, dev loss: {val_loss:.6f}, accuracy: {100*val_metric:.2f}")
print("-"*10)
# load best model weights
model.load_state_dict(best_model_wts)
return model, loss_history, metric_history
That's my code, I want to implant Grad-Cam. I'd be more than happy if you guide me.
Upvotes: 0
Views: 361