深度学习 —— 个人学习笔记10(池化层、LeNet)

news2025/1/22 9:09:27

声明

  本文章为个人学习使用,版面观感若有不适请谅解,文中知识仅代表个人观点,若出现错误,欢迎各位批评指正。

二十一、池化层

1、 最大池化层和平均池化层

  与互相关运算符一样,汇聚窗口从输入张量的左上角开始,从左往右、从上往下的在输入张量内滑动。在汇聚窗口到达的每个位置,它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚层还是平均汇聚层。

2、 torch.stack 和 torch.cat 的区别
  • 维度创建:
      torch.stack 会在堆叠时创建一个新的维度,‌将输入张量序列沿着这个新维度进行堆叠。‌这意味着堆叠后的张量的维度比输入张量序列的维度多一。‌
    ‌  torch.cat 不会引入新的维度,‌只在现有的某个维度上对输入张量进行拼接。‌

  • 拼接方式:
      torch.stack 会将输入张量序列按照指定维度进行逐个元素的堆叠,‌生成一个新的张量。‌这要求所有输入张量的形状必须相同。‌
      torch.cat 则会对输入张量进行连接,‌不关心元素的位置,‌只要各个张量的拼接维度匹配即可。‌这种连接方式更加灵活,‌因为它不要求所有输入张量的形状完全相同,‌只要在拼接的维度上尺寸一致即可。

3、 代码演示‌
import torch
from torch import nn

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def pool2d(X, pool_size, mode='max'):
    p_h, p_w = pool_size
    Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1)).to(device)
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            if mode == 'max':
                Y[i, j] = X[i: i + p_h, j: j + p_w].max().to(device)
            elif mode == 'avg':
                Y[i, j] = X[i: i + p_h, j: j + p_w].mean().to(device)
    return Y


X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
print("pool_size = (2, 2) 时 max : ", pool2d(X, (2, 2)))

print("pool_size = (2, 2) 时 avg : ", pool2d(X, (2, 2), 'avg'))

X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4)).to(device)
print(f'X : {X}')

pool2d = nn.MaxPool2d(3)
print("pool = (3, 3) : ", pool2d(X))

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
print("pool = (3, 3), padding = 1, stride = 2 : ", pool2d(X))

pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))
print("pool = (2, 3), padding = (2, 3), stride = (0, 1) : ", pool2d(X))

##### 多个通道 #####
X = torch.cat((X, X + 1), 1)
print(f'X : {X}')

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
print("pool = (3, 3), padding = 1, stride = 2 : ", pool2d(X))

二十二、卷积神经网络(LeNet)

import torch
import torchvision
import time
from torch import nn
from IPython import display
import matplotlib.pyplot as plt
from matplotlib_inline import backend_inline
from torchvision import transforms
from torch.utils import data

mydevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def accuracy(y_hat, y):                                                           # 定义一个函数来为预测正确的数量计数
    """计算预测正确的数量"""
    if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:
        y_hat = y_hat.argmax(axis=1)
    cmp = y_hat.type(y.dtype) == y                                                # bool 类型,若预测结果与实际结果一致,则为 True
    return float(cmp.type(y.dtype).sum())

def evaluate_accuracy_gpu(net, data_iter, device=None):
    """使用GPU计算模型在数据集上的精度"""
    if isinstance(net, nn.Module):
        net.eval()  # 设置为评估模式
        if not device:
            device = next(iter(net.parameters())).device
    # 正确预测的数量,总预测的数量
    metric = Accumulator(2)
    with torch.no_grad():
        for X, y in data_iter:
            if isinstance(X, list):
                # BERT微调所需的(之后将介绍)
                X = [x.to(device) for x in X]
            else:
                X = X.to(device)
            y = y.to(device)
            metric.add(accuracy(net(X), y), y.numel())
    return metric[0] / metric[1]

def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    axes.set_xlabel(xlabel), axes.set_ylabel(ylabel)
    axes.set_xscale(xscale), axes.set_yscale(yscale)
    axes.set_xlim(xlim),     axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    axes.grid()

class Accumulator:                                                                # 定义一个实用程序类 Accumulator,用于对多个变量进行累加
    """在n个变量上累加"""
    def __init__(self, n):
        self.data = [0.0] * n

    def add(self, *args):
        self.data = [a + float(b) for a, b in zip(self.data, args)]

    def reset(self):
        self.data = [0.0] * len(self.data)

    def __getitem__(self, idx):
        return self.data[idx]

class Animator:                                                                   # 定义一个在动画中绘制数据的实用程序类 Animator
    """在动画中绘制数据"""
    def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,
                 ylim=None, xscale='linear', yscale='linear',
                 fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,
                 figsize=(3.5, 2.5)):
        # 增量地绘制多条线
        if legend is None:
            legend = []
        backend_inline.set_matplotlib_formats('svg')
        self.fig, self.axes = plt.subplots(nrows, ncols, figsize=figsize)
        if nrows * ncols == 1:
            self.axes = [self.axes, ]
        # 使用lambda函数捕获参数
        self.config_axes = lambda: set_axes(
            self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
        self.X, self.Y, self.fmts = None, None, fmts

    def add(self, x, y):
        # Add multiple data points into the figure
        if not hasattr(y, "__len__"):
            y = [y]
        n = len(y)
        if not hasattr(x, "__len__"):
            x = [x] * n
        if not self.X:
            self.X = [[] for _ in range(n)]
        if not self.Y:
            self.Y = [[] for _ in range(n)]
        for i, (a, b) in enumerate(zip(x, y)):
            if a is not None and b is not None:
                self.X[i].append(a)
                self.Y[i].append(b)
        self.axes[0].cla()
        for x, y, fmt in zip(self.X, self.Y, self.fmts):
            self.axes[0].plot(x, y, fmt)
        self.config_axes()
        display.display(self.fig)
        # 通过以下两行代码实现了在PyCharm中显示动图
        plt.draw()
        plt.pause(interval=0.001)
        display.clear_output(wait=True)
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

class Timer:
    def __init__(self):
        self.times = []
        self.start()

    def start(self):
        self.tik = time.time()

    def stop(self):
        self.times.append(time.time() - self.tik)
        return self.times[-1]

    def sum(self):
        """Return the sum of time."""
        return sum(self.times)

def load_data_fashion_mnist(batch_size, resize=None):
    """下载 Fashion-MNIST 数据集,然后将其加载到内存中"""
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="../data", train=True, transform=trans, download=False)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="../data", train=False, transform=trans, download=False)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=4),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=4))


net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))

""" 尝试更换不同的激活函数及将平均池化层替换为最大池化层 """
net_demo = nn.Sequential(
    nn.Conv2d(1, 8, kernel_size=5, padding=2), nn.Tanh(),
    nn.MaxPool2d(kernel_size=2, stride=2),
    nn.Conv2d(8, 32, kernel_size=5), nn.Tanh(),
    nn.MaxPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(32 * 5 * 5, 128), nn.Tanh(),
    nn.Linear(128, 84), nn.Tanh(),
    nn.Linear(84, 10))

X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape: \t\t',X.shape)

batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size=batch_size)

def train(net, train_iter, test_iter, num_epochs, lr, device):
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', torch.cuda.get_device_name(device))
    net.to(device)
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()
    animator = Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=['train loss', 'train acc', 'test acc'])
    timer, num_batches = Timer(), len(train_iter)
    for epoch in range(num_epochs):
        # 训练损失之和,训练准确率之和,样本数
        metric = Accumulator(3)
        net.train()
        for i, (X, y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            optimizer.step()
            with torch.no_grad():
                metric.add(l * X.shape[0], accuracy(y_hat, y), X.shape[0])
            timer.stop()
            train_l = metric[0] / metric[2]
            train_acc = metric[1] / metric[2]
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (train_l, train_acc, None))
        test_acc = evaluate_accuracy_gpu(net, test_iter)
        animator.add(epoch + 1, (None, None, test_acc))
    plt.title(f'loss {train_l:.3f}, train acc {train_acc:.3f}, test acc {test_acc:.3f}\n'
              f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec on {str(device)}')
    plt.show()


lr, num_epochs = 0.9, 10
train(net, train_iter, test_iter, num_epochs, lr, mydevice)


def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        try:
            numpy = lambda x, *args, **kwargs: x.detach().numpy(*args, **kwargs)
            img = numpy(img)
        except:
            pass
        ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
            plt.title(titles)
    plt.show()
    return axes

def show_activate(net, train_iter, num_epochs, lr, device):
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', torch.cuda.get_device_name(device))
    net.to(device)
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()
    Animator(xlabel='epoch', xlim=[1, num_epochs], legend=['train loss', 'train acc', 'test acc'])
    for epoch in range(num_epochs):
        net.train()
        for i, (X, y) in enumerate(train_iter):
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            optimizer.step()
            torch.no_grad()
    x_first_Sigmoid_layer = net[0:2](X)[0:9, 1, :, :]
    show_images(x_first_Sigmoid_layer.reshape(9, 28, 28).cpu().detach(), 1, 9, titles=f'第一次 {net[1]}')
    x_second_Sigmoid_layer = net[0:5](X)[0:9, 1, :, :]
    show_images(x_second_Sigmoid_layer.reshape(9, 10, 10).cpu().detach(), 1, 9, titles=f'第二次 {net[4]}')

""" 可多尝试不同情况 """
show_activate(net_demo, train_iter, num_epochs, lr, mydevice)

net = nn.Sequential(
   nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
   nn.AvgPool2d(kernel_size=2, stride=2),
   nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
   nn.AvgPool2d(kernel_size=2, stride=2),
   nn.Flatten(),
   nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
   nn.Linear(120, 84), nn.Sigmoid(),
   nn.Linear(84, 10))

net_demo = nn.Sequential(
   nn.Conv2d(1, 8, kernel_size=5, padding=2), nn.Sigmoid(),
   nn.MaxPool2d(kernel_size=2, stride=2),
   nn.Conv2d(8, 32, kernel_size=5), nn.Sigmoid(),
   nn.MaxPool2d(kernel_size=2, stride=2),
   nn.Flatten(),
   nn.Linear(32 * 5 * 5, 128), nn.Sigmoid(),
   nn.Linear(128, 84), nn.Sigmoid(),
   nn.Linear(84, 10))

net_demo = nn.Sequential(
   nn.Conv2d(1, 8, kernel_size=5, padding=2), nn.Tanh(),
   nn.MaxPool2d(kernel_size=2, stride=2),
   nn.Conv2d(8, 32, kernel_size=5), nn.Sigmoid(),
   nn.MaxPool2d(kernel_size=2, stride=2),
   nn.Flatten(),
   nn.Linear(32 * 5 * 5, 128), nn.Sigmoid(),
   nn.Linear(128, 84), nn.Sigmoid(),
   nn.Linear(84, 10))


  文中部分知识参考:B 站 —— 跟李沐学AI;百度百科

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

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

相关文章

打靶记录6——靶机EvilBox---One

靶机下载地址 https://www.vulnhub.com/entry/evilbox-one,736/学习记录 在进行目录爆破和文件爆破的过程当中,如果有发现新的路径,一定要对新的路径再次进行更深层次的爆破虚拟机出现问题就删除掉,重新导入虚拟机 目标: 获取两个flag&am…

如何准备专利申请书的摘要部分?

如何准备专利申请书的摘要部分?

基于概率神经网络的异方差不确定性估计

目录 摘要1 介绍2 预热3 分析3.1对称性和特征非线性3.2逆方差加权有效欠样本 4 方法5 实验5.1合成数据集5.2真实数据集6 结论 摘要 捕获任意不确定性是许多机器学习系统的关键部分。在深度学习中,达到这一目的的一种常用方法是训练神经网络,通过最大化观…

力扣SQL50 组合两个表 入门基础连表查询

Problem: 175. 组合两个表 select FirstName, LastName, City, State from Person left join Address on Person.PersonId Address.PersonId ;

AI说 | 如何入门AI行业,成为人工智能产品经理?(上)

这周在上海出差,划个水,发一篇之前写的文章,谈谈如何入门AI行业 另外,有朋友说我的文章读起来很累,自我反思,确实写的太长,后面我会在保证有趣或有干货的情况下,将文章内容尽量减短…

《深入浅出WPF》学习笔记四.提高效率,code snippets的使用

《深入浅出WPF》学习笔记四.提高效率,code snippets的使用 背景 再跟着视频教程学习Wpf的过程中,发现这个小技巧。很惭愧好几年开发经验,没用过这个东西。 这个信息差还是很让人头疼的,特别在此分享。 code snippets是什么 Code Snippets是插入代码…

Elasticsearch 未授权访问漏洞

Elasticsearch 未授权访问漏洞 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索…

zabbix监控中文乱码解决方案

zabbix切换中文后,会出现乱码情况,如下图: 解决方案如下: 1、找到字体 WinR打开运行,输入fonts,回车进入Windows字体目录,找到微软雅黑-常规字体,复制出来将文件名修改为msyh.ttf…

Substance Painter工具栏及快捷键

3 菜单栏_哔哩哔哩_bilibili ctrl右键左右滑动调整笔刷大小/左键流量 上下滑动有其他作用 线框显示工具 制作随机效果 Fill要配合遮罩使用 白色遮罩显示底色,黑色遮罩不显示底色 核心工具 图层关系 必须添加在蒙版的效果下 选择中蒙版 滤镜仅能添加在图层下 id图…

k8s中yaml文件的编写

目录 1.编写pod.yaml 2.编写deploment.yaml 3.编写service.yaml关联创建的pod 4.总结获取K8S资源配置清单文件模板方法 方法1:根据现有资源导出yaml文件修改配置,重新创建 方法2:根据现有资源,进入其配置中,复制…

Go语言实现多协程文件下载器

文章目录 前言流程图主函数下载文件初始化分片下载worker分发下载任务获取下载文件的大小下载文件分片错误重试项目演示最后 前言 你好,我是醉墨居士,最近在开发文件传输相关的项目,然后顺手写了一个多协程文件下载器,代码非常精…

Cxx primer-chap12-Dynamic Memory

目前我们使用的对象都是语言本身代替我们管理其生命周期和作用域,例如global object、局部的自动变量和局部的static变量,除此之外,语言也允许我们创建动态分配的对象(即运行时创建的对象):不同类型的对象&…

SpringCloud概述和基本工程搭建

目录 1.认识微服务 1.1单体架构 1.2集群和分布式架构 1.3微服务架构 1.4微服务的优势 2.微服务解决方案-Spring Cloud 2.1什么是Spring Cloud 2.2Spring Cloud Alibaba 2.3SpringCloud实现对比 3.服务拆分原则 3.1单一职责原则 3.2服务自治原则 3.3单向依赖原则 …

前端:Vue

一、引入 Vue是一套前端框架,免除javaScript中的DOM操作,简化书写。基于MVVM思想,实现数据的双向绑定,将编程的关注点放在数据上。 框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。基于…

C#初级——字典Dictionary

字典 字典是C#中的一种集合&#xff0c;它存储键值对&#xff0c;并且每个键与一个值相关联。 创建字典 Dictionary<键的类型, 值的类型> 字典名字 new Dictionary<键的类型, 值的类型>(); Dictionary<int, string> dicStudent new Dictionary<int, str…

深度学习-----------数值稳定性

目录 神经网络的梯度数值稳定性的常见两个问题例子&#xff1a;MLP 梯度爆炸梯度爆炸的问题 梯度消失梯度消失的问题 总结模型初始化和激活函数让训练更加稳定让每层的方差是一个常数 权重初始化正向均值和方差正向均值正向方差 反向均值和方差Xavier初始正向和反向的均值和方差…

HTTP:从基础概念到协议机制,详解请求响应与状态保持

文章目录 一、HTTP概述1、HTTP的理解2、HTTP是无状态的协议 二、HTTP协议的过程1、URL&#xff08;统一资源定位符&#xff09;2、客户端3、服务器端 三、HTTP请求与响应1、HTTP请求和响应2、HTTP请求方法3、状态码 四、HTTP报文1、请求报文首部2、响应报文首部3、首部字段 五、…

全网唯一!R语言顶刊配色包TheBestColors

与Matlab相比&#xff0c;R语言在绘图方面有着天然的优势。 比如在配色方面&#xff0c;R语言有各式各样现成的包&#xff0c;按理说配色这种事应该很方便才对。 但实际体验下来&#xff0c;发现似乎不是那么回事。 首先&#xff0c;你很难记住每个包的调用方法以及每种配色…

【autodl】stable-diffusion-3-medium快速部署

sd3m是一个文生图模型&#xff0c;支持英文提示词&#xff0c; 支持自然语言 stable diffusion 3 medium 是一个开源模型&#xff0c;本教程是在autodl上部署modelscope上的sd3模型。下面是运行的webui页面图 配置 充值autodl &#xff0c;并且创建一个服务器&#xff1a;我的…

7.C基础_数组

一维数组 1、数组定义 形式&#xff1a;<数据类型> <数组名>[元素数量]&#xff0c;如&#xff1a;int a[3]; 数组的元素&#xff1a;组成数组的各个变量 注意&#xff1a; 数组中各元素的数据类型要求相同元素数量必须为整数&#xff0c;数组一旦创建&#x…