一:编码器(AE)介绍
它在形状上和普通的BP网络,或者是卷积网络很相似,都是由输入层,隐藏层,输出层组成的,只不过在我们的之前学习中,BP神经网络和卷积神经网络都用来做分类使用了,也就是在监督学习的场景下做分类。

AE是是无监督学习工作的,数据本身没有标签,AE的输出Y的标签刚好就是数据本身,也就是说,输入端是X,输出端是Y,且恰恰Y=X,先来看看网络结构。

输入端是数据本身X,最中间的隐藏层是code层,节点的数目维度要小于输出端的维度,在input层和code层之间,还可以自定义很多隐藏层,这一部分叫做编码器encoder,将高维度的X信息压缩和降维到了code层的维度,code层保留降维后的信息。

输出端是Y,我们希望能从code层原样输出数据X,也就是希望Y尽量逼近于数据X,Y和X的维度一致,都是大于code层的维度,在code层到输出层之间也可以自定义其他隐藏层,这部分是从低维度到高维度的转换,还原出数据X,所以这部分叫做解码器decoder。

感觉这个是不是特别像GAN,后面的decoder部分,可以从一个低维度的信息,直接转换(还原)成一个输入信息的X。

因此,我们训练完网络后,当我们随便输入一个测试样本数据X,那么自编码网络将对X先进行隐藏层的编码,得到X’,然后再从隐藏X’转换解码到输出层,完成解码,重构出X。隐藏层可以看成是原始数据X的另外一种特征表达。

自编码器的应用

  1. 数据降维 可视化
  2. 数据去噪
  3. 图像压缩
  4. 特征学习

常见的几种自编码器

  1. 稀疏自编码(SAE)
  2. 降噪自编码(DAE)
  3. 收缩自编码(CAE)
  4. 栈式自编码

如上说述,隐藏层也就是code层,通过encoder可以描述成是数据X的另外一种形式,它可以通过decoder还原出X,因此可以用于数据压缩,这里有点像之前学习的SVD。将数据降维后,可以跟KNN,Kmeans等聚类/类算法结合,降低模型的复杂度,也使得模型更加容易训练。

二:运行实例
例子一:还是拿MNIST实例集做测试。

from torchvision import transforms, datasets, models
import time
import torch
from torch import nn
from torch.autograd import Variable
from torch.utils.data import DataLoader, sampler
import numpy as np
import matplotlib.pyplot as plt
import torchvision.transforms as tfs
import matplotlib.gridspec as gridspec#======================================================定义图像展示相关的
plt.rcParams['figure.figsize'] = (10.0, 8.0)  # 设置画图的尺寸
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'def show_images(images):  # 定义画图工具images = np.reshape(images, [images.shape[0], -1])print('show_images: ', images.shape)sqrtn = int(np.ceil(np.sqrt(images.shape[0])))sqrtimg = int(np.ceil(np.sqrt(images.shape[1])))fig = plt.figure(figsize=(sqrtn, sqrtn))gs = gridspec.GridSpec(sqrtn, sqrtn)gs.update(wspace=0.05, hspace=0.05)for i, img in enumerate(images):ax = plt.subplot(gs[i])plt.axis('off')ax.set_xticklabels([])ax.set_yticklabels([])ax.set_aspect('equal')plt.imshow(img.reshape([sqrtimg, sqrtimg]))return# step 1: ===================================================加载数据
class ChunkSampler(sampler.Sampler):  # 定义一个取样的函数def __init__(self, num_samples, start=0):self.num_samples = num_samplesself.start = startdef __iter__(self):return iter(range(self.start, self.start + self.num_samples))def __len__(self):return self.num_samples# 加载数据时候的处理函数
def preprocess_img(x):x = tfs.ToTensor()(x)return (x - 0.5) / 0.5# 展示图片时候的处理函数
def deprocess_img(x):return (x + 1.0) / 2.0NUM_TRAIN = 60000
batch_size = 128
EPOCHS = 100
HIDDEN_SIZE = 30train_dataset = datasets.MNIST('./data', train=True, transform=preprocess_img)
train_data = DataLoader(train_dataset, batch_size=batch_size, sampler=ChunkSampler(NUM_TRAIN, 0))# step 2: ======================================定义自动编码器
class AutoEncoderNet(nn.Module):def __init__(self):super(AutoEncoderNet, self).__init__()# 输入是[batch_size, 1, 28, 28]self.en_conv = nn.Sequential(nn.Conv2d(1, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.Conv2d(16, 32, 4, 2, 1),nn.BatchNorm2d(32),nn.Tanh(),nn.Conv2d(32, 16, 3, 1, 1),   # 输出: [batch_size, 16, 7, 7]nn.BatchNorm2d(16),nn.Tanh())# 隐藏层是 HIDDEN_SIZE 个节点组成的。self.en_fc = nn.Linear(16*7*7, HIDDEN_SIZE)   # 输出: [batch_size, 30]self.de_fc = nn.Linear(HIDDEN_SIZE, 16*7*7)   # 输出: [batch_size, 16*7*7]self.de_conv = nn.Sequential(nn.ConvTranspose2d(16, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.ConvTranspose2d(16, 1, 4, 2, 1),   # 输出: [batch_size, 1, 28, 28]nn.Sigmoid())def forward(self, x): # x : [batch_size, 1, 28, 28]en = self.en_conv(x) # en: [batch_size, 16, 7, 7]en = en.view(en.size(0), -1) # en: [batch_size, 784]code = self.en_fc(en) # code: [batch_size, 30]de = self.de_fc(code) # de: [batch_size, 784]de = de.view(de.size(0), 16, 7, 7) # de: [batch_size, 16, 7, 7]decoded = self.de_conv(de) # decoded: [batch_size, 1, 28, 28]return code, decodednet = AutoEncoderNet()# step 3: ======================================定义优化器和损失函数
# 使用Adam梯度下降
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)
# 由于问题不是分类,需要最终得到的编码器生成的图像和原始图像很像,因此需要使用回归用的误差函数,均方差函数。
loss_f = nn.MSELoss()# step 4: ======================================开始训练
iter_count = 0
for epoch in range(EPOCHS):net.train()for step, (images, _) in enumerate(train_data, 1):net.zero_grad()print(images.shape)# 前向传播code, decoded = net(images)print('code: ', code.shape)print('decoded image: ', decoded.shape)# 计算损失值,反向传播更新参数。loss = loss_f(decoded, images)optimizer.zero_grad()loss.backward()optimizer.step()if (iter_count % 200 == 0):print('Iter: {}, Loss: {:.4}'.format(iter_count, loss.item(), ))imgs_numpy = deprocess_img(decoded.data.cpu().numpy())show_images(imgs_numpy[0:16])plt.show()print()iter_count = iter_count + 1

我们直接把decoder生成的图片展示了出来,下面挑选了几个图片,发现效果还是挺不错的。



例子二:
使用彩色图片的鸣人来做实验:
输入36464维度的图片,隐藏层是128维度的向量。

from torchvision import transforms, datasets
import torch
from torch import nn
from torch.utils.data import DataLoader
import os
from torchvision.utils import save_imageimage_size = 64  # 图片大小
batch_size = 16   # 批量大小,我就只用16个鸣人的图片做个测试的哈,都是从百度上取截图取得的。
EPOCHS = 1000
HIDDEN_SIZE = 128def deprocess_img(img):out = 0.5 * (img + 1)out = out.clamp(0, 1)out = out.view(-1, 3, image_size, image_size)return outdata_path = os.path.abspath("D:/software/Anaconda3/doc/3D_Naruto")
print (os.listdir(data_path))
# 请注意,在data_path下面再建立一个目录,存放所有图片,ImageFolder会在子目录下读取数据,否则下一步会报错。
dataset = datasets.ImageFolder(root=data_path, transform=transforms.Compose([transforms.Resize(image_size),transforms.CenterCrop(image_size),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), ]))
train_data = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)# step 2: ======================================定义自动编码器
class AutoEncoderNet(nn.Module):def __init__(self):super(AutoEncoderNet, self).__init__()# 输入是[batch_size, 3, 64, 64]self.en_conv = nn.Sequential(nn.Conv2d(3, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.Conv2d(16, 32, 4, 2, 1),nn.BatchNorm2d(32),nn.Tanh(),nn.Conv2d(32, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.Conv2d(16, 8, 3, 1, 1),   # 输出: [batch_size, 8, 8, 8]nn.BatchNorm2d(8),nn.Tanh())# 隐藏层是 HIDDEN_SIZE 个节点组成的。self.en_fc = nn.Linear(8 * 8 * 8, HIDDEN_SIZE)   # 输出: [batch_size, 30]self.de_fc = nn.Linear(HIDDEN_SIZE, 8 * 8 * 8)   # 输出: [batch_size, 8 * 8 * 8]self.de_conv = nn.Sequential(nn.ConvTranspose2d(8, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.ConvTranspose2d(16, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.ConvTranspose2d(16, 3, 4, 2, 1),   # 输出: [batch_size, 3, 28, 28]nn.Sigmoid())def forward(self, x): # x : [batch_size, 1, 28, 28]en = self.en_conv(x) # en: [batch_size, 8, 8, 8]en = en.view(en.size(0), -1) # en: [batch_size, 512]code = self.en_fc(en) # code: [batch_size, 128]de = self.de_fc(code) # de: [batch_size, 512]de = de.view(de.size(0), 8, 8, 8) # de: [batch_size, 8, 8, 8]decoded = self.de_conv(de) # decoded: [batch_size, 3, 64, 64]return code, decodednet = AutoEncoderNet()# step 3: ======================================定义优化器和损失函数
# 使用Adam梯度下降
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)
# 由于问题不是分类,需要最终得到的编码器生成的图像和原始图像很像,因此需要使用回归用的误差函数,均方差函数。
loss_f = nn.MSELoss()# step 4: ======================================开始训练
# os.mkdir('D:/software/Anaconda3/doc/3D_Img/AE/')
iter_count = 0
for epoch in range(EPOCHS):net.train()for step, images in enumerate(train_data, 0):net.zero_grad()img_data = images[0]print(img_data.shape)# 前向传播code, decoded = net(img_data)print('code: ', code.shape)print('decoded image: ', decoded.shape)# 计算损失值,反向传播更新参数。loss = loss_f(decoded, img_data)optimizer.zero_grad()loss.backward()optimizer.step()if (iter_count % 10 == 0):print('Iter: {}, Loss: {:.4}'.format(iter_count, loss.item(), ))real_images = deprocess_img(decoded.data)save_image(real_images, 'D:/software/Anaconda3/doc/3D_Img/AE/test_%d.png' % (iter_count))print()iter_count = iter_count + 1

最后通过encoder和decoder后得到的图片如下:



深度学习《自动编码器》相关推荐

  1. 深度学习之自编码器(4)变分自编码器

    深度学习之自编码器(4)变分自编码器 1. VAE原理  基本的自编码器本质上是学习输入 x\boldsymbol xx和隐藏变量 z\boldsymbol zz之间映射关系,它是一个 判别模型(Di ...

  2. 深度学习之自编码器(5)VAE图片生成实战

    深度学习之自编码器(5)VAE图片生成实战 1. VAE模型 2. Reparameterization技巧 3. 网络训练 4. 图片生成 VAE图片生成实战完整代码  本节我们基于VAE模型实战F ...

  3. 深度学习之自编码器AutoEncoder

    深度学习之自编码器AutoEncoder 原文:http://blog.csdn.net/marsjhao/article/details/73480859 一.什么是自编码器(Autoencoder ...

  4. 深度学习之自编码器(3)自编码器变种

    深度学习之自编码器(3)自编码器变种 1. Denoising Auto-Encoder 2. Dropout Auto-Encoder 3. Adversarial Auto-Encoder  一般 ...

  5. 深度学习之自编码器(2)Fashion MNIST图片重建实战

    深度学习之自编码器(2)Fashion MNIST图片重建实战 1. Fashion MNIST数据集 2. 编码器 3. 解码器 4. 自编码器 5. 网络训练 6. 图片重建 完整代码  自编码器 ...

  6. 深度学习之自编码器(1)自编码器原理

    深度学习之自编码器(1)自编码器原理 自编码器原理  前面我们介绍了在给出样本及其标签的情况下,神经网络如何学习的算法,这类算法需要学习的是在给定样本 x\boldsymbol xx下的条件概率 P( ...

  7. 【深度学习】 自编码器(AutoEncoder)

    目录 RDAE稳健深度自编码 自编码器(Auto-Encoder) DAE 深度自编码器 RDAE稳健深度自编码 自编码器(Auto-Encoder) AE算法的原理 Auto-Encoder,中文称 ...

  8. 深入理解深度学习——Transformer:编码器(Encoder)部分

    分类目录:<深入理解深度学习>总目录 相关文章: ·注意力机制(AttentionMechanism):基础知识 ·注意力机制(AttentionMechanism):注意力汇聚与Nada ...

  9. 深度学习之自编码器实现——实现图像去噪

    大家好,我是带我去滑雪! 自编码器是一种无监督学习的神经网络,是一种数据压缩算法,主要用于数据降维和特征提取.它的基本思想是将输入数据经过一个编码器映射到隐藏层,再通过一个解码器映射到输出层,使得输出 ...

  10. 深度学习:自编码器、深度信念网络和深度玻尔兹曼机

    最近自己会把自己个人博客中的文章陆陆续续的复制到CSDN上来,欢迎大家关注我的 个人博客,以及我的github. 本文主要讲解有关自编码器.深度信念网络和深度玻尔兹曼机的相关知识. 一.自编码器 1. ...

最新文章

  1. 条件随机场(CRF) - 4 - 学习方法和预测算法(维特比算法)
  2. python字符串压缩字_gzip如何在Python中压缩字符串?
  3. 记一次mysql性能优化过程
  4. 关于魔法方法的一点总结
  5. linux多节点部署,Linux下docker部署+面板portainer管理多节点docker
  6. Windows系统调用学习笔记(三)—— 保存现场
  7. 你真的做好数字化运营了吗?来直播间,给你加点儿“灵感”丨教育专题
  8. zabbix mysql.status_Zabbix 监控 Mysql 状态
  9. 2021信阳高中高考成绩查询,河南省普通高中综合信息管理系统2021信阳中考成绩查询入口...
  10. 服务器网口和虚拟服务器网口配置,Apache服务器使用不同端口配置多个虚拟主机站点...
  11. Object/Relation Mapping 对象关系映射
  12. 【floyd】HDU 1874 畅通project续
  13. 数据库笔记01:SQL Server系统概述
  14. 小米折叠屏手机设计专利曝光:向内折叠 正面无开孔
  15. webapi 初识 net
  16. 数据结构与算法之符号表
  17. Linux RT(1)-硬实时Linux(RT-Preempt Patch)在PC上的编译、使用和测试
  18. leetcode17 电话号码的字母组合,39 组合总和(python)
  19. 如何在windows11系统中打开ie11浏览网页
  20. 怎样放大图片保持清晰度?

热门文章

  1. [高性能javascript笔记]1-加载和执行
  2. Matlab norm 用法小记
  3. TCP连接(Time_Wait、Close_Wait)说明
  4. corosync + pacemaker + drbd 实现mysql存储的高可用(一)
  5. 容器编排技术 -- Kubernetes kubectl create secret generic 命令详解
  6. Hibernate Native SQL查询示例
  7. 安利几款语音识别软件
  8. H5新增特性之语义化标签
  9. 【Python爬虫】一个简单的网络爬虫
  10. AlgorithmMan,一套免费的算法演示神器(开源动画演示版)