image_output_1.png
from torch.utils.data import Dataset,DataLoader

from torchvision import transforms,datasets

import torch

import torch.nn as nn

torch.manual_seed(42)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
train_transforms = transforms.Compose([transforms.Resize((224, 224)), transforms.Grayscale(), transforms.RandomHorizontalFlip(p=0.5), transforms.ToTensor()])
test_transforms = transforms.Compose([transforms.Resize((224, 224)), transforms.Grayscale(), transforms.ToTensor()])
dataset = datasets.ImageFolder('../input/brain-mri-images-for-brain-tumor-detection/brain_tumor_dataset', train_transforms)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)

def convBlock(ni, no):
    return nn.Sequential(nn.Dropout(0.2), nn.Conv2d(ni, no, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.BatchNorm2d(no), nn.MaxPool2d(2))

class BrainCancerClassifier(nn.Module):
    def __init__(self):
        super().__init__()
        self.model = nn.Sequential(convBlock(1, 64), convBlock(64, 64), convBlock(64, 128), convBlock(128, 256), convBlock(256, 512), convBlock(512, 64), nn.Flatten(), nn.Linear(576, 256), nn.Dropout(0.3), nn.ReLU(inplace=True), nn.Linear(256, 128), nn.Dropout(0.2), nn.ReLU(inplace=True), nn.Linear(128, 64), nn.Dropout(0.2), nn.ReLU(inplace=True), nn.Linear(64, 2))
    def forward(self, x):
        return self.model(x)

def compute_metrics(preds, targets):
    loss = nn.CrossEntropyLoss()
    acc = (torch.max(preds, 1)[1] == targets).float().mean()
    return (loss(preds, targets), acc)

def train_batch(model, data, optimizer):
    model.train()
    images, labels = data
    images = images.to(device)
    labels = labels.to(device)
    optimizer.zero_grad()
    loss, acc = compute_metrics(model(images), labels)
    loss.backward()
    optimizer.step()
    return (loss.item(), acc.item())

model = BrainCancerClassifier().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

im2fmap = nn.Sequential(*list(model.model[:5].children()) + list(model.model[5][:2].children()))

epochs = 20
for epoch in range(epochs):
    epoch_loss = []
    epoch_acc = []
    for data in dataloader:
        loss, acc = train_batch(model, data, optimizer)
        epoch_loss.append(loss)
        epoch_acc.append(acc)
    print(f'Epoch: {epoch + 1}..Loss: {sum(epoch_loss) / len(epoch_loss):.3f}..Accuracy: {sum(epoch_acc) / len(epoch_acc):.3f}..')