In this lecture we are going to do an example of classification and code using pi torch.
Our problem for this lecture will be to predict whether a patient's diagnosis of breast tissue is malignant
or benign.
This is a classic application of machine learning and deep learning especially has made great progress
in this field.
This lecture is going to walk you through a prepared collab notebook.
Although a very good exercise which I always recommend is once you know how this is done to try and
recreate it yourself with as few references as possible as usual you can look at the title of the notebook
to determine what notebook we are currently looking at.
To start we're going to have all our usual imports torch towards that and in number pi and map plot
lib.
Next we are going to load in the data.
This dataset is part of psyche.
Learn so we're going to import the function load breast cancer from the module as killer and that data
sets.
Next we're going to call this function and assign it to a variable called data.
Next we're going to check the type of the data variable since it's not clear what it returns.
We can see that it returns an object of type a bunch
luckily I've already inspected this object.
So I know that it acts kind of like a dictionary in that way we can call the function keys and it's
going to show us all the keys that we can access from this object so we see data Target Target names
description feature names and file name so the first two keys data and target refer to the input data
X and the targets y respectively.
So I'm going to call data dot data that shape to check the shape of X
okay.
So we see that it's five sixty nine by 30.
So that means we have five hundred and sixty nine samples in 30 input features
next.
I'm going to print out the targets here so as you can see it returns a one dimensional array of zeros
and ones as expected
now luckily even though the targets are just zeros and ones we can still determine what they mean by
printing out data.
Target names as promised.
They stand for malignant and benign.
Next we can confirm that the length of y is equal to the length of X 569
next.
Note that we can also print out the input feature names as well so we can see things like mean radius
mean texture mean perimeter and so forth.
Of course you're free to look up this dataset online if you want to learn more about it but remember
that we would just like to treat this as a geometry problem.
Next we're going to split the data into train and test.
You'll notice that I'm importing things as we go along since that helps tell the story.
But in general you'll find that it's more conventional to put all the imports at the top.
So here we're going to import the function train test split from the module scalar and model selection
then we're going to call this function and make the test set 33 percent of the original data set.
This returns X train x test y train and Y tests then we're going to assign the shape of X train to the
variables in indeed which may or may not be useful later
next.
And this is important in deep learning.
We want to scale our data the basic idea behind this is that because the output is a linear combination
of the input you don't want one inputs have a very large range say one million and another input to
have a very small range like say zero point zero zero one.
If this happens then the weights will be too sensitive when the input has a large range and not sensitive
enough when the input has a small range.
So the typical way to deal with this is a normalization or standardization.
Basically this just means subtracting the mean and dividing by the standard deviation luckily circular
and already comes with a class for this called standard scalar so we fit transform on X train and then
we transform on X test.
Remember that it's important not to expose any of our test data to the training pipeline
next.
It's time to do our PI torture work as you saw earlier.
We first need to build a model object which is now a sequence of modules it takes in a list of two modules
linear and sigmoid the linear layer has an input size D and an output size 1.
As mentioned we want to apply the sigmoid activation so that the outputs are in the range 0 and 1.
Next we are going to prepare to train our model.
So we'll need a loss and an optimizer the loss we're going to use is the binary cross entropy loss or
BCE loss which is the appropriate laws for binary classification.
The optimizer will use is called atom which is a common default chosen by deep learning practitioners
next we're going to convert our data into torture tenses before we enter our training loop as you've
seen before.
This involves calling the function at torchlight from num pi.
In addition we still need to convert all the data to flow 30 to one detail you may have missed.
If you're not accustomed to PI torch is that we want to reshape the targets to be a 2D array of size
n by 1 instead of just a one B array of length then in other libraries such as site yet learned carries
and tensor flow a 1 the array is appropriate but that's not the case.
And Patrick.
Next we have our main training loop as promised we're not going to spend much time explaining this because
it's pretty much exactly the same as before.
There is one small additional detail here but it's one that doesn't require any new knowledge.
Now that we have both a train and test set we want to be clear about which data set we use where.
So when we do the training portion meaning a step of gradient descent will want to use the train set
X train and Y train.
This involves doing a forward pass calculating the loss calling lost not backward and then calling the
optimizer step so you can see all these here.
So we pass X train into model to get outputs we pass y train and outputs to get the loss we lost that
backward and then optimize it.
Step but on top of that we would still like to know the test lost per iteration.
This will tell us whether or not our model is over fitting.
For example if we see the test loss increasing during training then we know that we are over fitting
our model to calculate the Test loss.
We do some of the same steps but with the test data instead of the train data.
So we do the forward pass but we pass in x test instead of X train.
Then we calculate the criterion with the test outputs against y test.
Finally we save both the train loss and the test lost in our arrays of losses.
Next we check our loss per iteration
everything appears to look good and the train loss is not too different from the test loss which means
our model is not over fitting
next.
We check the accuracy of our model.
Remember that unlike with regression the metric we care about is very different from the lost function
we minimized in order to train our network.
Accuracy is simply the number we got right divided by the total number of predictions.
In order to get the train predictions we first pass X train into the model which gives us P train.
We want to convert the output which is a torch tensor into an umpire Ray by calling the NUM pi function.
These outputs are still probabilities so we want to call NPD out round in order to convert them all
to zeros and ones.
Once we have our predictions we can calculate the accuracy by doing a point wise comparison with why
train and taking the mean.
Now this calculation often confuses beginners.
How does this calculate the accuracy.
I would encourage you to do a few simple examples in the console on your own.
If you don't get it right away remember that equals equals returns True or false.
You'll get true if two items are equal and false if not this operation happens element wise.
So if y train and P train are arrays of length n then doing equals equals will give us an array of like
then that contains all truths and forces so what happens when you take the mean of an array containing
truths and falsities.
What does that even mean.
Usually it only makes sense to calculate the mean for numbers and clearly true and false are not numbers.
However in Python true is treated like one and false is treated like zero.
So if you try one equals equals true in the console that returns true.
And if you try 0 equals equals false in the console that also returns true.
In other words this is really like an array of zeros and ones.
We have a 1 whenever you got the correct answer and 0 whenever we did not.
You should convince yourself that calculating the accuracy is the same as just adding up all the ones
and dividing by n which is also the same as taking the mean.
If you don't get it right away write it down on paper next.
We do the same thing for the test set to get the test accuracy.
The result is that we get about 98 percent accuracy on both the train and test step which is very good.
As an exercise.
Here is a nice thing to try and he intensive flow when you do a training loop.
You will actually get two arrays of data back.
One is the loss per iteration for both the train and test set and one is the accuracy per iteration
for both the train and test set.
You'll notice that we did not plot the accuracy per iteration here.
So for the exercise you should try to modify this code so that during the training loop we not only
collect the loss at each iteration but also the accuracy at each iteration when the loop is done.
You should be able to plot the accuracy per iteration you should see that as the loss goes down the
accuracy goes up.
This is usually the case you might want to also think about what are the downsides of calculating the
accuracy at each iteration of the loop.