深度学习实验(四)——卷积神经网络编程

2023-11-10

深度学习实验四:卷积神经网络编程

本次实验练习使用torch.nn中的类设计一个卷积神经网络进行MNIST手写体数字图像分类。

name = 'x'#填写你的姓名
sid = 'B02014152'#填写你的学号

print('姓名:%s, 学号:%s'%(name, sid))
姓名:x, 学号:B02014152
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

1. 设计CNN类

从torch.nn.Module派生一个子类CNN,表示一个卷积神经网络;

请合理设计网络各个层,尝试使用不同的结构,比如skip connection, batch normalization,group convolution等。

你的网络模型中至少有2个卷积层、2个聚合层。

#在下面添加代码,实现卷积神经网络,用于识别MNIST手写体数字
# conv1 = nn.Conv2d(in_channels = 3, out_channels = 16, kernel_size = 3, padding = 0) # Valid Conv
# conv2 = nn.Conv2d(in_channels = 3, out_channels = 16, kernel_size = 3, padding = 1) # Same Conv
# conv3 = nn.Conv2d(in_channels = 3, out_channels = 16, kernel_size = 3, padding = 2) # Full Conv

class CNN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.convd1 = nn.Conv2d(in_channels = 1, out_channels = 10, kernel_size = 3, padding = 0)
        self.pool1 = torch.nn.MaxPool2d(kernel_size= 2, stride= 2)
        self.convd2 = nn.Conv2d(in_channels = 10, out_channels = 20, kernel_size = 3, padding = 0)
        self.pool2 = torch.nn.MaxPool2d(kernel_size= 2, stride= 2)
        self.fc = torch.nn.Linear(500, 10)

    def forward(self, x):
        x.cuda()
        batch_size = x.size(0)
        z1 = self.pool1(self.convd1(x))
        a1 = F.relu(z1)
        z2 = self.pool2(self.convd2(a1))
        a2 = F.relu(z2)
        a2 = a2.view(batch_size, -1)
        a2 = self.fc(a2)
        # a2 = F.softmax(a2, dim=0)
        return a2
#测试MLP类
X = torch.rand((32,1,28,28),dtype = torch.float32)
net = CNN()
Y = net(X)
print(Y)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In [482], line 4
      2 X = torch.rand((32,1,28,28),dtype = torch.float32)
      3 net = CNN()
----> 4 Y = net(X)
      5 print(Y)


File ~\AppData\Roaming\Python\Python38\site-packages\torch\nn\modules\module.py:727, in Module._call_impl(self, *input, **kwargs)
    725     result = self._slow_forward(*input, **kwargs)
    726 else:
--> 727     result = self.forward(*input, **kwargs)
    728 for hook in itertools.chain(
    729         _global_forward_hooks.values(),
    730         self._forward_hooks.values()):
    731     hook_result = hook(self, input, result)


Cell In [481], line 19, in CNN.forward(self, x)
     17 batch_size = x.size(0)
     18 x = nn.BatchNorm2d(num_features=1)
---> 19 z1 = self.pool1(self.convd1(x))
     20 a1 = F.relu(z1)
     21 z2 = self.pool2(self.convd2(a1))


File ~\AppData\Roaming\Python\Python38\site-packages\torch\nn\modules\module.py:727, in Module._call_impl(self, *input, **kwargs)
    725     result = self._slow_forward(*input, **kwargs)
    726 else:
--> 727     result = self.forward(*input, **kwargs)
    728 for hook in itertools.chain(
    729         _global_forward_hooks.values(),
    730         self._forward_hooks.values()):
    731     hook_result = hook(self, input, result)


File ~\AppData\Roaming\Python\Python38\site-packages\torch\nn\modules\conv.py:423, in Conv2d.forward(self, input)
    422 def forward(self, input: Tensor) -> Tensor:
--> 423     return self._conv_forward(input, self.weight)


File ~\AppData\Roaming\Python\Python38\site-packages\torch\nn\modules\conv.py:419, in Conv2d._conv_forward(self, input, weight)
    415 if self.padding_mode != 'zeros':
    416     return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),
    417                     weight, self.bias, self.stride,
    418                     _pair(0), self.dilation, self.groups)
--> 419 return F.conv2d(input, weight, self.bias, self.stride,
    420                 self.padding, self.dilation, self.groups)


TypeError: conv2d(): argument 'input' (position 1) must be Tensor, not BatchNorm2d
Y.shape
torch.Size([32, 10])
#了解MLP中的参数
for name,param in net.named_parameters():
    print(name,':',param.size())
convd1.weight : torch.Size([10, 1, 3, 3])
convd1.bias : torch.Size([10])
convd2.weight : torch.Size([20, 10, 3, 3])
convd2.bias : torch.Size([20])
fc.weight : torch.Size([10, 500])
fc.bias : torch.Size([10])
#输出模型
print(net)
CNN(
  (convd1): Conv2d(1, 10, kernel_size=(3, 3), stride=(1, 1))
  (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (convd2): Conv2d(10, 20, kernel_size=(3, 3), stride=(1, 1))
  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc): Linear(in_features=500, out_features=10, bias=True)
)
#用torchsummary输出模型结构
# !pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torchsummary
from torchsummary import summary

summary(net.cuda(), input_size = (1,28,28))
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1           [-1, 10, 26, 26]             100
         MaxPool2d-2           [-1, 10, 13, 13]               0
            Conv2d-3           [-1, 20, 11, 11]           1,820
         MaxPool2d-4             [-1, 20, 5, 5]               0
            Linear-5                   [-1, 10]           5,010
================================================================
Total params: 6,930
Trainable params: 6,930
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.09
Params size (MB): 0.03
Estimated Total Size (MB): 0.12
----------------------------------------------------------------

2.训练模型

2.1 第一步,对数据做预处理

MNIST图像的像素取值范围是[0,1],先把值域改变为[-1,1]. 在PyTorch中,可以使用torchvision.transforms.Normalize类处理。

from torchvision import datasets,transforms

#构造一个变换,将像素值范围变换到[-1,1]
normalizer =  transforms.Normalize((0.5,), (0.5,))#一行代码
#定义一个变换序列transform,包含两个变换:第一个将PIL图像转换为张量,第二个是normalizer

transform = transforms.Compose([transforms.ToTensor(), normalizer]) #一行代码

2.2 第二步,构造训练集,加入预处理

data_path = '../data/'
mnist_train = datasets.MNIST(data_path,download=False,train = True,transform = transform)
mnist_test =  datasets.MNIST(data_path,download=False,train = False,transform = transform)

2.3 第三步,构造加载器

batch_size = 32 #可以自己定义batch_size大小
train_loader = torch.utils.data.DataLoader(mnist_train, batch_size = batch_size, shuffle = True)
test_loader = torch.utils.data.DataLoader(mnist_test, batch_size = batch_size, shuffle = False)
#从加载器里获取一批样本,并输出样本张量的形状
imgs,labels = iter(train_loader).next()#一行样本
imgs.shape
torch.Size([32, 1, 28, 28])
labels.shape
torch.Size([32])

2.4 第四步,训练模型

注意:训练卷积神经网络时,网络的输入是四维张量,尺寸为 N × C × H × W N\times C \times H \times W N×C×H×W,分别表示张量

def Train(model, loader, epochs, lr = 0.1):
    epsilon = 1e-6
    
    #将model置于train模式
    #一行代码
    net.train()

    
    #定义合适的优化器
    optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)#一行代码
    
    #定义损失函数
    loss = F.cross_entropy#一行代码
    
    #请在下面完成训练代码
    #请在迭代过程中每100次迭代,输出一次损失
    loss0 = 0
    for epoch in range(epochs):
        for it,(imgs, labels) in enumerate(loader):
            #1. zero_grads
            #请用一行代码实现
            optimizer.zero_grad()
            imgs, labels = imgs.cuda(), labels.cuda()

            #2. F.P.前向传播
            #请用一行代码实现
            logits = model(imgs)

            #3. 计算损失            
            loss1 = loss(logits, labels)#请用一行代码实现
            
            if(abs(loss1.item() - loss0)<epsilon):
                break
                
            loss0 = loss1.item()
                
            if it%100==0:
                print('epoch %d, iter %d, loss = %f\n'%(epoch,it,loss1.item()))
                
            #4. 后向传播
            #请用一行代码实现
            loss1.backward()
            
            #5. 梯度下降
            #请用一行代码实现.
            optimizer.step()

    
            
    return model            
#训练模型

model = CNN()
model = model.cuda()

model = Train(model, test_loader, 10)
epoch 0, iter 0, loss = 2.317181

epoch 0, iter 100, loss = 1.612653

epoch 0, iter 200, loss = 0.475313

epoch 0, iter 300, loss = 0.267556

epoch 1, iter 0, loss = 0.272252

epoch 1, iter 100, loss = 0.387812

epoch 1, iter 200, loss = 0.248591

epoch 1, iter 300, loss = 0.130585

epoch 2, iter 0, loss = 0.101499

epoch 2, iter 100, loss = 0.289020

epoch 2, iter 200, loss = 0.127526

epoch 2, iter 300, loss = 0.072299

epoch 3, iter 0, loss = 0.069821

epoch 3, iter 100, loss = 0.237272

epoch 3, iter 200, loss = 0.073975

epoch 3, iter 300, loss = 0.052888

epoch 4, iter 0, loss = 0.055265

epoch 4, iter 100, loss = 0.210844

epoch 4, iter 200, loss = 0.046827

epoch 4, iter 300, loss = 0.046028

epoch 5, iter 0, loss = 0.044145

epoch 5, iter 100, loss = 0.192648

epoch 5, iter 200, loss = 0.031938

epoch 5, iter 300, loss = 0.042316

epoch 6, iter 0, loss = 0.036941

epoch 6, iter 100, loss = 0.179299

epoch 6, iter 200, loss = 0.023668

epoch 6, iter 300, loss = 0.039010

epoch 7, iter 0, loss = 0.032049

epoch 7, iter 100, loss = 0.168726

epoch 7, iter 200, loss = 0.018773

epoch 7, iter 300, loss = 0.036361

epoch 8, iter 0, loss = 0.027803

epoch 8, iter 100, loss = 0.158944

epoch 8, iter 200, loss = 0.015419

epoch 8, iter 300, loss = 0.034879

epoch 9, iter 0, loss = 0.024135

epoch 9, iter 100, loss = 0.149009

epoch 9, iter 200, loss = 0.012855

epoch 9, iter 300, loss = 0.033128

2.5 第五步,测试模型

#编写模型测试过程
def Evaluate(model, loader):
    model.eval()
    correct = 0
    counts = 0
    for imgs, labels in loader:
        imgs, labels = imgs.cuda(), labels.cuda()
        logits = model(imgs)
        yhat = logits.argmax(dim = 1)
        correct = correct + (yhat==labels).sum().item()
        counts = counts + imgs.size(0)
    
    accuracy = correct / counts
    
    return accuracy
acc = Evaluate(model,test_loader)
print('Accuracy = %f'%(acc))
Accuracy = 0.974000
imgs,labels  = next(iter(test_loader))
imgs, labels = imgs.cuda(), labels.cuda()

logits = model(imgs)

imgs, labels = imgs.cpu(), labels.cpu()

yhat = logits.argmax(dim = 1)

plt.figure(figsize = (16,10))
for i in range(imgs.size(0)):
    plt.subplot(4,8,i+1)
    plt.imshow(imgs[i].squeeze()/2+0.5,cmap = 'gray')
    plt.axis('off')
    plt.title('GT=%d, Pred = %d'%(labels[i],yhat[i]))
    
plt.show()

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习实验(四)——卷积神经网络编程 的相关文章

  • Spark 请求最大计数

    我是 Spark 的初学者 我尝试请求允许我检索最常访问的网页 我的要求如下 mostPopularWebPageDF logDF groupBy webPage agg functions count webPage alias cntW
  • Python模块可以访问英语词典,包括单词的定义[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 python 模块 它可以帮助我从英语词典中获取单词的定义 当然有enchant 这可以帮助我检查该单词是否存在于英语中
  • 如何使用 Plotly 中的直方图将所有离群值分入一个分箱?

    所以问题是 我可以在 Plotly 中绘制直方图 其中所有大于某个阈值的值都将被分组到一个箱中吗 所需的输出 但使用标准情节Histogram类我只能得到这个输出 import pandas as pd from plotly import
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • 如何使用 imaplib 获取“消息 ID”

    我尝试获取一个在操作期间不会更改的唯一 ID 我觉得UID不好 所以我认为 Message ID 是正确的 但我不知道如何获取它 我只知道 imap fetch uid XXXX 有人有解决方案吗 来自 IMAP 文档本身 IMAP4消息号
  • Django 模型在模板中不可迭代

    我试图迭代模型以获取列表中的第一个图像 但它给了我错误 即模型不可迭代 以下是我的模型和模板的代码 我只需要获取与单个产品相关的列表中的第一个图像 模型 py class Product models Model title models
  • 填充两个函数之间的区域

    import matplotlib pyplot as plt import numpy as np def domain x np arange 0 10 0 001 f1 lambda x 2 x x 2 0 5 plt plot x
  • 从零开始的 numpy 形状意味着什么

    好的 我发现数组的形状中可以包含 0 对于将 0 作为唯一维度的情况 这对我来说是有意义的 它是一个空数组 np zeros 0 但如果你有这样的情况 np zeros 0 100 让我很困惑 为什么这么定义呢 据我所知 这只是表达空数组的
  • 如何通过在 Python 3.x 上按键来启动和中断循环

    我有这段代码 当按下 P 键时会中断循环 但除非我按下非 P 键 否则循环不会工作 def main openGame while True purchase imageGrab if a sum gt 1200 fleaButton ti
  • 首先对列表中最长的项目进行排序

    我正在使用 lambda 来修改排序的行为 sorted list key lambda item item lower len item 对包含元素的列表进行排序A1 A2 A3 A B1 B2 B3 B 结果是A A1 A2 A3 B
  • 将 JSON 对象传递给带有请求的 url

    所以 我想利用 Kenneth 的优秀请求模块 https github com kennethreitz requests 在尝试使用时偶然发现了这个问题自由库API http wiki freebase com wiki API 基本上
  • 如何使用列表作为pandas数据框中的值?

    我有一个数据框 需要列的子集包含具有多个值的条目 下面是一个带有 运行时 列的数据框 其中包含程序在各种条件下的运行时 df condition a runtimes 1 1 5 2 condition b runtimes 0 5 0 7
  • 在 Pandas 中使用正则表达式的多种模式

    我是Python编程的初学者 我正在探索正则表达式 我正在尝试从 描述 列中提取一个单词 数据库名称 我无法给出多个正则表达式模式 请参阅下面的描述和代码 描述 Summary AD1 Low free DATA space in data
  • 使用 Firefox 绕过弹出窗口下载文件:Selenium Python

    我正在使用 selenium 和 python 来从中下载某些文件web page http www oceanenergyireland com testfacility corkharbour observations 我之前一直使用设
  • 如何为每个屏幕添加自己的 .py 和 .kv 文件?

    我想为每个屏幕都有一个单独的 py 和 kv 文件 应通过 main py main kv 中的 ScreenManager 选择屏幕 设计应从文件 screen X kv 加载 类等应从文件 screen X py 加载 Screens
  • Ubuntu 上的 Python 2.7

    我是 Python 新手 正在 Linux 机器 Ubuntu 10 10 上工作 它正在运行 python 2 6 但我想运行 2 7 因为它有我想使用的功能 有人敦促我不要安装 2 7 并将其设置为我的默认 python 我的问题是 如
  • 具有自定义值的 Django 管理外键下拉列表

    我有 3 个 Django 模型 class Test models Model pass class Page models Model test models ForeignKey Test class Question model M
  • 从 Twitter API 2.0 获取 user.fields 时出现问题

    我想从 Twitter API 2 0 端点加载推文 并尝试获取标准字段 作者 文本 和一些扩展字段 尤其是 用户 字段 端点和参数的定义工作没有错误 在生成的 json 中 我只找到标准字段 但没有找到所需的 user fields 用户
  • 列表值的意外更改

    这是我的课 class variable object def init self name name alias parents values table name of the variable self name 这是有问题的函数 f
  • 您可以使用关键字参数而不提供默认值吗?

    我习惯于在 Python 中使用这样的函数 方法定义 def my function arg1 None arg2 default do stuff here 如果我不供应arg1 or arg2 那么默认值None or default

随机推荐

  • 【拆盲盒啦】摸鱼时间到! iPhone 12、AirPods Pro、罗技鼠标等你拆~

    喜迎开学季 C 站开豪礼 最高可开 iphone 12 盲盒开出的不只是一份礼物 更是对于一切美好的期待 拆开一个盲盒 就像开始一场未知的爱丽丝梦游仙境 为 两点一线 朝九晚九 的生活 埋下一刻期待的种子 去收获一份未知的惊喜 这次 价格再
  • C++面向对象求圆的周长和面积

    include
  • 物联网上行数据实现tcp 负载均衡和高可用架构 nginx + keepalived方案

    文章目录 需求介绍 架构设计 具体配置 nginx 配置 keepalived 配置 需求介绍 之前有做过一个物联网设备接入的项目 项目中会启动一个数据接入服务 TCP server 用来接收传感器设备上传的数据 数据接入服务需要分布式部署
  • 文件系统的基本认知笔记

    1 什么是文件系统 常规认知 Linux下的根目录 文件系统是操作系统用于明确存储设备 常见的是磁盘 也有基于NAND Flash的固态硬盘 或分区上的文件的方法 即在存储设备上组织文件的方法 这种所谓的方法就是文件管理系统 程序 简称文件
  • Mac下使用Git和Git客户端

    先到git官网 https git scm com download 下载安装 这里的git服务器使用本地虚拟机centos来模拟 创建一个用户 名为gitter 用于专门管理git相关 adduser gitter passwd gitt
  • 飞翔的圆(Flappy Bird)游戏源码完整版

    这个源码是一个不错的休闲类的游戏源码 飞翔的圆 Flappy Bird 游戏源码V1 0 本项目是一个仿Flappy Bird的小游戏 只不过是把Flappy Bird里面的鸟替换成了简单的圆 感兴趣的朋友可以研究一下 本项目默认编码GBK
  • 【Ubuntu安装 Nginx】

    ubuntu安装nginx 目前支持两种安装方式 一种是apt get的方式 另一种是根据包安装的方式 为方便我统一使用root用户 一 apt get安装nginx 切换至root用户 sudo su root apt get insta
  • C语言深度剖析——bool类型,浮点数相等比较。

    目录 序言 一 bool类型 1 C语言中到底有没有bool类型 2 VS中的BOOL类型 二 浮点数与 0 比较 1 浮点数的精度缺失 2 浮点数判断相等解决方案 3 判断浮点数是否为 0 最后 序言 C语言中有很多类型 但是bool我们
  • 【AI人工智能】 最强大的语言模型镜像 使用起来真的太方便了! 真的要解放代码思维了吗?

    个人主页 极客小俊 作者简介 web开发者 设计师 技术分享博主 希望大家多多支持一下 我们一起进步 如果文章对你有帮助的话 欢迎评论 点赞 收藏 加关注 前言 AI 在某些基础应用领域可以帮助你减少很多工作量 很强大哦 嘿嘿 优点 这玩意
  • VS2017 libTorch cpu 环境搭建

    C libTorch cpu 环境搭建 一 下载libTorch 下载地址 Start Locally PyTorch 可以在图中选择下载cuda版本或cpu版本的 以CPU Release版本的libTorch为例 下载地址为 https
  • Druid连接池 一个设置 removeAbandonedTimeout

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Druid连接池 一个设置 removeAbandonedTimeout 博客分类 数据库
  • 软件开发外包:你有什么选择

    在2019年 软件开发外包提供了各种各样的选择 成千上万的公司在全球范围内提供软件开发外包服务 您将有很多选择 具体取决于许多标准 例如地理位置 时差 语言要求 甚至文化相似性 2019年的软件开发外包状况如何 在过去的10到15年中 发达
  • 自己封装 vue3+ts 组件库并且发布到 NPM

    自己封装 vue3 ts 组件库并且发布到 NPM 创建项目 pnpm create vite 配置 package json 按照提示创建好项目 然后再 package json 中进行如下配置 name tribiani vue too
  • zip解压

    1 使用apache的ant解压 org apache tools zip 2 引入pom
  • [C++](26)智能指针

    文章目录 引入 智能指针的原理 C 智能指针及其问题 auto ptr unique ptr shared ptr weak ptr 删除器 引入 首先看下面这个程序 int div int a b cin gt gt a gt gt b
  • 服务器安装系统绑定网卡,HPE ProLiant 系列服务器Microsoft Windows Server 2012系统下网卡绑定方法...

    微软NIC组合 也称为负载平衡 故障转移 LBFO 允许多个网络适配器组合成一个 这样做的目的可以带来带宽聚合 解决网络连接失败过程中的故障转移 它应用于Windows Server 2012的所有版本中 包括核心版和图形界面完全版 1 打
  • 2022年,普通人如何找到适合的副业?

    这几天高温天气不适合户外工作和活动 坐在家里一动不动都能出汗 温度直飙升到40度以上了 同时我国的其他地方也阴雨连绵甚至有洪灾的可能性 每年夏季到来都会面临高温 暴雨 洪水 泥石流的恶劣天气 大自然也有脾气 所以我们还是要善待大自然爱护环境
  • mysql 创建function

    mysql 的function和procedure 仅对5 0版本后的有效 包括show function status等命令是没用的 以创建function为例 存储过程和这个差不多 懒得打字了 首先先在mysql 下运行 set glo
  • 基于MATLAB实现CAD技术及其应用完整教程(附上完整源码+数据+使用说明)

    MATLAB是一种功能强大的计算机辅助设计 CAD 工具 它为工程师和设计师提供了一种高效 灵活的方式来创建 分析和优化各种设计 在本文中 我们将介绍MATLAB如何实现CAD技术 并探讨其在不同领域中的应用 文章目录 介绍 部分源码 完整
  • 深度学习实验(四)——卷积神经网络编程

    深度学习实验四 卷积神经网络编程 本次实验练习使用torch nn中的类设计一个卷积神经网络进行MNIST手写体数字图像分类 name x 填写你的姓名 sid B02014152 填写你的学号 print 姓名 s 学号 s name s