自动编码器(autoencoder) 是神经网络的一种,该网络可以看作由两部分组成:一个编码器函数h = f(x) 和一个生成重构的解码器r = g(h)。传统上,自动编码器被用于降维或特征学习
自编码器原理示意图
编码器:将原始高维特征数据映射为低维度表征数据
解码器:将低纬度的压缩特征重构回原始数据
核心:输入特征等于输出特征
那么我们就会有一个疑问:压缩特征为什么小于输入特征?这里我们使用的是欠完备自动编码器:输入特征大于压缩特征.
下面我们手动编写一个自动编码器, 我们先来整理一下编写流程:
1. 获取数据
2. 模型搭建
3. 最优化设置
4. 模型训练
5. 数据3D可视化
然后呢, 我们就按照这个流程来编写我们的代码, 此代码的前提是有GPU, 代码才不会报错.
1. 获取数据
import numpy as np
import torch
import torchvision
import torchvision.transforms as tansforms
import torch.nn as nn
import torch.utils.data as data
# 数据集下载和导入
train_data = torchvision.datasets.MNIST(
root="./data/MNIST_data",
train=True,
transform=tansforms.ToTensor(),
download=True,
)
print(train_data.data.size()) # [60000,28,28]
print(train_data.targets.size()) # [60000]
# 显示图片
import matplotlib.pyplot as plt
# plt.imshow(train_data.data[10].numpy(),cmap="gray")
# plt.title("img_label:"+str(train_data.targets[10].numpy()))
# plt.show()
2. 模型搭建
class AutoEncoder(nn.Module):
def __init__(self):
super(AutoEncoder, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(28 * 28, 3),
nn.Tanh(),
)
self.decoder = nn.Sequential(
nn.Linear(3, 28 * 28),
nn.ReLU(),
)
def forward(self, x):
encode = self.encoder(x)
decode = self.decoder(encode)
return encode, decode
3. 最优化设置
# 网络初始化
EPOCH = 10 # 训练周期
BATCH_SIZE = 64
LR = 0.005 # 学习率
autoencoder = AutoEncoder()
if torch.cuda.is_available():
autoencoder = autoencoder.cuda()
optim = torch.optim.Adam(autoencoder.parameters(), lr=LR)
loss_func = nn.MSELoss()
# 图像初始化,用于动态展示训练结果
N_test_img = 5
f, a = plt.subplots(2, N_test_img, figsize=(5, 2))
plt.ion() # 持续绘图
# 原始图像
view_data = train_data.data[:N_test_img].view(-1, 28 * 28).type(torch.FloatTensor)
for i in range(N_test_img):
a[0][i].imshow(np.reshape(view_data.data.numpy()[i], (28, 28)), cmap="gray")
a[0][i].set_xticks(())
a[0][i].set_yticks(())
上图为显示的效果图
4. 模型训练
# 训练网络
train_loader = data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
for epoch in range(EPOCH):
for i, (x, y) in enumerate(train_loader):
if torch.cuda.is_available():
x = x.cuda()
b_x = x.view(-1, 28 * 28) # [batch_size,28*28]
encode, decode = autoencoder(b_x)
loss = loss_func(decode, b_x) # 均方误差损失函数
optim.zero_grad() # 清空梯度缓存
loss.backward()
optim.step()
if i % 500 == 0:
print("Epoch:", epoch, " train loss: ", loss.item())
# 绘制解码图像,第二行
_, decode = autoencoder(view_data.cuda())
for i in range(N_test_img):
a[1][i].clear()
a[1][i].imshow(np.reshape(decode.cpu().data.numpy()[i], (28, 28)), cmap="gray")
a[1][i].set_xticks(())
a[1][i].set_yticks(())
plt.draw()
plt.pause(0.05)
plt.ioff()
plt.show()
下图为显示的效果图:
5. 数据3D可视化
# 3D可视化
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
view_data = train_data.data[:200].view(-1,28*28).type(torch.FloatTensor)/255.
encode,_ = autoencoder(view_data.cuda())
fig =plt.figure()
ax = Axes3D(fig)
X = encode.cpu().data[:,0].numpy()
Y = encode.cpu().data[:,1].numpy()
Z = encode.cpu().data[:,2].numpy()
values = train_data.targets[:200].numpy()
for x,y,z,s in zip(X,Y,Z,values):
c = cm.rainbow(int(255*s/9))
ax.text(x,y,z,s,backgroundcolor=c)
ax.set_xlim(X.min(),X.max())
ax.set_ylim(Y.min(),Y.max())
ax.set_zlim(Z.min(),Z.max())
plt.show()
plt.pause(50)
下图为显示的效果图:
原文链接:https://blog.csdn.net/junjunzai123/article/details/107006799