class BreastCancerCNN(ImageClassificationBase):
def __init__(self):
super().__init__()
self.network = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2, 2), # output: 64 x 16 x 16
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.MaxPool2d(2, 2), # output: 128 x 8 x 8
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.MaxPool2d(2, 2), # output: 256 x 4 x 4
nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(512),
nn.ReLU(),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(512),
nn.ReLU(),
nn.MaxPool2d(2, 2), # output: 512 x 2 x 2
nn.Flatten(),
nn.Linear(256*2*2, 512),
nn.ReLU(),
nn.Linear(512, 256),
nn.ReLU(),
nn.Linear(256, 1)
)
def forward(self, xb):
return self.network(xb)
@torch.no_grad()
def get_lr(optimizer):
for param_group in optimizer.param_groups:
return param_group['lr']
def evaluate(model, val_loader):
model.eval()
outputs = [model.validation_step(batch) for batch in val_loader]
print(outputs)
return model.validation_epoch_end(outputs)
def fit(epochs, lr, model, train_loader, val_loader, opt_func=torch.optim.SGD):
history = []
# Set up cutom optimizer with weight decay
optimizer = opt_func(model.parameters(), lr, weight_decay=0)
# Set up one-cycle learning rate scheduler
sched = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr, epochs=epochs,
steps_per_epoch=len(train_loader))
for epoch in range(epochs):
train_losses = []
lrs = []
# Training Phase
model.train()
train_losses = []
for batch in train_loader:
loss = model.training_step(batch)
train_losses.append(loss)
loss.backward()
optimizer.step()
optimizer.zero_grad()
# Record & update learning rate
lrs.append(get_lr(optimizer))
sched.step()
# Validation phase
result = evaluate(model, val_loader)
result['train_loss'] = torch.stack(train_losses).mean().item()
result['lrs'] = lrs
model.epoch_end(epoch, result)
# print(result)
history.append(result)
return history
Get data from the history after running one epoch
history = [evaluate(model, val_dl)] history
This is the code that results in
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
/tmp/ipykernel_33/1481765314.py in <module>
1 # Get data from the histrory after running one epoch
----> 2 history = [evaluate(model, val_dl)]
3 history
/tmp/ipykernel_33/559867535.py in evaluate(model, val_loader)
7 def evaluate(model, val_loader):
8 model.eval()
----> 9 outputs = [model.validation_step(batch) for batch in val_loader]
10 print(outputs)
11 return model.validation_epoch_end(outputs)
/tmp/ipykernel_33/559867535.py in <listcomp>(.0)
7 def evaluate(model, val_loader):
8 model.eval()
----> 9 outputs = [model.validation_step(batch) for batch in val_loader]
10 print(outputs)
11 return model.validation_epoch_end(outputs)
/tmp/ipykernel_33/1785597948.py in validation_step(self, batch)
8 def validation_step(self, batch):
9 images, labels = batch
---> 10 out = self(images) # Generate predictions
11 loss = F.cross_entropy(out, labels) # Calculate loss
12 acc = accuracy(out, labels) # Calculate accuracy
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1109 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1110 return forward_call(*input, **kwargs)
1111 # Do not call functions when jit is used
1112 full_backward_hooks, non_full_backward_hooks = [], []
/tmp/ipykernel_33/3839242004.py in forward(self, xb)
45
46 def forward(self, xb):
---> 47 return self.network(xb)
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1109 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1110 return forward_call(*input, **kwargs)
1111 # Do not call functions when jit is used
1112 full_backward_hooks, non_full_backward_hooks = [], []
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input)
139 def forward(self, input):
140 for module in self:
--> 141 input = module(input)
142 return input
143
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
1108 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1109 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1110 return forward_call(*input, **kwargs)
1111 # Do not call functions when jit is used
1112 full_backward_hooks, non_full_backward_hooks = [], []
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/linear.py in forward(self, input)
101
102 def forward(self, input: Tensor) -> Tensor:
--> 103 return F.linear(input, self.weight, self.bias)
104
105 def extra_repr(self) -> str:
RuntimeError: mat1 and mat2 shapes cannot be multiplied (100x2048 and 1024x512)
I would like to analyse images for a defect and thus have a scale of 0 to 1 so as to evaluate the presence of a defect in the sample images Please help me break it down and understand what is actually going on and how do I determine the right values for the linear to get a single output that will result in a prediction of a
1
or0
CodePudding user response:
Without going fully through your code, but looking at the comments and error messages, one can see that for the last maxpool layer:
nn.MaxPool2d(2, 2), # output: 512 x 2 x 2
That is, the number of features per image are 512 x 2 x 2 = 1024.
This is then flattened and passed through this linear layer:
nn.Linear(256*2*2, 512),
But this only accepts 256 x 2 x 2 = 1024 input features. This is what causes the mismatch when calling forward
for this linear layer. To fix this, change this statement to:
nn.Linear(512*2*2, 512),