当前位置:   article > 正文

AE——重构数字(Pytorch+mnist)

AE——重构数字(Pytorch+mnist)

1、简介

  • AE(自编码器)由编码器和解码器组成,编码器将输入数据映射到潜在空间,解码器将潜在表示映射回原始输入空间。
  • AE的训练目标通常是最小化重构误差,即尽可能地重构输入数据,使得解码器输出与原始输入尽可能接近。
  • AE通常用于数据压缩、去噪、特征提取等任务。
  • 本文利用AE,输入数字图像。训练后,输入测试数字图像,重构生成新的数字图像。
    • 【注】本文案例需要输入才能生成输出,目标是重构,而不是生成。
  • 可以看出,重构图片和原始图片差别不大。 
  • 【注】输出的10张数字图像是输入的测试图像的第一批次。

2、代码

    1. import matplotlib.pyplot as plt
    2. import torch
    3. import torch.nn as nn
    4. import torch.optim as optim
    5. import torchvision
    6. # 在一个类中编写编码器和解码器层。为编码器和解码器层的组件都定义了全连接层
    7. class AE(nn.Module):
    8. def __init__(self, **kwargs):
    9. super().__init__()
    10. self.encoder_hidden_layer = nn.Linear(
    11. in_features=kwargs["input_shape"], out_features=128
    12. ) # 编码器隐藏层
    13. self.encoder_output_layer = nn.Linear(
    14. in_features=128, out_features=128
    15. ) # 编码器输出层
    16. self.decoder_hidden_layer = nn.Linear(
    17. in_features=128, out_features=128
    18. ) # 解码器隐藏层
    19. self.decoder_output_layer = nn.Linear(
    20. in_features=128, out_features=kwargs["input_shape"]
    21. ) # 解码器输出层
    22. # 定义了模型的前向传播过程,包括激活函数的应用和重构图像的生成
    23. def forward(self, features):
    24. activation = self.encoder_hidden_layer(features)
    25. activation = torch.relu(activation) # ReLU 激活函数,得到编码器的激活值
    26. code = self.encoder_output_layer(activation)
    27. code = torch.sigmoid(code) # Sigmoid 激活函数,以确保编码后的表示在 [0, 1] 范围内
    28. activation = self.decoder_hidden_layer(code)
    29. activation = torch.relu(activation)
    30. activation = self.decoder_output_layer(activation)
    31. reconstructed = torch.sigmoid(activation)
    32. return reconstructed
    33. if __name__ == '__main__':
    34. # 设置批大小、学习周期和学习率
    35. batch_size = 512
    36. epochs = 30
    37. learning_rate = 1e-3
    38. # 载入 MNIST 数据集中的图片进行训练
    39. transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()]) # 将图像转换为张量
    40. train_dataset = torchvision.datasets.MNIST(
    41. root="~/torch_datasets", train=True, transform=transform, download=True
    42. ) # 加载 MNIST 数据集的训练集,设置路径、转换和下载为 True
    43. train_loader = torch.utils.data.DataLoader(
    44. train_dataset, batch_size=batch_size, shuffle=True
    45. ) # 创建一个数据加载器,用于加载训练数据,设置批处理大小和是否随机打乱数据
    46. # 在使用定义的 AE 类之前,有以下事情要做:
    47. # 配置要在哪个设备上运行
    48. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    49. # 建立 AE 模型并载入到 CPU 设备
    50. model = AE(input_shape=784).to(device)
    51. # Adam 优化器,学习率 10e-3
    52. optimizer = optim.Adam(model.parameters(), lr=learning_rate)
    53. # 使用均方误差(MSE)损失函数
    54. criterion = nn.MSELoss()
    55. # 在GPU设备上运行,实例化一个输入大小为784的AE自编码器,并用Adam作为训练优化器用MSELoss作为损失函数
    56. # 训练:
    57. for epoch in range(epochs):
    58. loss = 0
    59. for batch_features, _ in train_loader:
    60. # 将小批数据变形为 [N, 784] 矩阵,并加载到 CPU 设备
    61. batch_features = batch_features.view(-1, 784).to(device)
    62. # 梯度设置为 0,因为 torch 会累加梯度
    63. optimizer.zero_grad()
    64. # 计算重构
    65. outputs = model(batch_features)
    66. # 计算训练重建损失
    67. train_loss = criterion(outputs, batch_features)
    68. # 计算累积梯度
    69. train_loss.backward()
    70. # 根据当前梯度更新参数
    71. optimizer.step()
    72. # 将小批量训练损失加到周期损失中
    73. loss += train_loss.item()
    74. # 计算每个周期的训练损失
    75. loss = loss / len(train_loader)
    76. # 显示每个周期的训练损失
    77. print("epoch : {}/{}, recon loss = {:.8f}".format(epoch + 1, epochs, loss))
    78. # 用训练过的自编码器提取一些测试用例来重构
    79. test_dataset = torchvision.datasets.MNIST(
    80. root="~/torch_datasets", train=False, transform=transform, download=True
    81. ) # 加载 MNIST 测试数据集
    82. test_loader = torch.utils.data.DataLoader(
    83. test_dataset, batch_size=10, shuffle=False
    84. ) # 创建一个测试数据加载器
    85. test_examples = None
    86. # 通过循环遍历测试数据加载器,获取一个批次的图像数据
    87. with torch.no_grad(): # 使用 torch.no_grad() 上下文管理器,确保在该上下文中不会进行梯度计算
    88. for batch_features in test_loader: # 历测试数据加载器中的每个批次的图像数据
    89. batch_features = batch_features[0] # 获取当前批次的图像数据
    90. test_examples = batch_features.view(-1, 784).to(
    91. device) # 将当前批次的图像数据转换为大小为 (批大小, 784) 的张量,并加载到指定的设备(CPU 或 GPU)上
    92. reconstruction = model(test_examples) # 使用训练好的自编码器模型对测试数据进行重构,即生成重构的图像
    93. break
    94. # 试着用训练过的自编码器重建一些测试图像
    95. with torch.no_grad():
    96. number = 10 # 设置要显示的图像数量
    97. plt.figure(figsize=(20, 4)) # 创建一个新的 Matplotlib 图形,设置图形大小为 (20, 4)
    98. for index in range(number): # 遍历要显示的图像数量
    99. # 显示原始图
    100. ax = plt.subplot(2, number, index + 1)
    101. plt.imshow(test_examples[index].cpu().numpy().reshape(28, 28))
    102. plt.gray()
    103. ax.get_xaxis().set_visible(False)
    104. ax.get_yaxis().set_visible(False)
    105. # 显示重构图
    106. ax = plt.subplot(2, number, index + 1 + number)
    107. plt.imshow(reconstruction[index].cpu().numpy().reshape(28, 28))
    108. plt.gray()
    109. ax.get_xaxis().set_visible(False)
    110. ax.get_yaxis().set_visible(False)
    111. plt.savefig('reconstruction_results.png') # 保存图像
    112. plt.show()
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/343815
推荐阅读
相关标签
  

闽ICP备14008679号