【Pytorch入门】构造一个小型CNN

neural networks

使用torch.nn包中的工具来构建神经网络
构建一个神经网络需要以下几步:

  • 定义神经网络的权重,搭建网络结构
  • 遍历整个数据集进行训练
    • 将数据输入神经网络
    • 计算loss
    • 计算网络权重的梯度
    • 更新网络权重
      • weight = weight + learning_rate * gradient
import torch
import torch.nn as nn
import torch.nn.functional as F
#nn.Conv2d接受输入4维的Tensor:n个样本*n个色彩频道*高度*宽度

class Net(nn.Module):#需要继承nn.Module这个类
    #Net初始化函数
    def __init__(self):
        super(Net,self).__init__() #调用父类Net的初始化方法
        #建立了两个卷积层:self.conv1,self.conv2,这些层不包括激活函数
        self.conv1=nn.Conv2d(1,6,5) #输入为1个通道, 输出为6个特征图,卷积核为5*5正方形
        self.conv2=nn.Conv2d(6,16,5)#输入为6个通道,输出为16个特征图,卷积核为5*5正方形
        #建立了三个全连接层:全连接函数为线性函数y=wx+b
        self.fc1=nn.Linear(16*5*5,120) #将上一层输出的16*5*5个节点连接到120个节点上
        self.fc2=nn.Linear(120,84)     #将上一层输出的120节点连接到84个节点上
        self.fc3=nn.Linear(84,10)      #将上一层输出的84节点连接到10个节点上
    # 定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
    def forward(self,x):
        x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))#输入x经卷积conv1->经激活函数Relu->使用窗口2*2进行最大池化
        x=F.max_pool2d(F.relu(self.conv2(x)),(2,2))#输入x经卷积conv2->经激活函数Relu->使用窗口2*2进行最大池化
        #x = F.max_pool2d(F.relu(self.conv2(x)), 2) #与上一行2*2等价
        x=x.view(-1,self.num_flat_features(x))#view函数将张量x变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备
        x=F.relu(self.fc1(x)) #输入x经过全连接fc1->经过ReLU激活函数,然后更新x
        x=F.relu(self.fc2(x)) #输入x经过全连接fc2->经过ReLU激活函数,然后更新x
        x=self.fc3(x) #输入x经过全连接fc3,然后更新x
        return  x

    # 使用num_flat_features函数计算张量x的特征总量(把每个数字都看出是一个特征,即特征总量)
    # 比如x是4*2*2的张量,那么它的特征总量就是16。
    def num_flat_features(self,x):
        #pytorch只接受批输入,也就是说一次性输入好几张图片,那么输入数据张量的维度自然上升到了4维。
        size=x.size()[1:]# 这里为什么要使用[1:],【1:】让我们把注意力放在后3维上面
        num_features=1
        for s in size:
            num_features*=s
        return num_features

net=Net()
print(net)
#---------------------------------
params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight
#-----------查看网络结构和参数数量-------------
params = list(net.parameters())
k=0
for i in params:
    l =1
    print("该层的结构:"+str(list(i.size())))
    for j in i.size():
        l *= j
    print("参数和:"+str(l))
    k = k+l

print("总参数和:"+ str(k))

一个完整NN

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
#nn.Conv2d接受输入4维的Tensor:n个样本*n个色彩频道*高度*宽度
########################################################################
# Define a Convolution Neural Network
class Net(nn.Module):#需要继承nn.Module这个类
    #Net初始化函数
    def __init__(self):
        super(Net,self).__init__() #调用父类Net的初始化方法
        #建立了两个卷积层:self.conv1,self.conv2,这些层不包括激活函数
        self.conv1=nn.Conv2d(1,6,5) #输入为1个通道, 输出为6个特征图,卷积核为5*5正方形
        self.conv2=nn.Conv2d(6,16,5)#输入为6个通道,输出为16个特征图,卷积核为5*5正方形
        #建立了三个全连接层:全连接函数为线性函数y=wx+b
        self.fc1=nn.Linear(16*5*5,120) #将上一层输出的16*5*5个节点连接到120个节点上
        self.fc2=nn.Linear(120,84)     #将上一层输出的120节点连接到84个节点上
        self.fc3=nn.Linear(84,10)      #将上一层输出的84节点连接到10个节点上
    # 定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
    def forward(self,x):
        x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))#输入x经卷积conv1->经激活函数Relu->使用窗口2*2进行最大池化
        x=F.max_pool2d(F.relu(self.conv2(x)),(2,2))#输入x经卷积conv2->经激活函数Relu->使用窗口2*2进行最大池化
        #x = F.max_pool2d(F.relu(self.conv2(x)), 2) #与上一行2*2等价
        x=x.view(-1,self.num_flat_features(x))#view函数将张量x变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备
        x=F.relu(self.fc1(x)) #输入x经过全连接fc1->经过ReLU激活函数,然后更新x
        x=F.relu(self.fc2(x)) #输入x经过全连接fc2->经过ReLU激活函数,然后更新x
        x=self.fc3(x) #输入x经过全连接fc3,然后更新x
        return  x

    # 使用num_flat_features函数计算张量x的特征总量(把每个数字都看出是一个特征,即特征总量)
    # 比如x是4*2*2的张量,那么它的特征总量就是16。
    def num_flat_features(self,x):
        #pytorch只接受批输入,也就是说一次性输入好几张图片,那么输入数据张量的维度自然上升到了4维。
        size=x.size()[1:]# 这里为什么要使用[1:],【1:】让我们把注意力放在后3维上面
        num_features=1
        for s in size:
            num_features*=s
        return num_features

net=Net()
print(net)
#如果使用MNIST数据集来训练这个LeNet网络,需要把图片大小重新调整到32*32
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)
#将所有参数的梯度缓存清零,然后进行随机梯度的的反向传播.
net.zero_grad()
out.backward(torch.randn(1, 10))
########################################################################
# Define a Loss function and optimizer
output=net(input)
target=torch.randn(10)
target=target.view(1,-1)
criterion=nn.MSELoss()
loss=criterion(output,target)
print(loss)

# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)
# in your training loop:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值