📜  在 PyTorch 中实现深度自动编码器进行图像重建(1)

📅  最后修改于: 2023-12-03 14:51:06.886000             🧑  作者: Mango

在 PyTorch 中实现深度自动编码器进行图像重建

深度自动编码器(Deep Autoencoder)是一种无监督学习模型,用于学习数据的低维表示和重建数据。它由一个编码器(Encoder)和一个解码器(Decoder)组成,其中编码器将输入数据映射到较低维度的隐藏表示,而解码器将隐藏表示映射回原始数据空间。这种架构可以用于图像重建、降维和特征提取等任务。

本文将介绍如何使用 PyTorch 实现深度自动编码器进行图像重建。我们将使用 MNIST 手写数字数据集作为示例。

环境准备

首先,确保你的环境中已经安装了 PyTorch 和 torchvision 库。可以使用以下命令安装所需的依赖:

pip install torch torchvision
数据准备

我们将使用 torchvision 库中的 MNIST 数据集。首先,导入必要的库并加载数据集:

import torch
import torchvision

# 加载训练集和测试集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=torchvision.transforms.ToTensor())

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

我们使用 PyTorch 构建深度自动编码器模型。模型由两部分组成:编码器和解码器。编码器将输入图像压缩成隐藏表示,而解码器将隐藏表示解码为重建的图像。

import torch.nn as nn

# 定义模型类
class Autoencoder(nn.Module):
    def __init__(self):
        super(Autoencoder, self).__init__()
        # 编码器
        self.encoder = nn.Sequential(
            nn.Linear(28*28, 128),  # 输入大小为28x28,输出大小为128
            nn.ReLU(),
            nn.Linear(128, 64),  # 输入大小为128,输出大小为64
            nn.ReLU(),
            nn.Linear(64, 12),  # 输入大小为64,输出大小为12
            nn.ReLU(),
            nn.Linear(12, 3)  # 输入大小为12,输出大小为3
        )
        # 解码器
        self.decoder = nn.Sequential(
            nn.Linear(3, 12),  # 输入大小为3,输出大小为12
            nn.ReLU(),
            nn.Linear(12, 64),  # 输入大小为12,输出大小为64
            nn.ReLU(),
            nn.Linear(64, 128),  # 输入大小为64,输出大小为128
            nn.ReLU(),
            nn.Linear(128, 28*28),  # 输入大小为128,输出大小为28x28
            nn.Sigmoid()
        )
    
    def forward(self, x):
        x = self.encoder(x)
        x = self.decoder(x)
        return x

代码中,我们使用了全连接层实现编码器和解码器的网络结构,并在每个层之间应用了ReLU激活函数。输入图像大小为28x28,经过编码器的处理后得到3维的隐藏表示,然后解码器将隐藏表示映射回原始图像空间,输出大小仍为28x28。

训练模型

现在我们可以开始训练我们的深度自动编码器了。在训练过程中,我们将使用均方误差(MSE)作为损失函数,优化器选择随机梯度下降(SGD)。

# 实例化模型
model = Autoencoder()

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)

# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
    for data in train_loader:
        images, _ = data
        images = images.view(images.size(0), -1)
        
        reconstructions = model(images)
        loss = criterion(reconstructions, images)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

训练过程中我们遍历每个训练批次,将图像展平为784维向量,并将其输入模型进行前向传播和反向传播。最后打印出每个epoch的损失值。

测试模型

训练完成后,我们可以使用测试集评估模型的性能。以下代码将重建测试集中的图像并计算均方误差作为评估指标:

model.eval()
test_loss = 0

with torch.no_grad():
    for data in test_loader:
        images, _ = data
        images = images.view(images.size(0), -1)
        
        reconstructions = model(images)
        test_loss += criterion(reconstructions, images).item()
    
test_loss /= len(test_loader)
print(f'Test Loss: {test_loss:.4f}')
结果可视化

最后,我们可以选择一些测试集中的图像,并将原始图像与重建图像进行可视化比较:

import matplotlib.pyplot as plt

# 可视化结果
num_images = 5
reconstructions = model(images[:num_images].view(num_images, -1)).detach()

fig, axes = plt.subplots(nrows=2, ncols=num_images, figsize=(10, 4))

for i in range(num_images):
    axes[0, i].imshow(images[i].view(28, 28), cmap='gray')
    axes[0, i].axis('off')
    axes[1, i].imshow(reconstructions[i].view(28, 28), cmap='gray')
    axes[1, i].axis('off')

axes[0, 0].set_title('Original')
axes[1, 0].set_title('Reconstruction')

plt.tight_layout()
plt.show()

以上代码将绘制一行中的原始图像和重建图像。

这样,我们就使用 PyTorch 成功实现了一个深度自动编码器,并利用其进行图像重建。

参考文档:https://pytorch.org/docs/stable/index.html