I am trying to setup a CNN model. My images are 224x224.
import torch.nn as nn
import torch.nn.functional as F
# define the CNN architecture
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# convolutional layer
self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
self.conv3 = nn.Conv2d(32, 64, 3, padding=1)
# max pooling layer
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(64 * 28*28 , 500)
# linear layer (500 -> 10)
self.fc2 = nn.Linear(500, 10)
# dropout layer (p=0.25)
self.dropout = nn.Dropout(0.25)
def forward(self, x):
# add sequence of convolutional and max pooling layers
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
# flatten image input
print(x.shape)
x = x.view(-1, 64 * 28*28 )
print(x.shape)
# add dropout layer
x = self.dropout(x)
# add 1st hidden layer, with relu activation function
x = F.relu(self.fc1(x))
# add dropout layer
x = self.dropout(x)
# add 2nd hidden layer, with relu activation function
x = self.fc2(x)
return x
# instantiate the CNN
model_scratch = Net()
print(model_scratch)
# move tensors to GPU if CUDA is available
if use_cuda:
model_scratch.cuda()
My Train and Validation loop:
# the following import is required for training to be robust to truncated images
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
def train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path):
"""returns trained model"""
# initialize tracker for minimum validation loss
valid_loss_min = np.Inf
for epoch in range(1, n_epochs+1):
# initialize variables to monitor training and validation loss
train_loss = 0.0
valid_loss = 0.0
print("====================EPOCHE", epoch)
###################
# train the model #
###################
model.train()
print('model trained')
for batch_idx, (data, target) in enumerate(loaders['train']):
print("Loop over Train", batch_idx)
print("USE_CUDA",use_cuda)
# move to GPU
if use_cuda:
data, target = data.cuda(), target.cuda()
# clear the gradients of all optimized variables
optimizer.zero_grad()
# forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the batch loss
loss = criterion(output, target)
# backward pass: compute gradient of the loss with respect to model parameters
loss.backward()
# perform a single optimization step (parameter update)
optimizer.step()
# update training loss
train_loss += loss.item()*data.size(0)
## find the loss and update the model parameters accordingly
## record the average training loss, using something like
## train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))
######################
# validate the model #
######################
model.eval()
for batch_idx, (data, target) in enumerate(loaders['valid']):
# move to GPU
print("USE_CUDA2",use_cuda)
if use_cuda:
data, target = data.cuda(), target.cuda()
## update the average validation loss
# forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the batch loss
loss = criterion(output, target)
# update average validation loss
valid_loss += loss.item()*data.size(0)
# calculate average losses
train_loss = train_loss/len(train_loader.dataset)
valid_loss = valid_loss/len(valid_loader.dataset)
# print training/validation statistics
print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
epoch, train_loss, valid_loss))
# save model if validation loss has decreased
if valid_loss <= valid_loss_min:
print('Validation loss decreased ({:.6f} --> {:.6f}). Saving model ...'.format(
valid_loss_min,
valid_loss))
torch.save(model.state_dict(), 'model_scratch.pt')
valid_loss_min = valid_loss
# return trained model
return model
# train the model
model_scratch = train(100, loader_scratch, model_scratch, optimizer_scratch,
criterion_scratch, use_cuda, 'model_scratch.pt')
# load the model that got the best validation accuracy
model_scratch.load_state_dict(torch.load('model_scratch.pt'))
I get the above error, and don’t really understand how to flatten my data right:
torch.Size([1, 64, 37, 28])
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-70-ef616b23c264> in <module>
81 # train the model
82 model_scratch = train(100, loader_scratch, model_scratch, optimizer_scratch,
---> 83 criterion_scratch, use_cuda, 'model_scratch.pt')
84
85 # load the model that got the best validation accuracy
<ipython-input-70-ef616b23c264> in train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path)
27 optimizer.zero_grad()
28 # forward pass: compute predicted outputs by passing inputs to the model
---> 29 output = model(data)
30 # calculate the batch loss
31 loss = criterion(output, target)
~\Anaconda3\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs)
491 result = self._slow_forward(*input, **kwargs)
492 else:
--> 493 result = self.forward(*input, **kwargs)
494 for hook in self._forward_hooks.values():
495 hook_result = hook(self, input, result)
<ipython-input-67-ebe7a14cbba0> in forward(self, x)
26 # flatten image input
27 print(x.shape)
---> 28 x = x.view(-1, 64 * 28*28 )
29 print(x.shape)
30 # add dropout layer
RuntimeError: shape '[-1, 50176]' is invalid for input of size 66304