自编码器简单介绍—使用PyTorch库实现一个简单的自编码器,并使用MNIST数据集进行训练和测试

news2024/11/19 17:28:35

文章目录

    • 自编码器简单介绍
    • 什么是自编码器?
    • 自动编码器和卷积神经网络的区别?
    • 如何构建一个自编码器?
    • 如何训练自编码器?
    • 如何使用自编码器进行图像压缩?
    • 总结
    • 使用PyTorch构建简单的自动编码器
      • 第一步:导入库和数据集
      • 第二步:建立编码器和解码器
      • 第三步:定义损失函数和优化器
      • 第四步:训练自编码器模型
      • 第五步:测试自编码器模型
      • 第六部:对比重构结果

自编码器简单介绍

自编码器是一种无监督学习算法,用于学习数据中的特征,并将这些特征用于重构与输入相似的新数据。自编码器由编码器和解码器两部分组成,编码器用于将输入数据压缩到一个低维度的表示形式,解码器将该表示形式还原回输入数据的形式。自编码器可以应用于多种领域,例如图像处理、语音识别和自然语言处理等。

什么是自编码器?

自编码器是一种无监督学习算法,用于学习数据的压缩表示。它由两个部分组成:编码器和解码器。编码器将输入数据压缩成低维表示,解码器将这个低维表示重构成与原始输入尽可能接近的输出。
简单结构如下:

自动编码器和卷积神经网络的区别?

自动编码器和卷积神经网络(CNN)都是深度学习中常用的模型,但它们的目的和结构略有不同。

自动编码器是一种无监督学习模型,其目的是学习一个对输入数据进行压缩和解压缩的函数。自动编码器通常由两个部分组成:编码器和解码器。编码器将输入数据转换为潜在表示,解码器将潜在表示转换回原始数据。自动编码器的目标是最小化重构误差,即在解码器输出的数据与原始数据之间的差异。

与之不同,卷积神经网络是一种用于图像分类、目标检测、语音识别等任务的有监督学习模型。卷积神经网络通常由卷积层、池化层、全连接层等组成。卷积层可以捕捉输入数据的局部特征,池化层可以减少特征图的大小,全连接层可以将特征图转换为分类结果。

虽然自动编码器和卷积神经网络的目的和结构不同,但它们都可以用于特征提取。自动编码器可以学习输入数据的低维表示,卷积神经网络可以提取输入数据的局部特征。在某些任务中,这些特征可以作为输入传递到其他模型中,以提高任务的性能。

除了特征提取,自动编码器和卷积神经网络还有其他方面的不同之处。

自动编码器可以用于数据的降维和去噪。通过学习输入数据的低维表示,自动编码器可以将高维数据降低到更低的维度,从而简化数据。此外,自动编码器还可以在输入数据中去除噪声,因为它们的目标是在重构时最小化重构误差,这有助于滤除输入数据中的噪声。

卷积神经网络则更适合处理图像、语音、视频等具有空间结构的数据。卷积层可以捕捉输入数据的局部特征,这对于图像分类、目标检测等任务非常重要。此外,卷积神经网络还可以通过使用池化层来减少特征图的大小,从而在处理大型图像时降低计算成本。

总的来说,自动编码器和卷积神经网络是两种不同的深度学习模型,它们的应用场景和目标略有不同。但是,它们都是非常有用的工具,可以在各种任务中发挥重要作用。

如何构建一个自编码器?

首先,需要确定编码器和解码器的结构。编码器可以是多层感知器(MLP)或卷积神经网络(CNN),其中每一层都包含多个神经元,并通过非线性函数进行激活。解码器通常与编码器结构相对称,也可以是一个MLP或CNN。在训练自编码器时,将输入数据输入编码器并计算编码器输出,然后将其输入解码器并计算解码器输出。最终的目标是最小化解码器输出和原始输入之间的差异。

如何训练自编码器?

训练自编码器的关键是确定损失函数。通常使用均方误差(MSE)来计算解码器输出和原始输入之间的差异。MSE的计算方式如下:

$ 在公式中, y i y_i yi 是实际值, y i ^ \hat{y_i} yi^ 是预测值, N N N 是数据集中的样本数。
M S E = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 \mathrm MSE=\frac{1}{N}\sum_{i=1}^N(y_i-\hat y_i)^2 MSE=N1i=1N(yiy^i)2
其中,N是样本数量, y i y_i yi是实际值, y ^ i \hat y_i y^i是解码器输出,即预测值。通过反向传播算法,可以计算编码器和解码器中所有参数的梯度,并使用梯度下降算法对参数进行更新。

如何使用自编码器进行图像压缩?

在用自编码器压缩图像时,将图像输入自编码器的编码器部分,得到低维表示,该表示可以看作是图像的压缩版本。可以通过解码器部分将该低维表示解码成原始图像。由于自编码器的解码器部分重构图像,因此可以使用自编码器进行图像压缩。

总结

以上是自编码器的简单入门教程。自编码器是一种无监督学习算法,可以用于学习数据的压缩表示。在训练自编码器时需要确定编码器和解码器的结构以及损失函数,并使用梯度下降算法对参数进行更新。自编码器可以用于图像压缩等任务。

使用PyTorch构建简单的自动编码器

在本教程中,我们将使用PyTorch库实现一个简单的自编码器,并使用MNIST数据集进行训练和测试。

第一步:导入库和数据集

首先,我们需要导入必要的库并加载MNIST数据集。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 检查是否安装了CUDA,并且CUDA是否适用于你的GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 超参数设置
batch_size = 64
learning_rate = 1e-3
num_epochs = 10

# 加载MNIST手写数字数据集
train_dataset = datasets.MNIST(root='./data/', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(root='./data/', train=False, transform=transforms.ToTensor())

# 创建数据加载器
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)

第二步:建立编码器和解码器

接下来,我们需要建立编码器和解码器模型。

# 定义一个自编码器的类
class Autoencoder(nn.Module):
    def __init__(self):
        super(Autoencoder, self).__init__()
        
        # 编码器部分
        self.encoder = nn.Sequential(
            nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=1),  # 输入1通道,输出16通道,3x3卷积,步长为2,padding为1
            nn.ReLU(),
            nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=1), # 输入16通道,输出32通道,3x3卷积,步长为2,padding为1
            nn.ReLU(),
            nn.Conv2d(32, 64, kernel_size=7),                      # 输入32通道,输出64通道,7x7卷积
        )
        
        # 解码器部分
        self.decoder = nn.Sequential(
            nn.ConvTranspose2d(64, 32, kernel_size=7),             # 输入64通道,输出32通道,7x7卷积转置
            nn.ReLU(),
            nn.ConvTranspose2d(32, 16, kernel_size=3, stride=2, padding=1, output_padding=1), # 输入32通道,输出16通道,3x3卷积转置,步长为2,padding为1,输出padding为1
            nn.ReLU(),
            nn.ConvTranspose2d(16, 1, kernel_size=3, stride=2, padding=1, output_padding=1),  # 输入16通道,输出1通道,3x3卷积转置,步长为2,padding为1,输出padding为1
            nn.Sigmoid()
        )
        
    def forward(self, x):
        x = self.encoder(x)
        x = self.decoder(x)
        return x

# 创建自编码器对象并将模型移动到GPU
model = Autoencoder().to(device)

第三步:定义损失函数和优化器

定义损失函数和优化器如下。

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

第四步:训练自编码器模型

现在可以使用MNIST数据集训练自编码器模型。

# 训练自编码器
for epoch in range(num_epochs):
    for data in train_loader:
        img, _ = data
        img = img.to(device)
        # 前向传播
        output = model(img)
        loss = criterion(output, img)
        # 反向传播和优化器优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print("Epoch[{}/{}], loss:{:.4f}".format(epoch+1, num_epochs, loss.data))

第五步:测试自编码器模型

# 测试自编码器
model.eval()
total_loss = 0
with torch.no_grad():
    for data in test_loader:
        img, _ = data
        img = img.to(device)
        output = model(img)
        loss = criterion(output, img)
        total_loss += loss.item()

print("Test average loss:{:.4f}".format(total_loss / len(test_loader)))

第六部:对比重构结果

在训练完成后,我们可以使用自编码器模型重构一些测试数据,并将重构的结果与原始数据进行比较。

# 迭代测试数据集,生成迭代器
dataiter = iter(test_loader)

# 从迭代器中获取下一个批次的图像和标签
images, labels = next(dataiter)

# 使用模型进行推断,处理获取的图像数据,并将结果保存在output变量中
output = model(images.to(device))

# 创建子图和轴对象,其中第一行显示原始图像,第二行显示重构后的图像
fig, axes = plt.subplots(nrows=2, ncols=10, sharex=True, sharey=True, figsize=(25,4))

# 循环遍历前10个图像,绘制原始图像和重构图像并添加标题
for i in range(10):
    # 显示原始图像
    axes[0,i].imshow(images[i].squeeze().numpy(), cmap='gray')
    axes[0,i].set_title("Original")
    axes[0,i].get_xaxis().set_visible(False)
    axes[0,i].get_yaxis().set_visible(False)

    # 显示重构后的图像
    axes[1,i].imshow(output[i].squeeze().cpu().detach().numpy(), cmap='gray')
    axes[1,i].set_title("Reconstructed")
    axes[1,i].get_xaxis().set_visible(False)
    axes[1,i].get_yaxis().set_visible(False)

# 显示生成的子图
plt.show()

运行完整的程序后,我们应该会看到原始图像和重构图像的对比结果。自编码器可以在其中一些图像上产生较好的结果,但在其他图像上可能会出现一些失真或模糊。

自编码器在实际应用中有许多变体和扩展,例如稀疏自编码器和卷积自编码器。这里仅仅是一个简单的入门教程,可以让您了解自编码器的基本原理和应用。

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

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

相关文章

中级软件设计师备考---数据库系统2

目录 规范化理论并发控制数据库完整性约束数据备份 规范化理论 函数依赖 部分函数依赖:在一个关系中,一个非主属性依赖于该关系的某个候选键的一部分属性。举个例子,假设有一个关系R(A,B,C,D),其中(A,B)是候选键。 如果C仅依赖于A…

微服务学习之面试知识相关总结(Nacos、MQ)

文章目录 壹 微服务Nacos1.1 SpringCloud常见组件1.2 Nacos的服务注册表结构1.3 Nacos如何支撑内部数十万服务注册压力1.4 Nacos避免并发读写冲突问1.5 Nacos与Eureka的区别1.6 Sentinel的限流与Gateway的限流的差别1.7 Sentinel的线程隔离与Hystix的线程隔离的差别 贰 MQ知识2…

前端Img图片不同格式的互相转化

目录 一、格式简介 二、格式互转 2.1、base64在视图上进行页面展示 2.3、将二进制流转为url进行页面展示 2.3、静态路径转二进制流传给后端 一、格式简介 主要有base64(数字字母组成的乱码那种)、url(http://xxx地址那种)、二进制流(后端上传图片的格式)、本地项目文件夹…

【JavaEE】社区版IDEA(2021.X版本及之前)创建SpringBoot项目

目录 下载Spring Boot Helper 创建项目 下载相关依赖 判断成功 删除多余文件 项目建好后添加依赖 输出Hello World SpringBoot的优点 下载Spring Boot Helper 创建项目 下载相关依赖 如果没有配置过国内源,参考【JavaEE】Spring项目的创建与使用_p_fly的博…

[架构之路-173]-《软考-系统分析师》-5-数据库系统-6-分布式数据库系统

目录 5 . 6 分布式数据库系统 5.6.1分布式数据库槪述 0. 分布式数据库特点 1 . 分布式数据库的体系结构 2 . 分布式数据库的优点 5.6.2 数据切片 1 . 数据分片方法的分类 2 . 数据分片的原则 3 . 分布透明性 5.6.3分布式数据库查询优化 2 . 副本的选择与多副本的更新策…

数据迁移实践 | MySQL到ClickHouse,HTAP黄金搭档

MySQL是世界上最流行的开源数据库,也是OLTP界的顶流,但是对于OLAP分析型业务场景的能力太弱。ClickHouse是最近几年数仓OLAP分析查询领域的黑马,当红炸子鸡,有意思的是天然兼容MySQL语法。所以很多用户喜欢OLTP放MySQL&#xff0c…

2023年湖北安全员ABC证报考条件都有哪些?甘建二告诉你

一、安全员ABC证是什么? 安全员A、B、C证属于建筑三类人员证书。建筑三类人员:是指建筑施工企业主要负责人、项目负责人和专职安全生产管理人员。 建筑企业的法人代表,必须取得A证才能担任法人代表 建造师必须取得B证才能担任项目负责人 …

FreeRTOS 信号量(一)

文章目录 一、信号量简介二、二值信号量1. 二值信号量简介2. 创建二值信号量①函数 vSemaphoreCreateBinary ()②函数 xSemaphoreCreateBinary()③函数 xSemaphoreCreateBinaryStatic() 3. 二值信号量创建过程分析4. 释放信号量①函数 xSemaphoreGive()②函数 xSemaphoreGiveFr…

UFD203A101 3BHE019361R0101电 工理论、电子技术、信息处理、控制理论、电力系统分析

UFD203A101 3BHE019361R0101电 工理论、电子技术、信息处理、控制理论、电力系统分析 作为电气工程及其自动化专业的大学生都会关心电气工程及其自动化就业方向是什么?电气工程专业就业方向怎样?自动化专业就业方向怎样? 对于很多本专业的在校…

实验06:哈夫曼编码

1.实验目的: 理解贪心算法的思想,掌握哈夫曼编码的技术和图像编解码算法的基本。 2.实验内容: 统计图像像素灰度值的分布特性,利用哈夫曼编码构造码表,实现对图像的编码和解码。 3.实验要求: 首先完成…

《JavaEE》InputStream, OutputStream 的用法

目录 File类 路径 绝对路径 相对路径 InputStream和OutputStream的使用 InputStream基本用法 OutputStream基本用法 功能实现 我们先来尝试着使用一些File类完成一些基本操作 我们查看这个文本是否存在 如果不存在我们创建一个新的文本出来 在当前文件夹中创建一个新…

MATLAB函数封装1:生成QT可以调用的.dll动态链接库

在进行相关算法的开发和设计过程中,MATLAB具有特别的优势,尤其是对于矩阵运算的处理,具有很多现成的方法和函数可以进行调用,同时MATLAB支持把函数封装成不同的语言方便完成算法的集成。 这里记录利用MATLAB封装成C动态链接库&…

git 自学笔记

git 自学笔记 git 是一个开源的分布式版本控制软件,可以敏捷的处理任何大小项目。 git 的工作流程大体如下: 首先克隆一个git资源作为工作目录 在克隆的资源上添加或者修改文件 如果其他人也修改了,就要对资源进行更新 在提交时也要查看有没有…

通过使用生成对抗市场模型改进基于强化学习的交易的泛化

Improving Generalization in Reinforcement Learning–Based Trading by Using a Generative Adversarial Market Model | IEEE Journals & Magazine | IEEE Xplore Improving Generalization in Reinforcement Learning–Based Trading by Using a Generative Adversaria…

ASEMI代理ADG736BRMZ-REEL7原装ADI车规级ADG736BRMZ-REEL7

编辑:ll ASEMI代理ADG736BRMZ-REEL7原装ADI车规级ADG736BRMZ-REEL7 型号:ADG736BRMZ-REEL7 品牌:ADI /亚德诺 封装:MSOP-10 批号:2023 安装类型:表面贴装型 引脚数量:10 类型&#xff1…

c/c++:指针p+p-p*p/,数组a+1,指针减指针,指针实现strlen函数,指针的比较运算,指针数组,多级指针

c: 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,此时学会c的话, 我所知道的周边的会c的同学,可手握10多个offer,随心所欲,而找啥算法岗的,基本gg 提…

IMX6ULLPRO单独编译kernel+dtb内核模块以及uboot

目录 为什么编译驱动程序之前要先编译内核? 驱动程序要用到内核文件: 编译内核 编译安装内核模块 编译内核模块 安装内核模块到 Ubuntu 某个目录下备用 安装内核和模块到开发板上 Bootloader 介绍 编译 u-boot 镜像 为什么编译驱动程序之前要先编…

4.4 使用分组聚合进行组内计算

4.4 使用分组聚合进行组内计算 4.4.1 使用groupby方法拆分数据groupby方法的参数及其说明:groupby对象常用的描述性统计方法如下: 4.4.2 使用agg方法聚合数据agg函数和aggregate函数的参数说明1、使用agg求出当前数据对应的统计量2、使用agg分别求字段的…

X509证书中的Subject Public Key Info

SubjectPublicKeyInfo在TBSCertificate的第七项: 对于ECC id-ecPublicKey OBJECT IDENTIFIER :: { iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } id-ecPublicKey 是必须的 ECParameters :: CHOICE {namedCurve OBJECT IDENTIFIER -- implicitCurve NULL -…

java day10

第10章 创建Swing界面 10.1 Swing的特性10.1.1 标准对话框1. 确认对话框2. 输入对话框3.消息对话框4. 选项对话框 10.1.2 使用对话框10.1.3 滑块10.1.4 滚动窗格10.1.5 工具栏10.1.6 进度条10.1.7 菜单10.1.8 选项卡式窗格 10.1 Swing的特性 10.1.1 标准对话框 JOptionPane类…