Daniel Voigt Godoy - Deep Learning with PyTorch Step-by-Step A Beginner’s Guide-leanpub

peiying410632
from peiying410632 More from this publisher
22.02.2024 Views

# These attributes are defined here, but since they are# not available at the moment of creation, we keep them Noneself.train_loader = Noneself.val_loader = Noneself.writer = NoneThe train data loader is obviously required. How could we possibly train a modelwithout it?"Why don’t we make the train data loader an argument then?"Conceptually speaking, the data loader (and the dataset it contains) is not part ofthe model. It is the input we use to train the model. Since we can specify a modelwithout it, it shouldn’t be made an argument of our class.In other words, our StepByStep class is defined by a particular combination ofarguments (model, loss function, and optimizer), which can then be used toperform model training on any (compatible) dataset.The validation data loader is not required (although it is recommended), and thesummary writer is definitely optional.The class should implement methods to allow the user to supply those at a latertime (both methods should be placed inside the StepByStep class, after theconstructor method):def set_loaders(self, train_loader, val_loader=None):# This method allows the user to define which train_loader# (and val_loader, optionally) to use# Both loaders are then assigned to attributes of the class# So they can be referred to laterself.train_loader = train_loaderself.val_loader = val_loaderdef set_tensorboard(self, name, folder='runs'):# This method allows the user to create a SummaryWriter to# interface with TensorBoardsuffix = datetime.datetime.now().strftime('%Y%m%d%H%M%S')self.writer = SummaryWriter(f'{folder}/{name}_{suffix}')Going Classy | 179

"Why do we need to specify a default value to the val_loader? Itsplaceholder value is already None."Since the validation loader is optional, setting a default value for a particularargument in the method’s definition frees the user from having to provide thatargument when calling the method. The best default value, in our case, is the samevalue we chose when specifying the placeholder for the validation loader: None.VariablesThen, there are variables we may want to keep track of. Typical examples are thenumber of epochs, and the training and validation losses. These variables are likelyto be computed and updated internally by the class.We need to append the following code to the constructor method (like we didwith the placeholders):# These attributes are going to be computed internallyself.losses = []self.val_losses = []self.total_epochs = 0"Can’t we just set these variables whenever we use them for the firsttime?"Yes, we could, and we would probably get away with it just fine since our class isquite simple. As classes grow more complex, though, it may lead to problems. So, itis best practice to define all attributes of a class in the constructor method.FunctionsFor convenience, sometimes it is useful to create attributes that are functions,which will be called somewhere else inside the class. In our case, we can createboth train_step_fn() and val_step_fn() using the higher-order functions wedefined in Chapter 2 (Helper Functions #1 and #3, respectively). Both of them takea model, a loss function, and an optimizer as arguments, and all of those are alreadyknown attributes of our StepByStep class at construction time.The code below will be the last addition to our constructor method (once again, aswe did with the placeholders):180 | Chapter 2.1: Going Classy

"Why do we need to specify a default value to the val_loader? Its

placeholder value is already None."

Since the validation loader is optional, setting a default value for a particular

argument in the method’s definition frees the user from having to provide that

argument when calling the method. The best default value, in our case, is the same

value we chose when specifying the placeholder for the validation loader: None.

Variables

Then, there are variables we may want to keep track of. Typical examples are the

number of epochs, and the training and validation losses. These variables are likely

to be computed and updated internally by the class.

We need to append the following code to the constructor method (like we did

with the placeholders):

# These attributes are going to be computed internally

self.losses = []

self.val_losses = []

self.total_epochs = 0

"Can’t we just set these variables whenever we use them for the first

time?"

Yes, we could, and we would probably get away with it just fine since our class is

quite simple. As classes grow more complex, though, it may lead to problems. So, it

is best practice to define all attributes of a class in the constructor method.

Functions

For convenience, sometimes it is useful to create attributes that are functions,

which will be called somewhere else inside the class. In our case, we can create

both train_step_fn() and val_step_fn() using the higher-order functions we

defined in Chapter 2 (Helper Functions #1 and #3, respectively). Both of them take

a model, a loss function, and an optimizer as arguments, and all of those are already

known attributes of our StepByStep class at construction time.

The code below will be the last addition to our constructor method (once again, as

we did with the placeholders):

180 | Chapter 2.1: Going Classy

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!