Hello, everyone, and welcome to this new session in which we are going to go under the hood and understand
exactly what goes on when we call on this fit method right here.
In fact, we're going to be training our own model without making use of this feed method.
So yeah, we're going to have this custom training loop, which we are going to build.
As you could see here, we have this training block, we have this validation block, and then we have
this method which we named neural learn, and this method which replaces the feed method, which we
used to get in TensorFlow is not only a great machine learning library because it permits us build and
deploy machine learning models.
It's greatness also comes from the fact that it permits us build these models and train them without
getting to know everything which is going on under the hood.
So all you need to do to train TensorFlow model is to specify that model and then make use of this feed
method while passing in your dataset, which is made up of the inputs and the output.
That said, in this section, we'll see how to create our own feed method.
That is, we'll go a step further in understanding how TensorFlow works under the hood.
Recall that when you make use of this feed method right here, what goes on essentially is TensorFlow
applies the gradient descent method to update this weight tester right here.
So all the setters are being updated until the model converges.
Recall that for given inputs x1x2 and outputs y one, y2y3.
Our aim is to update this weights such that when we pass in this inputs into the model, we get an output
right here, which looks practically the same as this outputs.
And to know whether this model outputs are the same or similar to this actual outputs, we apply or
make use of a loss function, which computes the difference between these two and generally.
Initially, when you start training the model, that's when you start updating these parameters.
There will be a great difference between these two.
But as you keep on updating these parameters, we notice that the loss starts dropping.
And so once this loss drops, until it starts, it converges, we then stop the training.
But recall also that the way we update these weights is such that we take the initial weight minus the
learning rates, which is a constant with the fine times, the partial derivative of this loss.
Now, the loss which we've seen here, which we understand that is the difference between the model's
predictions and the actual prediction.
So here we have this partial derivative of the loss with respect to the parameter or the weight in question.
And so if we want to update, say, the stellar double prime to one, we'll simply use this same approach.
Now, the way TensorFlow computes this partial derivative right here is by automatic differentiation.
And so when you have this model with a inputs, as these inputs are being passed into the model in this
forward pass right up to the output TensorFlow records, this gradients others partial derivatives,
and this is done for each and every parameter such that once we get the output and we compute the loss,
we could now get this whole partial derivative right here that is a partial activity of the loss with
respect to each end every weight and then each and every weight has been optimized or been updated via
this formula.
So in general we can have tester, whatever.
And then we have, let's say, IG, we could have I comma, J, equal tetter, I comma, g minus learning
rate times, partial derivative of the loss respect to theta IJ And so as we go to this forward pass,
what TensorFlow does is it keeps in mind the taters and the gradients.
Let's call this gradient the tatter.
So we have the tetter and the dictator which have been stored or which have been recorded.
As we go through this model that's in this forward past that process of record in this gradients here.
As we pass in our inputs in the model is similar to what we would have with a tape recorder where you're
you just need to speak in this mic, The information is recorded and then it could be replayed later
on.
And so here, as information has been passed in this model, this gradients are being stored and they
could be used in the gradient descent algorithm later on.
Getting back to the code, we'll now see how to build a feed method from scratch.
So here we have this let's have for epoch in epochs.
You see that now, unlike your where we just needed to pass in this number of epochs and TensorFlow
does the job, you really need to do much work on your own.
So we have for epoch in epochs.
What we're going to do here is go through each and every batch of our data set.
So we also have that for each epoch.
We are now going to go through each and every batch.
So for X batch Y batch entering data set, let's have this tuple.
So we have X batch y batch in training data set.
What we're going to do now is pass in this X batch into our model.
And then after getting the model output, compare that model output with the actual output and obtain
the loss.
So here we have widespread, which is what the model outputs.
We have the model.
Yeah, we've defined the model already.
So we're working with a sequential model we had built previously.
Yeah, we go, we have this sequential model and then in this model we're going to pass our X batch.
There we go.
We specify that we're training, so we're in training mode.
Training equal true.
Okay, So now we have y Pred and what we could do next is compute the loss.
So here we have loss, equal loss function, which we're going to define loss function, which is going
to take in our widespread and the models are and the actual y so we can make use of this custom BCI
right here.
Now this takes in the y true y pred So we should ensure that we have y true before widespread.
And yeah, we have we should have y batch and then widespread.
Okay, so let's take this off and that's it.
So yeah, we're going to use our custom BCI.
We could take this off and then specify custom BCI.
Now we have our custom BCI.
We could go ahead and update this model's weights, but in order to update our model's weights, we
need those gradients.
The way we get those gradients is by recording or taping this gradients as we pass the input into the
model to do this, this part of our code has to be put in a particular scope.
So yeah, we have width gradients or TF that gradient gradient tape as tape, we are going to have this,
let's have that.
We are going to have this two lines of code.
Now the effect of doing this is we are recording the gradients in this tape, in this recorder.
We could say this as recorder and now all the intermediate values of tetter and intermediate gradients
have been recorded and now could be used in computing this partial derivative right here.
That said, we could now obtain the partial derivatives.
So we have partial derivatives equal to tape.
So this tape all rather equal to recorder because we changed that to recorder so equal this recorder
dot gradient of the loss with respect to all the models trainable weights.
And so this line of code here represents this operation that is computing this partial derivative of
the loss with respect to each and every weight.
Then we move on to optimize our model by going through this stochastic gradient descent or some other
gradient descent based optimizer like the Atom Optimizer, which we've used so far.
That said, we get back up to this compiler, we have this optimizer, let's take this from your copy
that.
And then what we do is we are going to add a so let's take this up.
We have our optimizer here, so let's have this optimizer.
That's it.
Our item optimizer defined.
Were on that cell.
And then what we do now is we have Optimizer.
Optimizer that apply gradients.
So we use this apply gradient method in order to update the weights based on the gradient descent algorithm.
In here we have zip of gradients or rather the partial derivatives.
So we are passing in the partial derivatives and the model trainable weights.
So recall we have some unchangeable weights actually.
So we have this model trainable weights right here.
And the derivatives.
Let's scroll.
Okay, let's have this here.
This.
This is linked.
So this part.
It's linked to this.
And then for this, it's the whole algorithm, the whole gradient descent based algorithm, which takes
in this partial derivative and the model trainable weights does the taters.
Obviously, while defining the optimizer, we have already set the learning rate.
So there we go.
Then from here, we could print out our lost values.
Yeah, we could print out the loss.
Print off the loss.
Okay, So now we said we could now run this and see how this works.
Let's not forget to specify the number of epochs.
So let's have a number of epochs equal.
Say three for stat.
Let's have this epochs and then we run the cell.
We are taught here that the model is not defined.
So let's modify this and have Loonette Loonette model run that again.
We get in this error where we told this expects the shape y, what we get is this.
Now the fact that we have this means that we haven't yet resized our training data, so let's get back
up and then run this cells here for resizing.
And there we go.
Let's run the cells.
Okay, we have that and now it looks fine.
So we have the cells run.
Let's get back to our custom training loop.
Okay, So let's run this.
As we can see, the training goes on smoothly.
You have those last values we should drop in and we run this actually for three epochs.
So there we go.
We have our loss, which is dropping.
Let's and then we could decide to print this out after a given number of steps.
So yeah, we could add the step and enumerate enumerate.
There we go.
We could check out our free python course on neural and AI to understand this in case you new to all
those keywords.
So there we go.
We enumerate, we have step.
And then what we're going to do here is we're going to print our last values only after a number of
steps.
So given that we have 689 steps, that's if our batch size is 32.
Or suppose that after, say, 300 steps, we're going to print this loss out.
So, yeah, we're going to have if the step modulo 300 equals zero, then we'll do the printing.
So there we go.
We have this print and then for every epochs that we're going to print out, training starts for epoch
number and then we format that.
So here we have the epoch.
Okay, let's rerun this again.
Here is what we get now.
So we have this training starts, training starts, training starts, and then we have this intermediate
loss values which have been printed out.
Now what if we include the validation?
So here, notice we finish like we trained the model and then after training for one epoch we don't.
We then get into validation.
So for x batch, val y batch val in val data set, we'll simply copy this out.
So here we have this your let's paste it on your OC.
So here we have the Y pride and our loss.
Val The same model that your training is set to false.
We have training false, we have y print.
Val and then we have y batch.
Val Yes.
X batch of all two and then we print out the last Val So yeah, we have validation loss.
Okay, let's run the cell now.
While training is going on, we could include the metric.
Here we have this metric which is binary accuracy.
Binary accuracy.
Now, while training is going on, we could deal with the metric.
So you're for this or for each batch we're working with.
We are going to update the state.
We are going to print out the result and then we are going to reset the states.
So let's get back to this part and then just after this, that's for this particular batch.
What we have here is we have our metric that update state and then we pass in our why or our why batch.
That's all by batch.
True.
Why and then why Pred?
So once we update this metric, we could now print out this metric value out of this for loop.
So after each epoch we're going to print out the metric value.
And so here we have print of metric dot result.
There we go, print metric results.
And then we should have your the accuracy is there we go.
Accuracy is does it once we once we print out the result, we now go ahead and reset state.
So we have metric that reset states and that should be good.
So we reset the states and that's fine.
We could repeat this exact same process for the validation.
With the validation just in here in this batch, we are going to repeat the same step.
So here we have the metric, space it out here and then yeah, we're going to have metric vol metric
while we update the state.
Yeah, we're going to use why batch file and why pred vao.
Okay.
Once we update the state, we now do this same process here.
So we print and then we reset the states.
Let's have this here print and then reset states.
Let's take that off.
So we have here metric value and then metric vial and that's it.
Let's define metric and metric.
Wow.
Here we go.
We have metric and then we have metric.
Wow.
So that's it.
So here we see how to recreate this feat method that we have here.
Now that we've seen this, we see the training is going out well.
We see that the training lost, the validation loss and that's it.
But the training loss we're getting here is for each and every three hundredths batch.
So let's take this off from here.
Let's let's say we print this out after that's after each epoch.
So the training loss, we print it out after each epoch and that's it.
This means that we don't really need to have this again.
Let's take that off.
So we print out the training loss and the accuracy.
There should be good.
We now run this and here's where we get You see, we have the train loss.
We have the train accuracy, validation, accuracy.
We've changed this to our accuracy.
And then we have the validation loss for Epoch two.
We have the same for Epoch three.
We have this for now.
We're in the ego mode.
So obviously this training process is going to be slower as compared to if we're working in the graph
mode.
Now what we're going to do is we are going to pick out those computation, expensive units of this cell
right here.
Now we know that this is computationally expensive because, yeah, we have to pass in our input into
the model compared to the output, compute the loss, get the gradients, optimize the model of the
the metrics.
So we look at this as one of those blocks and then we have this other block.
Let's scroll up, we have this, let's take this off.
So yeah, we have this block and then we also have this other block.
Now you'll notice that this is what we call the training step, and then this is the validation step.
So what we could simply do here is create this to methods.
So we have training, let's call this training block, we have the training block.
And then what goes on this training block is we take in an X, so you have X batch and then Y batch.
Basically we just copied all this.
So here we copy this code that and then we paste it right here.
So yeah, we have this training block and then your instead of having this, we just say for each step
we're going to go pass to the training block, pass for the training block we pass in X batch and Y.
Then we repeat the same process for the validation.
Here we have this copied out.
And let's copy this.
So yeah, we have the validation block.
That's a file block.
Here we have the block, which takes L batch, val and Y batch Val.
There we go.
We have this string block validation block.
Now, just here we could paste out.
Let's create our validation block and then take X batch.
Val x batch.
Val y batch, Val.
There we go.
We pick this out.
So for this, we have that.
Now, since we compute this loss in the training block, we want to return want to return this loss.
So we return this loss.
Okay, We have the last returned.
And then just right in here, we are going to see loss equals this.
So we call this loss.
And now we could make use of it right here and then we do.
Same for the validation block.
With the validation block, we take this here and then we return our loss.
Val.
Now, that sounds great.
We should now be able to change this in our graph mode, so we have to function.
That's all it takes to convert this to graph mode to F function.
That's it.
So there we go.
We've converted this to graph mode.
We can now run this.
We get in this error.
Let's check on what's going on.
Okay, let's run this now.
We told on and then doesn't match any outer indentation level.
Okay.
Yeah.
We should put this to match up with this width and that should be good.
Let's make sure we don't have the same error here.
So we have this four and that's it.
Okay, so let's run again.
And obviously we should have no problem now.
We could retrain our model and we should get faster training this time around, but still we get this
error loss value must be defined before the loop.
So we get back to the code.
And what we could do is command this section, which is for the training, because this works already.
So let's command the section and then focus on the validation block.
The first remark we have here is we've made an error of putting this for loop in this block.
It's not actually a syntax error, but more of a design error.
So it's better for us to have this var block in this far loop instead.
So that said, we are going to cut out this from this var block, and then what we'll have here now
is for this.
So we have for x y in the data set.
You see we're going to pass this in here and then have this block.
So here we have this var block.
Now everything looks fine.
We should have that.
And then let's now run the cell again.
You now see how just correcting that error automatically solved that issue.
And then we could go ahead and uncomment the section and rerun our training.
While the training is going on, we are going to create this method.
So this method, basically we're going to copy from this.
So here we should add the cell, we add the cell, and then we'll define this method, which we'll call
train, or let's call it neural learn.
So we'll call this method neural learn, and our neural and method we are going to take in a training
data set.
So we have trained data set and then our validation data set, we could also get in the model.
So we have the model we could pass in the number of epochs.
Let's have that here.
So it looks like the fit, the model fit, which comes for TensorFlow.
So here we have the number of epochs and then after the model we have the loss function loss function
metric, Val metric.
And that seems okay.
So yeah, we have that.
We didn't have this call.
So yeah, we just have neural learn and then we pass the model.
In that model, we pass the last function loss function, we pass the metric, we pass the vital metric
metric, we pass the train data set, we pass the data set, and then we pass a number of epochs.
So all we need to do now is just run this.
And then our training process is going to start getting back to your training.
Here.
You see how this training loss.
You see we have the training loss, we have the accuracy, we have the validation loss and we have the
validation accuracy.
Let's stop this.
And then we could even take off the cell.
Let's take off the cell.
Okay.
And then we have that cell off.
Let's delete that cell and then focus on this.
So now we have our neural learning, which takes in the model.
So here, as you could see, we had this optimizer, We had the metric metric.
Val epochs.
Let's get back to the optimizer.
Let's add the optimizer here.
So we should have after this last function metric and then let's have Optimizer Optimizer.
There we go.
Now, after the metric here we have our optimizer looks fine, let's run this and this last function
are defined.
So let's scroll up and we have this custom.
So let's just put out the custom BCI right there.
Custom custom BCI, we run that training is now complete and you are the results we get you now know
how to create your own custom training loops and make them around in graph mode.
Thank you for getting around to this point and see you next time.