Pytorch 第十三回:神经网络编码器------自动编码器
本次开启深度学习第十三回,基于Pytorch的神经网络编码器。本回先分享一个自动编码器。在本回中,通过minist数据集来分享如何建立一个简单的自动编码器。接下来给大家分享具体思路。
本次学习,借助的平台是PyCharm 2024.1.3,python版本3.11 numpy版本是1.26.4,pytorch版本2.0.0
文章目录
- [Pytorch 第十三回:神经网络编码器------自动编码器](#Pytorch 第十三回:神经网络编码器——自动编码器)
- 前言
- 一、数据准备
- 二、模型准备
-
- 1.模型准备
- 2.定义损失函数和优化函数
- [3 定义生成图片的函数](#3 定义生成图片的函数)
- 三、模型训练
-
- [1 实例化模型](#1 实例化模型)
- [2 迭代训练](#2 迭代训练)
- [3 图片展示](#3 图片展示)
- 总结
前言
讲述模型前,先讲述两个概念,统一下思路:
1、神经网络编码器
神经网络编码器(Encoder)是深度学习中的核心组件之一,其作用在于将输入数据转化为更高效、更具表征能力的中间形式,以支持后续处理任务。通过将输入数据本身作为学习目标,实现对数据的压缩编码与重建,从而学习输入的本质特征。其核心目标是在编码-解码过程中捕获数据的关键特征,而非简单复制输入数据。换句话说,编码器把原始数据转化为一个固定大小的向量或特征表示。这个过程称为"编码"或"特征提取"。
2、自动编码器组成
编码器(Encoder):将高维输入数据映射到低维隐空间(Latent Space),提取核心特征。例如,输入图像通过卷积层或全连接层压缩为向量表示;
解码器(Decoder):从隐空间重构原始输入数据,尽可能复现原始输入。例如,低维向量通过反卷积层恢复为图像。
自动编码器结构如下所示:
闲言少叙,直接展示逻辑,先上引用:
c
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision import transforms as tfs
from torchvision.utils import save_image
一、数据准备
首先准备MNIST数据集,并进行数据的预处理。关于数据集、数据加载器的介绍,可以查看第五回内容。
c
data_treating = tfs.Compose([
tfs.ToTensor(),
tfs.Normalize([0.5], [0.5])
])
train_set = MNIST('./data', transform=data_treating)
train_data = DataLoader(train_set, batch_size=64, shuffle=True)
二、模型准备
1.模型准备
这里定义的编码器和解码器都是4层的神经网络,网络之间的连接采用Relu激活函数。
c
class autoencoder(nn.Module):
def __init__(self):
super(autoencoder, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(28 * 28, 256),
nn.ReLU(True),
nn.Linear(256, 100),
nn.ReLU(True),
nn.Linear(100, 20),
nn.ReLU(True),
nn.Linear(20, 4)
)
self.decoder = nn.Sequential(
nn.Linear(4, 20),
nn.ReLU(True),
nn.Linear(20, 100),
nn.ReLU(True),
nn.Linear(100, 256),
nn.ReLU(True),
nn.Linear(256, 28 * 28),
nn.Tanh()
)
def forward(self, x):
encode = self.encoder(x)
decode = self.decoder(encode)
return encode, decode
注:由于输入图片标准化在-1到1之间,因此输出也要在-1到1之间,因此解码器的最后采用tanh激活函数。
2.定义损失函数和优化函数
定义计算均方误差损失函数;定义Adam优化器,学习率设定为0.01。
c
loss_f = nn.MSELoss(reduction='sum')
optimizer = torch.optim.Adam(encoder_net.parameters(), lr=1e-3)
3 定义生成图片的函数
c
def change_image(x):
x = 0.5 * (x + 1.)
x = x.clamp(0, 1)
x = x.view(x.shape[0], 1, 28, 28)
return x
三、模型训练
1 实例化模型
这里实例化了一个自动编码-解码的模型,同时为了加快模型训练,引入GPU进行训练(如何引入GPU进行训练,可以查看第六回)
c
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("device=", device)
encoder_net = autoencoder().to(device)
2 迭代训练
进行100次迭代训练,并将生成的图片保存。
c
for e in range(100):
for image, _ in train_data:
image = image.view(image.shape[0], -1)
image = image.to(device)
_, y_code = encoder_net(image)
loss = (loss_f(y_code, image).to(device) / image.shape[0])
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (e + 1) % 10 == 0:
print('epoch: {}, Loss: {:.4f}'.format(e + 1, loss))
print("image.shape[0]=",image.shape[0])
print("image.shape=", image.shape)
pic = change_image(y_code.cpu().data)
if not os.path.exists('./simple_autoencoder'):
os.mkdir('./simple_autoencoder')
save_image(pic, './simple_autoencoder/image_{}.png'.format(e + 1))
误差输出如下:
c
epoch: 10, Loss: 82.4779
epoch: 20, Loss: 81.4972
epoch: 30, Loss: 78.1668
epoch: 40, Loss: 69.2767
epoch: 50, Loss: 68.0554
epoch: 60, Loss: 73.5405
epoch: 70, Loss: 74.1826
epoch: 80, Loss: 72.9499
epoch: 90, Loss: 71.9427
epoch: 100, Loss: 68.0742
3 图片展示
训练10次生成图片
训练100次生成的图片:
相对来说,经过100次迭代训练,生成的图片还是比较清晰的。
总结
1)数据准备:准备MNIST集;
2)模型准备:定义自动编解码模型、损失函数和优化器;
3)数据训练:实例化模型并训练,生成新的图片数据。