Iterators don't have lengths - how come code in video works?

(Antoine) #1

From lesson4-mnist_sgd.ipynb, see also video lesson 9 (ml1):

dl = iter(md.trn_dl)

is by definition an iterator, hence does not have a length. However, the cell (see link to video timestamp above) contains the loop

for t in range(len(dl)):
    # do things

seems to be running fine. I find that puzzling.

I certainly get

TypeError: object of type 'generator' has no len()

when I run it. To fix this, I replace

range(len(dl))

with

range(len(md.trn_dl))

What is going on?

0 Likes

#2

I believe this may be a Python version issue. Regardless, I think what you want is this:

net2 = LogReg().cuda()
loss = nn.NLLLoss()
learning_rate = 1e-2
optimizer = optim.SGD(net2.parameters(), lr=learning_rate)

for epoch in range(1):
    losses=[]
    for xt,yt in iter(md.trn_dl):
        # Forward pass: compute predicted y and loss by passing x to the model.
        y_pred = net2(V(xt))
        l = loss(y_pred, V(yt))
        losses.append(l)

        # Before the backward pass, use the optimizer object to zero all of the
        # gradients for the variables it will update (which are the learnable weights of the model)
        optimizer.zero_grad()

        # Backward pass: compute gradient of the loss with respect to model parameters
        l.backward()

        # Calling the step function on an Optimizer makes an update to its parameters
        optimizer.step()
    
    val_scores = [score(x,y) for x,y in iter(md.val_dl)]
    print(np.mean(val_scores))

There is no need to call next when iterators are designed to be looped over natively. Easier to read and fewer LOC.

1 Like

(Antoine) #3

Yes, absolutely !

0 Likes