深度学习实验(五)——循环神经网络编程

news2024/11/18 16:31:27

深度学习实验五:循环神经网络编程

本次实验练习使用torch.nn中的类设计一个循环神经网络进行MNIST图像分类。

在本次实验中,你要设计一个CNN,用于将 28 × 28 28 \times 28 28×28的MNIST图像转换为 M × M × D M\times M\times D M×M×D的特征图,将该特征图看作是一个长度为 M × M M\times M M×M的特征序列,序列中每一个特征向量的大小为 D D D,然后使用RNN对该序列分类。

name = '杨宇海'#填写你的姓名
sid = 'B02014152'#填写你的学号

print('姓名:%s, 学号:%s'%(name, sid))

姓名:杨宇海, 学号: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. 准备数据

from torchvision import datasets,transforms
#定义变换
#一行代码,提示:transforms.Compose()函数
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
    ])
data_path = '../data/'
mnist_train = datasets.MNIST(data_path,download=True,train = True,transform = transform)
mnist_test =  datasets.MNIST(data_path,download=True,train = False,transform = transform)
mnist_train

Dataset MNIST
Number of datapoints: 60000
Root location: ../data/
Split: Train
StandardTransform
Transform: Compose(
ToTensor()
Normalize(mean=(0.5,), std=(0.5,))
)

#显示图像样本
mnist_iter = iter(mnist_train)
plt.figure(figsize = [16,10])
for i in range(8):
    im,label = next(mnist_iter)
    im = (im.permute((1,2,0))+1)/2
    plt.subplot(1,8,i+1)
    plt.imshow(im)
    plt.title('label = %d'%(label))
    plt.axis('off')
    
plt.show()

2. 设计CNN类

从torch.nn.Module派生一个子类CNN,表示一个卷积神经网络;用于将 MNIST 图像转换为一个𝑀×𝑀×𝐷 的特征图

#在下面添加代码,实现一个CNN,用于提取图像特征
class CNN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.convd1 = nn.Conv2d(in_channels = 1, out_channels = 16, kernel_size = 2, padding = 0)
        self.pool1 = torch.nn.MaxPool2d(kernel_size= 2, stride= 1)
        self.convd2 = nn.Conv2d(in_channels = 16, out_channels = 32, kernel_size = 2, padding = 0)
        self.pool2 = torch.nn.MaxPool2d(kernel_size= 2, stride= 2)
        self.convd3 = nn.Conv2d(in_channels = 32, out_channels = 64, kernel_size = 2, padding = 0)
        self.pool3 = torch.nn.MaxPool2d(kernel_size= 2, stride= 1)
        self.convd4 = nn.Conv2d(in_channels = 64, out_channels = 128, kernel_size = 2, padding = 0)
        self.pool4 = torch.nn.MaxPool2d(kernel_size= 2, stride= 2)

    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)
        z3 = self.pool3(self.convd3(a2))
        a3 = F.relu(z3)
        z4 = self.pool4(self.convd4(a3))
        a4 = F.relu(z4)
        return a4
    
    
#测试CNN类
X = torch.rand((5,1,28,28),dtype = torch.float32)
net = CNN()
Y = net(X)
print(Y.shape)

torch.Size([5, 128, 4, 4])

#输出模型
print(net)

CNN(
(convd1): Conv2d(1, 16, kernel_size=(2, 2), stride=(1, 1))
(pool1): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
(convd2): Conv2d(16, 32, kernel_size=(2, 2), stride=(1, 1))
(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(convd3): Conv2d(32, 64, kernel_size=(2, 2), stride=(1, 1))
(pool3): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
(convd4): Conv2d(64, 128, kernel_size=(2, 2), stride=(1, 1))
(pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)

!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torchsummary
from torchsummary import summary

# summary(net, input_size = (1,28,28))
summary(net.cuda(), input_size = (1,28,28))
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1           [-1, 16, 27, 27]              80
         MaxPool2d-2           [-1, 16, 26, 26]               0
            Conv2d-3           [-1, 32, 25, 25]           2,080
         MaxPool2d-4           [-1, 32, 12, 12]               0
            Conv2d-5           [-1, 64, 11, 11]           8,256
         MaxPool2d-6           [-1, 64, 10, 10]               0
            Conv2d-7            [-1, 128, 9, 9]          32,896
         MaxPool2d-8            [-1, 128, 4, 4]               0
================================================================
Total params: 43,312
Trainable params: 43,312
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.56
Params size (MB): 0.17
Estimated Total Size (MB): 0.73
----------------------------------------------------------------

3. 设计分类模型

在分类模型中,使用上面定义的CNN作为特征提取器,用LSTM循环网络构造分类器。你的模型中应该包含一个CNN和一个RNN。

#在下面添加代码,实现一个Classifier类,用CNN和LSTM循环网络构造分类器
class Classifier(nn.Module):
    def __init__(self):
        super().__init__()
        self.cnn = CNN()
        print(self.cnn)
        self.rnn = nn.LSTM(input_size = 128, hidden_size = 16, batch_first = True)
        self.MLP = nn.Sequential(
            # nn.Linear(in_features = 16, out_features = 128),
            # nn.ReLU(),
            # nn.Linear(in_features = 128, out_features = 10)
            nn.Linear(in_features = 16, out_features = 10)
        )
    
    def forward(self, x):
        batch_size = x.size(0)
        # cnn
        x = self.cnn(x)
        
        # 数据维度处理
        x = x.reshape([batch_size, 128, -1]) # B * 128 * 16
        x = x.permute(0, 2, 1) 
        # print(x.shape) # B * 16 * 128

        # rnn
        h, c = self.rnn(x) # h [N * L * hitsize]
        # print(h.squeeze().shape)
        
        # MLP
        logit = self.MLP(h[:,-1,:])
        return logit
     
#测试上面的类
model = Classifier()#一行代码
X = torch.randn(5,1,28,28)
Y = model(X)
print(Y.shape)
CNN(
  (convd1): Conv2d(1, 16, kernel_size=(2, 2), stride=(1, 1))
  (pool1): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
  (convd2): Conv2d(16, 32, kernel_size=(2, 2), stride=(1, 1))
  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (convd3): Conv2d(32, 64, kernel_size=(2, 2), stride=(1, 1))
  (pool3): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
  (convd4): Conv2d(64, 128, kernel_size=(2, 2), stride=(1, 1))
  (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
torch.Size([5, 10])

4.训练模型

4.1 第一步,构造加载器,用于加载上面定义的数据集

train_loader = torch.utils.data.DataLoader(mnist_train, batch_size = 32, shuffle = True)
test_loader = torch.utils.data.DataLoader(mnist_test, batch_size = 32, shuffle = False)
imgs,labels = next(iter(train_loader))
imgs.shape

torch.Size([32, 1, 28, 28])

labels.shape

torch.Size([32])

4.2 第二步,训练模型

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

#添加代码,完成下面的训练函数
def Train(model, loader, epochs, lr = 0.1):
    '''
    model:模型对象
    loader:数据加载器
    '''
    epsilon = 1e-6
    model.train()
    optimizer = optim.SGD(params=model.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()  # 损失函数
    
    loss0 = 0
    for epoch in range(epochs):
        for iter, data in enumerate(loader):
            features, labels = data
            optimizer.zero_grad() # 梯度清空
            logits = model(features)

            loss1 = loss(logits, labels)
            if(abs(loss1.item() - loss0) < epsilon):
                break
            loss0 = loss1.item()

            if iter%100==0:
                print('epoch %d, iter %d, loss = %f\n'%(epoch,iter,loss0))

            # 反向传播
            loss1.backward()

            # 梯度下降   
            optimizer.step()
    return model                
            
#构造并训练模型
model = Classifier()

model = Train(model, test_loader, 10, 0.1)
CNN(
  (convd1): Conv2d(1, 16, kernel_size=(2, 2), stride=(1, 1))
  (pool1): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
  (convd2): Conv2d(16, 32, kernel_size=(2, 2), stride=(1, 1))
  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (convd3): Conv2d(32, 64, kernel_size=(2, 2), stride=(1, 1))
  (pool3): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
  (convd4): Conv2d(64, 128, kernel_size=(2, 2), stride=(1, 1))
  (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
epoch 0, iter 0, loss = 2.301467

epoch 0, iter 100, loss = 2.279888

epoch 0, iter 200, loss = 2.084048

epoch 0, iter 300, loss = 1.706302

epoch 1, iter 0, loss = 1.520445

epoch 1, iter 100, loss = 1.137834

epoch 1, iter 200, loss = 0.864159

epoch 1, iter 300, loss = 0.567380

epoch 2, iter 0, loss = 0.723860

epoch 2, iter 100, loss = 0.599388

epoch 2, iter 200, loss = 0.428438

epoch 2, iter 300, loss = 0.232027

epoch 3, iter 0, loss = 0.509207

epoch 3, iter 100, loss = 0.344112

epoch 3, iter 200, loss = 0.306382

epoch 3, iter 300, loss = 0.150422

epoch 4, iter 0, loss = 0.357463

epoch 4, iter 100, loss = 0.193024

epoch 4, iter 200, loss = 0.130213

epoch 4, iter 300, loss = 0.079743

epoch 5, iter 0, loss = 0.460217

epoch 5, iter 100, loss = 0.201989

epoch 5, iter 200, loss = 0.095881

epoch 5, iter 300, loss = 0.049980

epoch 6, iter 0, loss = 0.552857

epoch 6, iter 100, loss = 0.206212

epoch 6, iter 200, loss = 0.068986

epoch 6, iter 300, loss = 0.038401

epoch 7, iter 0, loss = 0.481544

epoch 7, iter 100, loss = 0.123809

epoch 7, iter 200, loss = 0.069442

epoch 7, iter 300, loss = 0.030164

epoch 8, iter 0, loss = 0.306035

epoch 8, iter 100, loss = 0.083185

epoch 8, iter 200, loss = 0.052271

epoch 8, iter 300, loss = 0.038275

epoch 9, iter 0, loss = 0.275993

epoch 9, iter 100, loss = 0.108630

epoch 9, iter 200, loss = 0.052308

epoch 9, iter 300, loss = 0.026095

4.3 第三步,测试模型

#编写模型测试过程
def Evaluate(model, loader):
    model.eval()
    correct = 0
    counts = 0
    for imgs, labels in loader:
        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.961000

imgs,labels  = next(iter(test_loader))

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135953.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我,做了两年程序员,存了巨款5000,你们拿什么跟我比?

&#x1f550;没错&#xff0c;标题所见&#xff0c;从21年1月份开始从事程序员工作也过了两年了&#xff0c;今年还是没有存到钱。 今年换了一份工作&#xff0c;四月份的时候&#xff0c;从惠州换到了广州工作&#xff0c;从制造业转行到了政务行业&#xff0c;工资涨了&…

Keithley 2604B数字源表-安泰测试

Keithley 2600B 系列系统 SMU 仪器是业界标准电流-电压源和测量解决方案&#xff0c;适用于高度自动化生产测试应用。 双通道和单通道型号都紧密集成一个精密电源、真正电流源、数字万用表和具有脉冲生成功能的电子负载。 另外&#xff0c;TSP? 技术可运行完整测试程序&#x…

多点双向重发布的应用

目录 1.拓扑图 2.实验思路 3.主要配置 4.测试 5.实验总结 1.拓扑图 2.实验思路 在配置完RIP和OSPF之后&#xff0c;在2&#xff0c;3号设备上进行多点的双向重发布由于在进行了多点的双向重发布之后&#xff0c;会出现大量的负载均衡&#xff0c;导致选路不佳的问题解决办…

前端工程师leetcode算法面试必备-二叉树深度广度遍历

一、前言 Medium 难度主要考察结合二叉树性质的 CRUD 操作&#xff0c;而这一切的基础都离不开遍历二叉树。 二叉树是图的子集&#xff0c;因而同样适用以下两种搜索思想&#xff1a; **DFS&#xff08;深度优先搜索&#xff09;&#xff1a;**沿着根节点递归下去&#xff0c…

普通程序员怎么赚多份钱?解锁更多赚钱新姿势

在当下这个社会&#xff0c;学会如何make money很重要。 咱们是个俗人&#xff0c;赚钱才是社会生存的头等大事。这不是高山流水的世界&#xff0c;而是能力创造财富&#xff0c;对于程序员来说&#xff0c;更是如此。 作为程序员&#xff0c;我们有更多挣钱的姿势&#xff01;…

通过一个测试项目了解EF CORE

首先用vs2019创建一个.net core项目 可以是控制台应用程序,也可以是asp.net core项目 如果你使用控制台应用程序, 则可以在Main方法中直接使用EF Core进行CRUD操作。这通常用于测试或开发时快速进行数据库操作。 如果你使用ASP.NET Core应用程序, 则可以在控制器中使用EF Cor…

低温超导系统中实现液氦温度准确控制的解决方案

摘要&#xff1a;针对目前两种典型低温超导测试系统中存在的液氦压力控制精度较差的问题&#xff0c;本文提出了相应的解决方案。解决方案分别采用了直接压力控制和流量控制两种技术手段和配套数控阀门&#xff0c;结合24位AD和16位DA的超高精度的PID真空压力控制器和压力传感器…

第三十九章 贪心算法——区间问题(下)

第三十九章 贪心算法——区间问题&#xff08;下&#xff09;一、区间问题1&#xff1a;最大不相交区间数量1、思路详解2、代码实现二、区间问题2&#xff1a;区间覆盖1、问题2、思路3、代码一、区间问题1&#xff1a;最大不相交区间数量 1、思路详解 这道题和前一章讲的最后一…

IDEA 使用的小技巧

1、调整 idea 的虚拟内存&#xff1a; 尽管本质都是去改变 .vmoptions 配置文件&#xff0c;但推荐使用Change Memory Settings去调整&#xff0c;选择Edit Custom VM Options 或者在本地磁盘目录更改&#xff0c;通过某些方法破解的 idea 很可能造成 idea 打不开的情况 2、显…

【数据结构-源码分析】HashMap源码分析(超级详细)

文章内容1、HashMap简介2、类结构3、属性4、构造方法5、方法5.1、put方法5.2、resize方法6、jdk1.8的优化1、HashMap简介 HashMap基于哈希表的Map接口实现&#xff0c;是以key-value存储形式存在。&#xff08;除了不同步和允许使用 null 之外&#xff0c;HashMap 类与 Hashta…

Oracle数据库同步复制工具Beedup产品功能(二)

接续...... 8、对象比较 Beedup提供主从库相关对象比较功能&#xff0c;比对结果包含各类对象概要统计及差异详情。 支持Oracle、SQL Server、MySQL、DB2 对象比较。 9、 对象恢复 Beedup在向从库写入数据时会禁用目标表的关联触发器&#xff0c;另外对于Oracle 序列的状态…

MySQL复制技术方案——GTID复制配置

在日常运维中&#xff0c;GTID带来的最方便的作用就是搭建和维护主从复制&#xff0c;这也是DBA日常工作中最经常的操作了。GTID的主从模式替代了MySQL前期版本中利用二进制日志文件的名称和日志位置的做法&#xff0c;使用GTID使操作和维护都变得更加简洁和可靠。 搭建主从时…

SQL SELECT 语句

SELECT 语句用于从数据库中选取数据。 SQL SELECT 语句 SELECT 语句用于从数据库中选取数据。 结果被存储在一个结果表中&#xff0c;称为结果集。 SQL SELECT 语法 SELECT column1, column2, ... FROM table_name; 与 SELECT * FROM table_name; 参数说明&#xff1a; …

SVM训练莺尾花数据集

SVM训练莺尾花数据集 代码在莺尾花数据集上训练SVM&#xff0c;数据集由莺尾花的测量值及其相应的物种标签组成。该模型使用70%数据用于训练&#xff0c;然后剩余部分进行测试。其中′fit′fit′fit′方法在训练集上训练数据&#xff0c;′score′score′score′数据在返回模型…

HTC FOCUS3在PC端串流FOHEART H1数据手套(腕带)

本教程介绍使用FOHEART H1数据手套与HTC腕带式追踪器驱动VR中的虚拟手运动&#xff0c;实现手部的追踪及定位。与之前教程&#xff08;HTC FOCUS 3连接FOHEART H1数据手套&#xff09;不同&#xff0c;这次我们的场景内容运行在PC端&#xff0c;而不是头显端&#xff0c;使用VI…

基于Vue和SpringBoot的电商管理系统的设计与实现

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

8.mysql模块

目录 1 安装mysql模块 2 建立与mysql的连接 3 执行SQL语句 3.1 查询数据 3.2 插入数据 3.2.1 直接写入SQL语句 3.2.2 使用问号进行占位 3.2.3 使用对象传入 3.3 更新数据 3.3.1 使用问号进行占位 3.3.2 使用对象传入 3.4 删除数据 常见的数据库有下面几…

光驱重装系统教程

光驱重装系统是使用最长的系统安装方法&#xff0c;最早时候电脑都有光驱的&#xff0c;很多用户重装电脑系统的时候都会使用光驱重装系统&#xff0c;现在小编来为大家详细的介绍一下光驱重装系统的教程。 工具/原料&#xff1a; 系统版本&#xff1a;win7系统 品牌型号&#…

仪表板工具Stimulsoft Dashboards中的面板组件介绍

Stimulsoft Dashboards.JS是一个功能齐全的仪表盘工具&#xff0c;用于为JavaScript平台创建仪表板。 Stimulsoft Dashboards.JS官方正版下载&#xff08;qun&#xff1a;740060302&#xff09;https://www.evget.com/product/4101/download在上一篇文章中&#xff0c;主要介绍…

剑指 Offer 24. 反转链表

一、题目 定义一个函数&#xff0c;输入一个链表的头节点&#xff0c;反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 限制&#xff1a; 0 < 节点个数 < 5000 二、题目解析&…