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?
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