神经网络与深度学习入门记录005——Pytorch搭建卷积网络

Pytorch搭建基础卷积网络检测Mnist

思路:
1.加载本地mnist数据集
2.搭建网络结构
3.训练
4.测试训练模型

加载数据

import torch as tch
import torchvision.datasets.mnist as mnist
from torch.utils.data import DataLoader
def main():
    train_set = (
        mnist.read_image_file( \
            'D:/mnist/train-images.idx3-ubyte'),
        mnist.read_label_file( \
            'D:/mnist/train-labels.idx1-ubyte')
    )
    test_set = (
        mnist.read_image_file( \
            'D:/mnist/t10k-images.idx3-ubyte'),
        mnist.read_label_file( \
            'D:/mnist/t10k-labels.idx1-ubyte')
    )
    #数据分组
    train_data=[[x.view(1,28,28)/255,y]for (x,y) in zip(train_set[0],train_set[1])]
    test_data=[[x.view(1,28,28)/255,y]for (x,y) in zip(test_set[0],test_set[1])]
    #转换batch_size
    train_dataload=DataLoader(train_data,batch_size=10)
    test_dataload=DataLoader(test_data,batch_size=10)

    return train_dataload,test_dataload
main()

遇到的问题:
1.Dataloader可将数据小批量分组,调用前需将数据图片与标签足组合[(x1,y1),(x2,y2),…]
2.输入数据要归一化(R/G/B)/255,否则可能造成梯度爆炸grad=nan

网络搭建

import torch as tch
import torch.nn as nn
#网络定义
class Network(nn.Module):
    def __init__(self):
        #继承父类初始化
        super(Network, self).__init__()
        #创建网络序列
        self.model=nn.Sequential(
            nn.Conv2d(1,10,5),  #Conv1:输入1维,输出10维,卷积核大小5
            nn.Sigmoid(),       #Sigmoid激活函数
            nn.MaxPool2d(2),    #池化大小2
            nn.Flatten(),       #展平
            nn.Linear(10*12*12,30),     #全连接层输入10*12*12,输出30
            nn.Sigmoid(),
            nn.Linear(30,10),   #全连接层输入30,输出10
            nn.Softmax(dim=1)   #柔性最大值激活函数
        )
    #前向传播
    def forward(self,x):
        x=self.model(x)
        return x
if __name__=='__main__':
    net=Network()
    inpt=tch.randn(10,1,28,28)
    output=net.model(inpt)
    print(output)

遇到的问题:
1.卷积池化全连接层并不带激活函数,需再调用一层激活层,且从池化到全连接需展平
2.卷积层输入大小input,输出大小output,步长stride,卷积核大小kernel,填充输入数pad
output=(inpt+2*pad-kernel)/stride+1

训练及测试

from model import *
import data_load
import sys
def main():
    net=Network()
    #交叉熵损失函数
    loss_fn=nn.CrossEntropyLoss()
    learning_rate=0.5
    epoch=30
    #定义优化器,随机梯度下降
    optimizer=tch.optim.SGD(net.parameters(),lr=learning_rate)
    #获取Mnist数据
    train_data,test_data=data_load.main()
    n_train=len(train_data)
    n_test=len(test_data)
    for i in range(epoch):
        loss_record=0
        n_accuracy=0
        for data in train_data:
            images,labels=data
            #前向传播
            output=net.model(images)
            loss=loss_fn(output,labels)
            loss_record+=loss
            #梯度清除
            optimizer.zero_grad()
            #反向传播
            loss.backward()
            #参数(w,b)更新
            optimizer.step()
        #测试网络
        with tch.no_grad():
            for data in test_data:
                images,labels=data
                output=net.model(images)
                n_accuracy+=(output.argmax(1)==labels).sum()
        loss_record/=len(train_data)
        print('Epoch:{0}\nloss_record:{1}\nAccuracy:{2:.2f}%\n'.format(i,loss_record,n_accuracy/n_test*10))
main()

遇到的问题:
1.交叉熵代价函数nn.CorssEntropyLoss(a,y)
a为网络的(mini batch size,output)两维输出,y为一维整数,分别对应a中的每行的期望

#Example
import torch.nn as nn
import torch as tch
loss_fn=nn.CrossEntropyLoss()
inpt=tch.randn(3,5,requires_grad=True)
target=tch.empty(3,dtype=tch.long).random_(5)
print(inpt,target,sep='\n')
print(loss_fn(inpt,target))

2.torch.optim中存放各类优化器,如SGD(随机梯度下降),用于网络反向传播后,更新网络w、b。
3.net.parameters()返回网络的参数(w,b),在torch.optim.SGD()调用表示需更新的参数
4.进入网络的输入必须是思维tensor,(mini_batch_size,depth,height,witdh)
5.tensor.argmax(a),a=1时横向比较,a=0时纵向比较,返回最大值位置

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值