Some of the notebooks in the specialization used PyTorch, a super popular deep learning framework developed by Facebook and that I really love. But if you haven't used it before, do not worry. You'll see that it's really similar to other frameworks like TensorFlow and in every notebook assignment there will be hints to help guide you along in using this PyTorch framework. In this video, I'll first compare PyTorch with TensorFlow. Then you'll see how to define models and how to train them using PyTorch functions. So PyTorch and TensorFlow are arguably the most popular deep learning frameworks right now. And if you took the deep learning specialization, you're probably familiar with TensorFlow. But here is a secret, I like PyTorch more. The main difference between them is the way they typically make computations. In PyTorch, you compute things on the go, and this is sometimes called imperative programming. In TensorFlow, you first define how to compute things, and then you make the calculations afterwards, which is called a symbolic approach. So this just means that in PyTorch, you have some values for variables A and B, like A is 1, B is 2 and when you sum them up, you get 3 as a result. Well, in TensorFlow, you don't have initial values for A and B, but you can store the sum of them in another variable, C. So it's a bit abstract here, but then you compile C and to get a value for that computation, you have to assign values where A and B are. So this gives PyTorch the ability to have dynamic computational graphs and this just means that your known networks could change their structure at every run pretty easily. However, because the computational graphs in TensorFlow are static, the models tend to take less time to run. So because you are describing this, C = A + B or your entire neural network like that, these computational graphs are considered static. And recently, with TensorFlow 2.0, there's something called Eager Execution and this is very, very similar to PyTorch with having dynamic computational graphs. But all in all, the dynamic computational graphs still feel much more natural in PyTorch. But on the whole, these currently are very, very similar frameworks and you'll see that transitioning from one to another has never been easier, especially from the TensorFlow to PyTorch direction. So focusing on PyTorch, let's start with how to define a model using PyTorch. First, you have to import PyTorch with the line import torch. And this is just the PyTorch Library. And then it's also useful to also import the nn module, which stands for neural network. And this includes custom layers for deep learning models. So it's very, very useful. It's common to define models in PyTorch using subclasses of the class nn.Module. And here the class LogisticRegression will help us create a logistic regression model. The initialization method for this class, it takes the parameters that you want for your model, so this is typical to object oriented Python. And in this case, the variable in here determines the number of input variables for this logistic regression model. Then you define the architecture of the model as an attribute within the constructor init, and for a logistic regression, you can use a Linear layer and a Sigmoid activation within what's called a Sequential module. And so the sequential module is just layering on sequential layers. So first give me a linear layer and then give me a sigmoid activation function. And here in the Linear layer you can see that I passed this variable in from here, so this is the size of that input going in and then the output is 1. I just want one prediction from all these inputs. And so this 1 here could just be a class of cut or not cut, which goes through the sigmoid activation that produces values between zero and one. And then finally, after this init here, you define the forward method of your model class and the forward method just means what your model does on the forward pass given inputs to produce an output. It's not the backward pass with back propagation, the forward pass is what happens when you put in the inputs. How does it produce the outputs? And so in this case, the sequential model you define here, self.logistic regression, you just return given the inputs x. So given the inputs x, you put it through this sequential set of layers. All right, so this is a very simple general outline of how to define a model in PyTtorch, but you could achieve the same results with a different code structure as well. Now, to train a model in this framework, you have to initialize an instance of the class that you define for your model. So here the LogisticRegression class, this model from the last slide has 16 input variables. Then you determine a cost function for your model. I'll call this the criterion, so it's a criterion that your model is learning from. And this is a typical name that's given to the cost function in PyTorch. And here I'm going to initialize the BCELoss for the cost function, which is available through this nn library, the torch neural network library. After that, you have to choose the optimizer you want to use, for example stochastic gradient descent passing your models parameters. So these are the theta that you've seen previously and that will be awaits that are going to be updated during training. And then you have to specify different hyper parameters for this optimizer. For example, the learning rate here. Finally, you can train your model for a number of different epochs, so let's start the training loop with n_epochs, this could be let's say 100, where within this training loop you pass the input into your model. You get a prediction from your model. Then you compare your prediction to the ground truth output using this criterion, using your cost function, and this gets your loss for this particular step. And then take a step towords your optimum using the optimizer that you defined. You don't need to worry about the exact syntax here, but basically what's happening is that this optimizer we are zeroing out the gradients from before to make sure that it's all clean and good, and this is the important step for back propagation. This prepares the back propagation step and this last optimizer.step here means using stochastic gradient descent on the model parameters with this small learning rate to step in that general direction and update those parameters. So to sum up, PyTorch makes computations on the run, so it allows you to experiment with models that can change in every single run. However, as you've seen in this video, PyTorch is just another deep learning framework that's actually very similar to TensorFlow. You'll be able to change back and forth between these frameworks without any problem, if you're already familiar with one of them.