深度学习:卷积神经网络CNN

目录

一、什么是卷积?

二、卷积神经网络的组成

1. 卷积层

2. 池化层

3. 激活函数

4. 全连接层

三、卷积神经网络的构造

四、代码实现

1.数据预处理

2.创建卷积神经网络

3.创建训练集和测试集函数

4.创建损失函数和优化器并进行训练


一、什么是卷积?

        对图像(不同的数据窗口数据)和卷积核(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。

 

二、卷积神经网络的组成

1. 卷积层

  • 功能:通过卷积操作提取特征。卷积核(滤波器)在输入图像上滑动,计算局部区域的加权和,生成特征图
  • 参数:卷积核的大小(如3x3、5x5)、步幅(每次滑动的像素数)和填充(为避免信息损失,通常在图像边缘添加零)。

 

2. 池化层

  • 功能:降低特征图的空间维度,减少计算量和参数数量,防止过拟合
  • 类型
    • 最大池化:在每个窗口中取最大值。
    • 平均池化:在每个窗口中取平均值。
  • 参数:池化窗口的大小和步幅。

 

3. 激活函数

  • 功能:引入非线性,帮助模型捕捉复杂的模式。
  • 常用类型
    • ReLU(修正线性单元):输出为输入的正部分,负部分输出为0。
    • Sigmoid:将输出限制在0到1之间,适用于二分类问题。
    • Softmax:将输出转化为概率分布,适用于多分类问题。

 

4. 全连接层

  • 功能:将卷积层和池化层提取的特征进行整合,用于最终的分类或回归。
  • 结构:每个神经元与前一层的所有神经元相连接。

 

三、卷积神经网络的构造

  • 输入层--卷积层--池化层--全连接层--输出层

 

四、代码实现

1.数据预处理

  • 从本地读取图片数据并打包
  • 将其裁剪成256*256大小并转换成tensor类型数据
  • 将对应图片标签也转换成tensor类型数据
import torch
import numpy as np
from torch.utils.data import DataLoader, Dataset  # 数据包管理工具,打包数据,
from torchvision import transforms
from PIL import Imageclass food_dataset(Dataset):def __init__(self, file_path, transform=None):  # 类的初始化,解析数据文件txtself.file_path = file_pathself.imgs = []self.labels = []self.transform = transformwith open(self.file_path) as f:  # 是把train.txt文件中图片的路径保存在 self.imgs,train.txt文件中标签保存在self.label里samples = [x.strip().split(' ') for x in f.readlines()]  # 去掉首尾空格 再按空格分成两个元素for img_path, label in samples:self.imgs.append(img_path)  # 图像的路径self.labels.append(label)  # 标签,还不是tensor# 初始化:把图片目录加载到selfdef __len__(self):  # 类实例化对象后,可以使用len函数测量对象的个数return len(self.imgs)def __getitem__(self, idx):  # 关键,可通过索引的形式获取每一个图片数据及标签image = Image.open(self.imgs[idx])  # 读取到图片数据,还不是tensorif self.transform:# 将pil图像数据转换为tensorimage = self.transform(image)  # 图像处理为256x256,转换为tenorlabel = self.labels[idx]  # label还不是tensorlabel = torch.from_numpy(np.array(label, dtype=np.int64))  # label也转换为tensorreturn image, labeldata_transforms = {'train':transforms.Compose([transforms.Resize([256, 256]),transforms.ToTensor()]),'test':transforms.Compose([transforms.Resize([256, 256]),transforms.ToTensor()])
}train_data = food_dataset(file_path=r'.\train.txt', transform=data_transforms['train'])   # 64张图片为一个包  训练集60000张图片 打包成了938个包
test_data = food_dataset(file_path=r'.\test.txt', transform=data_transforms['test'])train_dataloader = DataLoader(train_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)for x, y in test_dataloader:print(f"shape of x [N ,C,H,W]:{x.shape}")print(f"shape of y :{y.shape} {y.dtype}")break

 

2.创建卷积神经网络

from torch import nn  # 导入神经网络模块class CNN(nn.Module):  # Convolutional Neural Networkdef __init__(self):super(CNN, self).__init__()self.conv1 = nn.Sequential(  # 将多个层组合成一起。nn.Conv2d(  # 2d一般用于图像,3d用于视频数据(多一个时间维度),1d一般用于结构化的序列数据in_channels=3,  # 图像通道个数,1表示灰度图(确定了卷积核 组中的个数),out_channels=16,  # 要得到几多少个特征图,卷积核的个数kernel_size=5,  # 卷积核大小,5*5stride=1,  # 步长padding=2  # 一般希望卷积核处理后的结果大小与处理前的数据大小相同,效果会比较好。那pading改如何设计呢?建议stride为1),nn.ReLU(),  # relu层,不会改变特征图的大小nn.MaxPool2d(kernel_size=2),  # 进行池化操作(2x2 区域)  最大值池化)self.conv2 = nn.Sequential(  # 但整个 nn.Sequential 可以视为一个卷积模块nn.Conv2d(16, 32, 5, 1, 2),nn.ReLU(),nn.Conv2d(32, 32, 5, 1, 2),nn.ReLU(),nn.MaxPool2d(2))self.conv3 = nn.Sequential(nn.Conv2d(32, 128, 5, 1, 2),nn.ReLU())self.out = nn.Linear(128 * 64 * 64, 20)  # 全连接层得到的结果def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)x = x.view(x.size(0), -1)output = self.out(x)return outputdevice = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_avaibale() else 'cpu'model = CNN().to(device)  # 把刚刚创建的模型传入到GPU
print(model)

输出:

  • 可以看到该卷积神经网络有三个卷积模块
  • 最后通过全连接层输出预测结果
CNN((conv1): Sequential((0): Conv2d(3, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))(1): ReLU()(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(conv2): Sequential((0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))(1): ReLU()(2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))(3): ReLU()(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(conv3): Sequential((0): Conv2d(32, 128, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))(1): ReLU())(out): Linear(in_features=524288, out_features=20, bias=True)
)

 

3.创建训练集和测试集函数

def train(dataloader, model, loss_fn, optimizer):model.train()  # 告诉模型,我要开始训练,模型中w进行随机化操作,已经更新w.在训练过程中,w会被修改的# pytorch提供2种方式来切换训练和测试的模式,分别是:model.train()和 model.eval().# 一般用法是: 在训练开始之前写上model.trian(),在测试时写上model.eval().batch_size_num = 1for x, y in dataloader:  #x, y = x.to(device), y.to(device)  # 把训练数据集和标签传入CPU或GPUpred = model.forward(x)  # 向前传播loss = loss_fn(pred, y)  # 通过交叉熵损失函数计算损失值lossoptimizer.zero_grad()  # 梯度值清零loss.backward()  # 反向传播计算得到每个参数的梯度值woptimizer.step()  # 根据梯度更新网络w参数loss_value = loss.item()  # 从tensor数据中提取数据出来,tensor获取损失值if batch_size_num % 2 == 0:print(f"loss:{loss_value:>7f} [number:{batch_size_num}]")batch_size_num += 1def test(dataloader, model, loss_fn):size = len(dataloader.dataset)num_batches = len(dataloader)model.eval()  # 测试,w就不能再更新。test_loss, correct = 0, 0with torch.no_grad():  # 一个上下文管理器,关闭梯度计算。当你确认不会调用Tensor.backward()的时候。这可以减少计算所占用的消耗for x, y in dataloader:x, y = x.to(device), y.to(device)pred = model.forward(x)test_loss += loss_fn(pred, y).item()  # test loss是会自动累加每一个批次的损失值correct += (pred.argmax(1) == y).type(torch.float).sum().item()a = (pred.argmax(1) == y)  # dim=1表示每一行中的最大值对应的索引号,dim=0表示每一列中的最大值对应的索引号b = (pred.argmax(1) == y).type(torch.float)test_loss /= num_batches  # 能来衡量模型测试的好坏。correct /= size  # 平均的正确率print(f"Test result: \n Accuracy: {(100 * correct)}%, Avg loss: {test_loss}")

 

4.创建损失函数和优化器并进行训练

  • 创建处理多分类的损失函数
  • 使用Adam优化器
loss_fn = nn.CrossEntropyLoss()  # 处理多分类
optimizer = torch.optim.Adam(model.parameters(), lr=0.0002)epochs = 20  # 到底选择多少呢?
for t in range(epochs):print(f"Epoch {t + 1}\n--------------")train(train_dataloader, model, loss_fn, optimizer)
print("Done!")
test(test_dataloader, model, loss_fn)

输出:

Epoch 20
--------------
loss:0.002920 [number:2]
loss:0.003376 [number:4]
Done!
Test result: Accuracy: 41.02564102564102%, Avg loss: 5.77920389175415

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

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

相关文章

LPDDR4芯片学习(一)——基础知识与引脚定义

一、基础知识 01 dram基本存储单元 当需要将一位数据存储到DRAM中时,晶体管会充电或放电电容。充电的电容表示逻辑高(1),放电的电容表示逻辑低(0)。由于电容会随着时间泄漏电荷,因此需要定期刷…

学习记录:js算法(四十三):翻转二叉树

文章目录 翻转二叉树我的思路网上思路递归栈 总结 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点 图一: 图二: 示例 1:(如图一) 输入:root [4,2,7,1…

Python记录

1.冒泡排序 时间复杂度O(n^2) 选择、插入都是 def bubble(data, reverse):for i in range(len(data)-1):for j in range(len(data)-i-1):if data[j] > data[j1]:data[j], data[j1] data[j1], data[j]if reverse:data.reverse()return data 2.快速排序 时间…

护理陪护小程序|陪护系统||陪护系统开发

在当今社会,随着人口老龄化的加剧和家庭结构的变化,护理与陪护服务的需求日益增长。为了更好地满足这一市场需求,并提升服务效率与质量,护理陪护小程序应运而生。这类小程序不仅为用户提供了便捷、高效的服务预约与管理平台&#…

828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Redis集群

828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Redis集群 Redis 集群是一种分布式的 Redis 解决方案,能够在多个节点之间分片存储数据,实现水平扩展和高可用性。与传统的主从架构不同,Redis 集群支持数据自动分片、主节点故…

J Transl Med结肠癌分子分型+简单实验

目录 技术路线 实验设计(药物敏感性) 亮点 方法 从 TCGA 和 GEO 数据库下载大量和单细胞 RNA 测序以及 CRC 的临床数据。HRGs 和 LMRGs 来自分子特征数据库。使用 R 软件包 DESeq2 进行差异表达分析。使用无监督聚类进行分子亚型。使用单变量 Cox 回…

嘉宾云集旌城 只为大赛而来 2024ISGC国际烈酒(中国)大奖赛在德阳落下帷幕

秋高气爽、古蜀之源,迎来第六届国际烈酒(中国)大奖赛;五谷丰登、重装之都,齐聚百名国际烈酒大奖赛评委。 9月18日,由德阳市人民政府、国家葡萄酒及白酒露酒产品质量检验检测中心、上海合作组织多功能经贸平…

图片压缩怎么弄?教你5种图片压缩小技巧

现如今,图片已成为我们日常生活和工作不可或缺的一部分。然而,高清图片往往伴随着庞大的文件体积,给存储和传输带来诸多不便。这时候我们就需要对图片进行适当的压缩处理,那么该怎么做呢?下面教大家5种图片压缩小技巧&…

GBase 8s 安装手册

没有失败,只有暂时停止成功! 一:简介 GBase 8s 产品支持多种处理器平台,除国际主流的 x86_64 处理器(包括 Intel 和 AMD) 外,全面支持飞腾、鲲鹏、龙芯、兆芯、海光、申威等国产处理器。 GBas…

2025秋招内推|招联金融

【投递方式】 直接扫下方二维码,使用内推码: igcefb 【招聘岗位】 深圳,武汉: 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策划 产品运营 客户体验管理 风险管理 资产管理 【校招流程】 简历投递:9月…

kafka 消费者线程安全问题详细探讨

内容概要 主要内容 常见错误案例 下面这段代码大概逻辑 初始化时 实例化KafkaConsumer, 开启线程拉取消息并且处理 资源释放回调 停止线程、调用kafkaConsumer.close进行资源释放 表面上没有问题,但实际上可能出现线程安全问题,因为poll 和 close 两…

Jetpack Compose 核心组件(Text, Images, Buttons)(6)

导读大纲 1.1 基本组件介绍1.2 Text1.2.1 基本用法1.2.2 设计文字风格 1.3 Image组件1.3.1 从各种来源加载图片1.3.2 关键属性1.3.3 如何加载和显示不同类型的图像1.3.4 内容描述和无障碍访问: 1.4 Button组件1.4.1 基本用法1.4.2 装饰和自定义1.4.3 处理按钮点击1.4.4 重要考虑…

基于python深度学习遥感影像地物分类与目标识别、分割实践技术

我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…

JS惰性函数两种实现方式

惰性函数的本质就是函数重写,所谓惰性载入,指函数执行的分支只会发生一次。那什么时函数重写呢?由于一个函数可以返回另一个函数,因此可以用新的函数在覆盖旧的函数。 惰性函数有两种实现方式: 1、在函数被调用时&am…

案例研究丨国控星鲨利用DataEase释放数据潜能,重塑业务视野

国药控股星鲨制药(厦门)有限公司(以下简称为国控星鲨)始创于1952年,前身为厦门鱼肝油厂,距今已经有70余年历史,是国家商务部认定的“中华老字号”企业。2011年,国药控股与厦门轻工集…

2024年国庆小长假即将来临,陪猫咪的同时应该如何清浮毛

在父母眼中我们是不是永远都长不大?每次和他们讨论一点事情就开始吵起来。这不,前两天想着和好久不见的朋友去见面,出门前还要被逼问一番。 去到朋友家,发现朋友养了两只可爱的小猫,一时心动上头,我也转身…

通信工程学习:什么是MANO管理编排

MANO:管理编排 MANO:Management and Network Orchestration(管理和网络编排)在网络功能虚拟化(NFV)架构中扮演着至关重要的角色。MANO是一个由多个功能实体组合而成的层次,这些功能实体负责管理…

地图定位流程

用户端在小程序认证通过后会自动进行定位,也可以在首页手动定位,定位成功后用户在查询家政服务项目时会根据定位的城市查询该城市有哪些服务项目。 高德地图配置 小程序端的定位是通过手机的定位模块进行定位,定位成功获取经纬度坐标&#x…

吸烟行为检测、重点区域吸烟检测、吸烟检测算法样本标注

吸烟检测算法主要用于公共场所、工作场所和家庭环境中的吸烟行为监控,通过图像识别技术来检测和识别吸烟行为,以确保环境卫生和公共安全。这种技术可以帮助管理者实时监控吸烟行为,及时采取措施,减少二手烟的危害。 一、技术实现…

55 循环神经网络RNN的实现_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录循环神经网络的从零开始实现[**独热编码**]初始化模型参数循环神经网络模型预测[**梯度裁剪**]训练小结练习 循环神经网络的从零开始实现 import math import torch from torch import nn from torch.nn import functional as F from d2l i…