自编码器(AE)代码

AE.py

import torch 
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import torchvision
from torch.autograd import Variable
import torch.nn as nn
from time import time

from AE import *


num_epochs = 200 # 迭代完所有训练数据
batch_size = 128 #批量处理的大小,一般为8的倍数,在data_loader变量的初始化中使用到了
hidden_size = 30

'''一个iter训练batchsize张,一个epoch训练次数:总张数/batchsize'''

# MNIST dataset
#这部分是对数据的读取,该程序中使用的是minist数据,可以替换为其他数据
#dset中的totensor使得数据集能够在加载的阶段可以进行映射
dataset = dsets.MNIST(root='../MINIST/MNIST',
                            train=True,
                            transform=transforms.ToTensor(),
                            download=True)

# Data loader
# 加载数据,dataset 是传入的数据集,要求是映射类型的或者可迭代类型的数据集,batchsize 是非空的,
# shuffle set to True to have the data reshuffled at every epoch
data_loader = torch.utils.data.DataLoader(dataset=dataset,
                                            batch_size=batch_size,
                                            shuffle=True)

def to_var(x):
    # 判断cuda是不是可以使用
    if torch.cuda.is_available():
        x = x.cuda()
    return Variable(x)

#父类是nn.Module,因为它是所有的网络基类
class Autoencoder(nn.Module):
    # def __init__(self, in_dim=784, h_dim=400):
    # in_dim是每个输入样本的大小
    # h_dim是每个输出样本的大小
    def __init__(self, in_dim, h_dim):
        super(Autoencoder, self).__init__()

        # 编码器,Sequential是一个时序容器
        self.encoder = nn.Sequential(
            nn.Linear(in_dim, h_dim), # 做线性变换 y = ax + b
            nn.ReLU() # 激活函数 max(0, x)
            )

        # 解码器
        self.decoder = nn.Sequential(
            nn.Linear(h_dim, in_dim),
            nn.Sigmoid() # 激活函数,S型曲线
            )


    def forward(self, x):
        """
        Note: image dimension conversion will be handled by external methods
        """
        out = self.encoder(x)
        out = self.decoder(out)
        return out

# 对自编码类实例化
ae = Autoencoder(in_dim=784, h_dim=hidden_size)

if torch.cuda.is_available():
    ae.cuda()

criterion = nn.BCELoss() # 计算输入和目标之间的二进制交叉熵,个人认为也是一个实例化
optimizer = torch.optim.Adam(ae.parameters(), lr=0.001) # 优化方法,lr是步长
iter_per_epoch = len(data_loader) # 数据集中数据的个数
data_iter = iter(data_loader) # 完全训练一次

# save fixed inputs for debugging
fixed_x, _ = next(data_iter)
# 第一个参数是tensor,第二个参数是一个文件或者文件名,目的是将一个张量存储在一张图里
torchvision.utils.save_image(Variable(fixed_x).data.cpu(), './data/real_images.png')
# 函数,将输入放到一个容器里面
fixed_x = to_var(fixed_x.view(fixed_x.size(0), -1))


for epoch in range(num_epochs):
    t0 = time() # 返回当前时间戳
    for i, (images, _) in enumerate(data_loader):

        # flatten the image 使图片单调
        images = to_var(images.view(images.size(0), -1))
        out = ae(images) # 通过自编码训练
        loss = criterion(out, images) # 计算训练结果和原图的损失

        # 这三行的主要目的是训练loss,直到loss稳定,而这一点是通过训练梯度做到的,这三行做的事情就是训练梯度
        optimizer.zero_grad() # 设置每一个被优化的张量的梯度为0
        loss.backward() # 计算损失函数的梯度
        optimizer.step() # 重新给梯度

        if (i+1) % 100 == 0:
            print ('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f Time: %.2fs' 
                %(epoch+1, num_epochs, i+1, len(dataset)//batch_size, loss.data, time()-t0))

    # save the reconstructed images
    reconst_images = ae(fixed_x)
    reconst_images = reconst_images.view(reconst_images.size(0), 1, 28, 28)
    torchvision.utils.save_image(reconst_images.data.cpu(), './data/reconst_images_%d.png' % (epoch+1))

在实际实验中我对数据集进行了替换,这个过程比较痛苦,但是代码搞丢了,主要是替换数据集那部分,同时因为输入的数据是彩色图片,通道数要改,然而我并没有研究全连接处理彩色图片的方法,就不了了之了。
这个代码来自于github,我只是添加注释,仅作学习使用。链接如下:
https://github.com/wanglouis49/pytorch-autoencoders

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值