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

# A completely empty (and useless) classclass StepByStep(object):passBoring, right? Let’s make it more interesting.The Constructor"From where do we start building a class?"That would be the constructor, the __init__(self) method that we’ve alreadyseen a couple of times when handling both model and dataset classes.The constructor defines the parts that make up the class. These parts are theattributes of the class. Typical attributes include:• arguments provided by the user• placeholders for other objects that are not available at the moment of creation(pretty much like delayed arguments)• variables we may want to keep track of• functions that are dynamically built using some of the arguments and higherorderfunctionsLet’s see how each of these applies to our problem.ArgumentsLet’s start with the arguments, the part that needs to be specified by the user. Atthe beginning of Chapter 2, we asked ourselves: "Would the code inside the trainingloop change if we were using a different optimizer, or loss, or even model?" The answerwas and still is, no, it wouldn’t change.So, these three elements, optimizer, loss, and model, will be our main arguments.The user needs to specify these; we can’t figure them out on our own.But there is one more piece of information needed: the device to be used fortraining the model. Instead of asking the user to supply it, we’ll automatically checkif there is a GPU available and fall back to a CPU if there isn’t. But we still want togive the user a chance to use a different device (whatever the reason may be); thus,Going Classy | 177

we add a very simple method (conveniently named to()) that allows the user tospecify a device.Our constructor (__init__()) method will initially look like this:class StepByStep(object):def __init__(self, model, loss_fn, optimizer):# Here we define the attributes of our class# We start by storing the arguments as attributes# to use laterself.model = modelself.loss_fn = loss_fnself.optimizer = optimizerself.device = 'cuda' if torch.cuda.is_available() else 'cpu'# Let's send the model to the specified device right awayself.model.to(self.device)def to(self, device):# This method allows the user to specify a different device# It sets the corresponding attribute (to be used later in# the mini-batches) and sends the model to the devicetry:self.device = deviceself.model.to(self.device)except RuntimeError:self.device = ('cuda' if torch.cuda.is_available()else 'cpu')print(f"Couldn't send it to {device}, \sending it to {self.device} instead.")self.model.to(self.device)PlaceholdersNext, let’s tackle the placeholders or delayed arguments. We expect the user toeventually provide some of these, as they are not necessarily required. There areanother three elements that fall into that category: train and validation dataloaders and a summary writer to interface with TensorBoard.We need to append the following code to the constructor method above (I am notreproducing the rest of the method here for the sake of simplicity; in the Jupyternotebook you’ll find the full code):178 | Chapter 2.1: Going Classy

we add a very simple method (conveniently named to()) that allows the user to

specify a device.

Our constructor (__init__()) method will initially look like this:

class StepByStep(object):

def __init__(self, model, loss_fn, optimizer):

# Here we define the attributes of our class

# We start by storing the arguments as attributes

# to use later

self.model = model

self.loss_fn = loss_fn

self.optimizer = optimizer

self.device = 'cuda' if torch.cuda.is_available() else 'cpu'

# Let's send the model to the specified device right away

self.model.to(self.device)

def to(self, device):

# This method allows the user to specify a different device

# It sets the corresponding attribute (to be used later in

# the mini-batches) and sends the model to the device

try:

self.device = device

self.model.to(self.device)

except RuntimeError:

self.device = ('cuda' if torch.cuda.is_available()

else 'cpu')

print(f"Couldn't send it to {device}, \

sending it to {self.device} instead.")

self.model.to(self.device)

Placeholders

Next, let’s tackle the placeholders or delayed arguments. We expect the user to

eventually provide some of these, as they are not necessarily required. There are

another three elements that fall into that category: train and validation data

loaders and a summary writer to interface with TensorBoard.

We need to append the following code to the constructor method above (I am not

reproducing the rest of the method here for the sake of simplicity; in the Jupyter

notebook you’ll find the full code):

178 | Chapter 2.1: Going Classy

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

Saved successfully!

Ooh no, something went wrong!