Hi,
Please take a look at how the optim package should be used in the doc here 10.
The optimizer should be give parameters, not the output of your network.
If your net is made of top and bottom.

If you want to optimize both of them:

# Outside training loop
optimizer = t.optim.SGD(itertools.chain(top.parameters(), bottom.parameters()), ...)

# Inside training loop
v = bottom(x)
out = top(v)
loss = criterion(out, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()


If you want to optimize just top:

# Outside training loop
optimizer = t.optim.SGD(top.parameters(), ...)

# Inside training loop
v = bottom(x)
v.detach() # no need to backpropate to bottom
out = top(v)
loss = criterion(out, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()


If you want to optimize just bottom:

# Outside training loop
optimizer = t.optim.SGD(bottom.parameters(), ...)

# Inside training loop
# You need to backprop all the way, so you need to do the full forward
v = bottom(x)
out = top(v)
loss = criterion(out, target)
optimizer.zero_grad()
loss.backward()
# Since the optimizer has only the bottom parameters, the top net will not be changed
optimizer.step()

Does this help? Or is your usecase something else?