import time
# 在 GPU 上训练注意需要将网络和数据放到 GPU 上
net.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
以上代码我们可以看到,loss与optimizer没有任何关联(直观上),其实它们并不需要直接联系,它们是通过 Tensor 这个类来达到间接联系的。
首先,net网络中的参数都是tensor,一个 tensor 里面有两个地址,一个是存放的这个tensor当前实实在在的值,比如赋值为10,还有一个存放的是10求导后的值(? .grad? ),就是导数。当然,如果没求导,另一个存放的是None。
当我们进行计算loss.backward()的时候,其实就是进行反向链式求导,这个求导是对net中的参数进行求导的,这里面的参数就是tensor,其有两个地址,分别存放当前值和反向求导的值,loss.backward()后,这个时候就每个参数里面都有导数,然后optimizer其实就是根据net每个参数的导数进行优化(在最开始定义的时候就已经绑定optimizer与net的参数了),这也就关联了loss与optimizer了。
optimizer.step()是更新参数
刚刚写完这个,突然想到,loss是怎么跟net中参数联系起来的,其实可以这么来看:
y=w1X1+w2X2+w3X3
我们在计算 loss = criterion(out, input)时,这里的out就等于y就等于w1X1+w2X2+w3X3,(虽然y是一些具体的值,但是这些值是由w1X1+w2X2+w3X3构成的),所以 losss.backward()的时候就是更新w1,w2,w3,所以这就关联了。(这一段是自己的理解)
我是参考了这个人的博客,讲的还不错,就是有些公式看不了:
Pytorch 疑案之:优化器和损失函数是如何关联起来的? - 灰信网(软件开发博客聚合)
里面有一段原文,写的不错:
“反正记住这样一点:所有的优化都是围绕损失函数来转的,我们想要损失降到最小,我们想要损失函数最小的时候的那个自变量的值,就是我们需要的权值。整个训练的过程就是在求权值的过程。”
|