📅  最后修改于: 2023-12-03 14:51:06.886000             🧑  作者: Mango
深度自动编码器(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