<jupyter_start><jupyter_text>Model Building  Depth of network = 4<jupyter_code>def cont_conv_block(in_channel, out_channel):
    return nn.Sequential(
        nn.Conv2d(in_channel, out_channel, 3, padding=1),
        nn.ReLU(inplace=True),
        nn.Conv2d(out_channel, out_channel, 3, padding=1),
        nn.ReLU(inplace=True)
                        )

def cont_conv(in_channel, path_depth):
    contractive_layers = nn.ModuleList()
    contractive_layers.append(cont_conv_block(in_channel, 64))
    contractive_layers.append(nn.MaxPool2d(2, stride=2))
    in_channel = 64
    for i in range(1, path_depth):
        contractive_layers.append(cont_conv_block((2**(i-1))*in_channel, (2**(i))*in_channel))
        contractive_layers.append(nn.MaxPool2d(2, stride=2))
        
    return contractive_layers[:-1]

def exp_conv(path_depth):
    expansive_layers = nn.ModuleList()
    in_channel = 256
    for i in range(1, path_depth):
#         print(in_channel, i, int(2**-(i-1)*in_channel), int(2**-(i)*in_channel))
        expansive_layers.append(nn.ConvTranspose2d(int(2**-(i-1)*in_channel), int(2**-(i)*in_channel), 2, 2))
        expansive_layers.append(cont_conv_block(int(2**-(i-1)*in_channel), int(2**-(i)*in_channel)))
        
    return expansive_layers

class MRI_UNet(nn.Module):
    def __init__(self):
        super(MRI_UNet, self).__init__()
        self.cont_path = cont_conv(4,3)
        self.exp_path = exp_conv(3)
        self.last_layer = nn.Conv2d(64, 5, 1) # 5 output layers instead of 4
                                              # This is because I differentiated 
                                              # the background and the brain without any tumour
        
    def forward(self, inp_image):
        # Contractive path / down path
#         print('inp: ',inp_image.shape)
        d1 = self.cont_path[0](inp_image)
#         print('d1: ',d1.shape)
        dm1 = self.cont_path[1](d1)
#         print('dm1: ',dm1.shape)
        d2 = self.cont_path[2](dm1)
#         print('d2: ',d2.shape)
        dm2 = self.cont_path[3](d2)
#         print('dm2: ',dm2.shape)
        d3 = self.cont_path[4](dm2)
#         print(d2.shape)

        # Expansive path / up path
        u1 = self.exp_path[0](d3)
#         print('u1: ',u1.shape)
#         u1 = self.exp_path[1](torch.cat([cropped_feature(d2, u1), u1], 1))
        u1 = self.exp_path[1](torch.cat([d2, u1], 1))
#         print('u1_after_cat: ',u1.shape)
        u2 = self.exp_path[2](u1)
#         print('u2: ',u2.shape)
#         u2 = self.exp_path[3](torch.cat([cropped_feature(d1, u2), u2], 1))
        u2 = self.exp_path[3](torch.cat([d1, u2], 1))
#         print('u2_after_cat: ',u2.shape)

        # Last layer with 1x1 convolution
        out = self.last_layer(u2)
        
        return out        
        
model = MRI_UNet()
print(model)
class IoULoss(nn.Module):
    def __init__(self, weight=None, size_average=True):
        super(IoULoss, self).__init__()
        self.weights = weight

    def forward(self, inputs, targets, eps=0.001):

        inputs = torch.argmax(F.log_softmax(inputs, dim=1), dim=1)
        
        inputs = F.one_hot(inputs, 5).float()
        targets = F.one_hot(targets.long(), 5).float()
        
        bat_sz = inputs.shape[0]
        ch_sz = inputs.shape[3]
        
        intersection = (inputs.view(bat_sz,-1,ch_sz) * targets.view(bat_sz,-1,ch_sz)).sum(1)
#         print("intersection: ",intersection)

        total = (inputs.view(bat_sz,-1,ch_sz) + targets.view(bat_sz,-1,ch_sz)).sum(1)
#         print(total)

        union = total - intersection
#         print(union)

        IoU = (intersection + eps)/(union + eps)
#         print(IoU)

        iouLoss = 1 - (IoU.mean(0) * self.weights).sum()/self.weights.sum()

        return iouLoss, IoU.mean(0)
class DiceLoss(nn.Module):
    def __init__(self, weight=None):
        super(DiceLoss, self).__init__()
        self.weights = weight

    def forward(self, inputs, targets, eps=0.001):
        
        inputs = torch.argmax(F.log_softmax(inputs, dim=1), dim=1)
        
        inputs = F.one_hot(inputs, 5).float()
        targets = F.one_hot(targets, 5).float()
        
        bat_sz = inputs.shape[0]
        ch_sz = inputs.shape[3]

        intersection = (inputs.view(bat_sz,-1,ch_sz) * targets.view(bat_sz,-1,ch_sz)).sum(1)
#         print("intersection: ",intersection)

        total = (inputs.view(bat_sz,-1,ch_sz) + targets.view(bat_sz,-1,ch_sz)).sum(1)
#         print(total)

        dice = (2 * intersection + eps)/(total + eps)
#         print(IoU)

        diceLoss = 1 - (dice.mean(0) * self.weights).sum()/self.weights.sum()

        return diceLoss, dice.mean(0)<jupyter_output><empty_output><jupyter_text>Testing<jupyter_code>test_model1 = torch.load('models/U-net-arch1.pth', map_location=torch.device('cuda'))
test_model2 = torch.load('models/U-net-arch2.pth', map_location=torch.device('cuda'))
data_name = pd.read_csv('image_name_info.csv')
dataset = LoadMRIDataSet(transform=transforms.Compose([Normalize_Image()]))

N_SPLITS = 5

nfold = KFold(n_splits=N_SPLITS, shuffle=True)

for fold, (train_ids, test_ids) in enumerate(nfold.split(data_name)):
#     log_dict = dict()

    print("Fold: ", fold+1, "/", N_SPLITS) #, train_ids.shape, test_ids.shape)

    train_subsampler = SubsetRandomSampler(train_ids)
    test_subsampler = SubsetRandomSampler(test_ids)

    testloader = DataLoader(
                      dataset,
                      batch_size=1, sampler=test_subsampler)
    
    break
device = "cuda"
len(testloader)
loss_weights1 = torch.FloatTensor([0.1, 0.1, 0.5, 0.5, 0.5]).to(device)
# loss_weights = torch.FloatTensor([1,1,1,1,1]).to(device)

seg_loss1 = nn.CrossEntropyLoss(weight=loss_weights1).to(device)
iou_loss1 = IoULoss(weight=loss_weights1).to(device)
dice_loss1 = DiceLoss(weight=loss_weights1).to(device)
loss_weights2 = torch.FloatTensor([1,1,1,1,1]).to(device)
# loss_weights = torch.FloatTensor([1,1,1,1,1]).to(device)

seg_loss2 = nn.CrossEntropyLoss(weight=loss_weights2).to(device)
iou_loss2 = IoULoss(weight=loss_weights2).to(device)
dice_loss2 = DiceLoss(weight=loss_weights2).to(device)
# results = list()
for j, test_data in enumerate(testloader, 0):
    plt.figure(figsize=(15,20))
#     log_dict = dict()

    test_inputs, test_labels = test_data['image'], test_data['label']

    test_inputs = test_inputs.to(device)
    test_labels = test_labels.to(device)

    predictions = test_model(test_inputs.float()).to(device)
    
    
    lossCE = seg_loss(predictions.float(), test_labels.long())

    lossIoU, IoU_per_ch = iou_loss(predictions.float(), test_labels.long())

    diceLoss, dice_per_ch = dice_loss(predictions.float(), test_labels.long())

    clr = ['black','lightyellow', 'darksalmon', 'lightseagreen', 'slateblue']
    cmap = colors.ListedColormap(clr)
    plt.subplot(1,3,1)
    plt.imshow(torch.argmax(F.log_softmax(predictions[0], dim=0), dim=0).cpu(), cmap=cmap, vmin=-1, vmax=5)
    plt.title('pred label')
    plt.axis('off')
    
    plt.subplot(1,3,2)
    plt.imshow(test_inputs[0, 1].cpu(), cmap='gray')
    plt.title('input')
    plt.axis('off')
    
    plt.subplot(1,3,3)
    plt.imshow(test_labels[0].cpu(), cmap=cmap, vmin=-1, vmax=5)
    plt.title('actual label')
    plt.axis('off')
    
    plt.savefig('boxplots/' + str(j) + '.jpg', dpi=300)
    plt.show()
    
    pred = torch.argmax(F.log_softmax(predictions[0], dim=0), dim=0).cpu()
    act = test_labels[0].cpu()
    acc = (pred==act).sum()/torch.numel(act)
    
    print("Accuracy: {:.2f}".format(acc.item()))
    
    if (j+1)%10 == 0:
        break
results = list()
for j, test_data in enumerate(testloader, 0):

    test_inputs, test_labels = test_data['image'], test_data['label']

    test_inputs = test_inputs.to(device)
    test_labels = test_labels.to(device)

    predictions1 = test_model1(test_inputs.float()).to(device)
    predictions2 = test_model2(test_inputs.float()).to(device)
    
    
    lossCE1 = seg_loss1(predictions1.float(), test_labels.long())

    lossIoU1, IoU_per_ch1 = iou_loss1(predictions1.float(), test_labels.long())

    diceLoss1, dice_per_ch1 = dice_loss1(predictions1.float(), test_labels.long())
    
    lossCE2 = seg_loss2(predictions2.float(), test_labels.long())

    lossIoU2, IoU_per_ch2 = iou_loss2(predictions2.float(), test_labels.long())

    diceLoss2, dice_per_ch2 = dice_loss2(predictions2.float(), test_labels.long())
    
    pred1 = torch.argmax(F.log_softmax(predictions1[0], dim=0), dim=0).cpu()
    act1 = test_labels[0].cpu()
    acc1 = (pred1==act1).sum()/torch.numel(act1)
    
    pred2 = torch.argmax(F.log_softmax(predictions2[0], dim=0), dim=0).cpu()
    act2 = test_labels[0].cpu()
    acc2 = (pred2==act2).sum()/torch.numel(act2)
    
#     print("Accuracy: {:.2f}".format(acc.item()))
    
    result_dict_arch_1 = dict({
        "cross entropy loss" : lossCE1.item(),
        "IoU loss" : lossIoU1.item(),
        "Dice loss" : diceLoss1.item(),
        "brain background dice" : dice_per_ch1[1].item(),
        "brain background IoU" : IoU_per_ch1[1].item(),
        "Edema dice" : dice_per_ch1[2].item(),
        "Edema IoU" : IoU_per_ch1[2].item(),
        "NET dice" : dice_per_ch1[3].item(),
        "NET IoU" : IoU_per_ch1[3].item(),
        "ET dice" : dice_per_ch1[4].item(),
        "ET IoU" : IoU_per_ch1[4].item(),
        "accuracy" : acc1.item(),
        "architecture": "architecture 1",
        "index" : j
    })
    
    results.append(result_dict_arch_1)
    
    result_dict_arch_2 = dict({
        "cross entropy loss" : lossCE2.item(),
        "IoU loss" : lossIoU2.item(),
        "Dice loss" : diceLoss2.item(),
        "brain background dice" : dice_per_ch2[1].item(),
        "brain background IoU" : IoU_per_ch2[1].item(),
        "Edema dice" : dice_per_ch2[2].item(),
        "Edema IoU" : IoU_per_ch2[2].item(),
        "NET dice" : dice_per_ch2[3].item(),
        "NET IoU" : IoU_per_ch2[3].item(),
        "ET dice" : dice_per_ch2[4].item(),
        "ET IoU" : IoU_per_ch2[4].item(),
        "accuracy" : acc2.item(),
        "architecture": "architecture 2",
        "index" : j
    })
    
    results.append(result_dict_arch_2)
results_df = pd.DataFrame(results)
results_df
results_df.columns
for col in ['cross entropy loss', 'IoU loss', 'Dice loss', 'brain background dice',
       'brain background IoU', 'Edema dice', 'Edema IoU', 'NET dice',
       'NET IoU', 'ET dice', 'ET IoU', 'accuracy']:
    
    pd.pivot_table(results_df, values='brain background dice', index='index',
                        columns=['architecture'], aggfunc=np.mean).boxplot()
    plt.title(col)
    plt.savefig('boxplots/' +col + '.jpg', dpi=300)
    plt.show()
results_df[results_df['architecture'] == 'architecture 1'].mean()
results_df[results_df['architecture'] == 'architecture 1'].std()
results_df[results_df['architecture'] == 'architecture 2'].mean()
results_df[results_df['architecture'] == 'architecture 2'].std()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16040396688199435, 'fraction_numerical': 0.03038849968155764, 'mean_word_length': 3.112233445566779, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '613351', 'license': 'Linux-OpenIB', 'n_tokens_mistral': 4192, 'n_tokens_neox': 4055, 'n_words': 632, 'path': 'segmentation_u_net_pytorch_testing.ipynb', 'repo_name': 'TonyStark2195/Biomedical_Image_Segmentation', 'size': '10991'}