1.4 nn.Module 神经网络(二)

损失函数:

1.

nn.MSELoss用来计算均方误差

nn.CrossEntropyLoss用来计算交叉熵损失。

eg:

import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import torch as t
class Net(nn.Module):
    def __init__(self):
        #nn.Module子类的函数必须在构造函数中执行父类的构造函数
        #下式等价于nn.Module.__init__(self)
        super(Net,self).__init__()
        #卷积层‘1’表示输入图片为单通道,‘6’表示输出通道数,‘5’表示卷积核为5*5
        self.conv1=nn.Conv2d(1,6,5)
        #卷积层
        self.conv2 = nn.Conv2d (6, 16, 5)
        #仿射层、全连接层,y=wx+b
        #一般定义一个linear层的时候,写法为nn.Linear(in_features,out_features)
        self.fc1=nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear (120, 84)
        self.fc3 = nn.Linear (84, 10)
    def forward(self,x):
        #卷积-->激活-->池化
        x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d (F.relu (self.conv2 (x)), 2)
        #reshape,‘-1’表示自适应
        #这句话一般出现在model类的forward函数中,具体位置一般都是在调用分类器之前。分类器是一个简单的nn.Linear()结构,
        # 输入输出都是维度为一的值,x = x.view(x.size(0), -1)  这句话的出现就是为了将前面多维度的tensor展平成一维
        #view()函数的功能根reshape类似,用来转换size大小。x = x.view(batchsize, -1)中batchsize指转换后有几行,
        # 而-1指在不告诉函数有多少列的情况下,根据原tensor数据和batchsize自动分配列数。
        x=x.view(x.size()[0],-1)
        x=F.relu(self.fc1(x))
        x=F.relu(self.fc2(x))
        x=self.fc3(x)
        return x
net=Net()
input=Variable(t.randn(1,1,32,32))
out = net(input)
print(out)
net.zero_grad()
out.backward(t.randn(1,10))
output = net(input)
target = Variable(t.randn(1,10))#假设的target :1,2,3,4,5,6,7,8,9,10
criterion = nn.MSELoss()
loss = criterion(output,target)
print(loss)

out:
tensor([[-0.1351, -0.0720, -0.0460,  0.1184, -0.0810,  0.0441, -0.0008,
         -0.0082, -0.1029,  0.0620]])
tensor(2.6400)

注意:target = Variable(t.arange(1,11))#假设的target :1,2,3,4,5,6,7,8,9,10,此时输出为:tensor([  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.]),为一个向量,但output输出为1*10的矩阵,因此会出现不匹配问题。报错:RuntimeError: input and target shapes do not match: input [1 x 10], target [10] at /opt/conda/conda-bld/pytorch_1524584710464/work/aten/src/THNN/generic/MSECriterion.c:13。

但书上和某些博客确实有正常输出,因此改点有待研究。

2.如果对于loss进行反向传播,(使用grad_fn属性),可看到它的计算图。当调用loss.backward()时,该图会生成并自动微分,也会求出计算图中的参数的导数。

print(loss)
#运用.backward,观察调用之前和调用之后的grad
print(loss.grad_fn)
print(loss.grad_fn.next_functions)
print(loss.grad_fn.next_functions[0][0].next_functions)
net.zero_grad()#所有参数的梯度清零
print('反向传播之前的conv1.bias的梯度')
print(net.conv1.bias.grad)
loss.backward()
print('反向传播之后的conv1.bias的梯度')
print(net.conv1.bias.grad)

out:

<MseLossBackward object at 0x7f80b5af9320>
((<AddmmBackward object at 0x7f80b5728cc0>, 0),)
((<ExpandBackward object at 0x7f80b5728cc0>, 0), (<ReluBackward object at 0x7f80b57009b0>, 0), (<TBackward object at 0x7f80f0ac7198>, 0))
反向传播之前的conv1.bias的梯度
tensor([ 0.,  0.,  0.,  0.,  0.,  0.])
反向传播之后的conv1.bias的梯度
tensor(1.00000e-02 *
       [-0.2564,  0.5056,  0.5424,  0.2758, -1.5066, -0.0828])

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值