Before you attempt this assignment you should read chapters seven and eight in the textbook, and also look over the supplemental notes on the history of neural networks for image processing that we linked to from the course web site.
To download the data set of images we will be using for this assignment, run the following two commands in a terminal pane in your server account:
wget http://www.lawrence.edu/fast/greggj/CMSC490/cats_vs_dogs_small.zip unzip cats_vs_dogs_small.zip
Inside the expanded folder you will find various subfolders containing images of cats and dogs for training and for testing.
You will be doing all of your work for this assignment in a Jupyter notebook. Set up a new, empty notebook in the same directory where your images folder is located.
In this assignment we are going to construct a model that can correctly distinguish images of dogs from images of cats.
For almost any problem you set out to solve in neural networks, someone has already solved a similar problem. Often, you can get a head start on solving your problem by studying the solution to a similar problem.
For this assignment I have located an example online where someone has used a transfer learning strategy to train a pytorch network to distinguish two classes of images.
You can find that starter code at this URL:
https://www.kaggle.com/code/pmigdal/transfer-learning-with-resnet-50-in-pytorch
In that example code you will see the author setting up some code to load the data from the image files. The strategy that the author of the page uses to build a classifier is a widely-used strategy called transfer learning. In this approach we start with a pretrained image classifier network and then add an addition classifier layer on top to solve the task at hand. In the example code the author uses a pretrained ResNet50 network. To build our classifier we freeze the parameters in the network and bolt on a final classifier layer that is trainable:
resnet = models.resnet50(pretrained=True).to(device)
for param in resnet.parameters():
param.requires_grad = False
resnet.fc = nn.Sequential(
nn.Linear(2048, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 2)).to(device)
We can use exactly the same approach.
Although we will be using the same network architecture as the online example, we will have to make some adjustments.
The main adjustment will be necessary to handle some differences in the image data set the author is using the data set we have to work with. This will require us to use slightly different preprocessing logic when setting up our datasets. Replace the author's preprocessing logic with transforms that do the following:
You can use the same training loop as the author. You will have to experiment with the number of epochs to run to get reasonable results. (Be careful that you don't set the number of epochs too high at start - it will take forever to run through the training if you do.)
Note that our data set contains separate training, validation and test sets. After you train the network you would run the test data set through it to see how well the network does on that set.
When you are finished, upload your Jupyter notebook to the course Canvas page.