首页 > 编程知识 正文

编码器encoder,pyautogui教程

时间:2023-05-03 19:31:06 阅读:30803 作者:2205

文章目录1 .自编码器的介绍1 )传统的自编码器2 )降噪自编码器3 )卷积自编码器2 )自编码器的应用1 )字符检索2 )熟人图像检索(文本恢复)

1 .自编码器介绍

自编码器的思想很简单,就是把一张图像用编码器组成一个代码,把生成的代码用解码器重构成一张图像,希望重构的图像越接近原始图像越好。

1 )传统的自编码器通过神经网络实现传统的自编码器

传统自编码器的目的是使输出和输入尽可能相同,这完全可以通过学习两个恒等函数来实现,但这种变换没有任何意义。 之所以这么说,是因为我们关心的是隐层表现,而不是实际的输出。 因此,对自编码器的许多改进方法是对隐层表示施加一定的约束,迫使其学习隐层表示与输入的差异。 此时,如果模型能够重构输入信号,则隐藏层表示足以表示输入信号,该隐藏层表示是模型

2 )降噪自编码器的良好表现可以捕捉到输入信号的稳定结构,具有一定的鲁棒性,同时有助于信号的重构。

降噪自编码器的方案受到了人类对部分隐藏或损坏的图像也能正确识别的现象的启发。 因此,降噪自编码器的主要研究目标是隐层表示对局部破坏的输入信号具有鲁棒性。 也就是说,如果模型具有足够的鲁棒性,则局部损坏的输入应该与未损坏的干净输入几乎相同,但是使用该隐藏层表示可以重建完全干净的输入信号。

因此,噪声消除自编码器通过对净输入信号人为地施加噪声,局部地损伤净信号,生成与其对应损伤信号,将该损伤信号发送到以往的自编码器,尽可能重建与净输入相同的输出

3 )卷积自编码器的卷积神经网络得到的各种优良表现直接推动了卷积自编码器的生成。 严格来说,卷积自编码器是传统自编码器的特例,它使用卷积层和池化层来代替原始的全连通层。 传统的自编码器一般使用全连通层,对一维信号影响不大,但在二维图像和视频信号中全连通层会丢失空间信息,因此可以通过使用卷积操作来卷积自编码器

卷积自编码器与传统的自编码器非常相似,与卷积神经网络类似,因为卷积自编码器通过卷积方法对输入信号进行线性变换并共享其权重,所以重构处理是基于隐藏编码的基本图像块的线性组合。

对其中的Unpooling和Deconvolution可能有点理解问题。

Unpooling知道,卷积中的池化层最初通过在一个局部区域中平均化或最大化来实现大小的降低,通常池化后的比例大小为二分之一。 或者,池化也可以理解为下采样。 Unpooling可以理解为上采样。

一种实现方式是保留前面的池化的存储,即记住选择了最大值的区域,在尺度扩展时保留其最大值,在其他地方补0,从而实现尺寸的扩大。

另一种方法是直接将一模一样的值复制到单个扩展区域,而不是补充0。

未轮询后的效果:

2. Deconvolution

实际上,Deconvolution是convolution。 其中,convolution通过卷积降低维,但Deconvolution可以通过填充扩展维。 如下图所示,convolution是左侧操作,Deconvolution实际上是右侧操作。

2 .自编码器的应用基于自编码器降维得到的隐藏变量code,实际上有一些应用是可行的。

1 )文字检索(Text Retrieval )可以将一篇文章视为二维空间中的一个数据分布。 一篇文章代表了这个数据分布的一个点,所以一篇文章可以通过自编码器提取到二维码中。

然后根据这首歌二维码在数据空间的分布,搜索与其他文章的熟人,实现分类和其他操作。

2 )熟人图像检索实际上,也可以通过自己码搜索数据分布的能力进行图像检索。 具体来说,想找认识的图像时,如果根除我们使用的pixel之间的认识性,也就是两幅图像之间的像素点分布造成损失,往往得不到太好的结果。

但是,此时,能够将想要搜索的图像用编码器改变为代码,并用该代码进行检索。 也就是说,如果两张图像的代码,之间的差异比较小,相信这有可能找到我们需要的图像,最终结果往往比上诉的寻找像素之间分布的结果要好。 至少找到编码器的代码,我知道我们要找的是人像。

3 )在模型预训练(预训练)神经网络的训练中,我们知道初始化这个步骤通常是非常重要的,所以实际上使用自编码器来实现预训练的操作

当我们进行半监督学习时,我们通常有非常多的unlabel数据,然后只有很少的一部分带l

abel的data,那么这时候,我们就可以使用这些大量的unlabel的data来对模型进行预训练。

我们假设模型结构是3层隐藏层的全连接神经网络结构,那么对于第一层隐藏层来说,我们输入一个图像,然后通过自编码器,经过这隐层层得到一个1000维的code,而这个code其实就是第二层的隐含层。当然此时需要避免当code比图像的维度还要高的时候,网络可以原封不动的直接保留整个图像的维度信息,需要注意这点。然后通过Decoder将code重构出原来的模型,此时我们可以固定住第一层隐藏层的参数,因为这已经训练好了。

同样的,我们对第二层隐藏层就行训练,将第二层应汉成变成一个code,而这个code的维度就是第三层隐藏层的维度,然后再重构出来,然后再固定第二层隐藏层的参数。

类似的,对于其他的隐藏层操作类似。当保留好全部网络层数的参数时,这个网络就已经预训练好了。现在只需要使用那些少量的带label的data来对网络进行back propagation,稍微调整一下参数即可。

但是,其实对于现在的网络来说,没有初始化一般也是可以训练出来的,但这是得益于训练技术的提高,在曾经没有初始化与有初始化的差距还是比较大的。

3.自编码器的实现

框架使用Pytorch
数据集使用MNIST

参考代码

model.py

import torchimport torchvisionimport torch.nn as nn# 定义自编码器结构class Auto_Encoder(nn.Module): def __init__(self): super(Auto_Encoder, self).__init__() # 定义编码器结构 self.Encoder = nn.Sequential( nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 64), nn.ReLU(), nn.Linear(64, 20), nn.ReLU() ) # 定义解码器结构 self.Decoder = nn.Sequential( nn.Linear(20, 64), nn.ReLU(), nn.Linear(64, 256), nn.ReLU(), nn.Linear(256, 784), nn.Sigmoid() ) def forward(self, input): code = input.view(input.size(0), -1) code = self.Encoder(code) output = self.Decoder(code) output = output.view(input.size(0), 1, 28, 28) return output

train.py

import torchimport torchvisionfrom torch import nn, optimfrom torchvision import datasets, transformsfrom torchvision.utils import save_imagefrom torch.utils.data import DataLoaderfrom model import Auto_Encoderimport os# 定义超参数learning_rate = 0.0003batch_size = 64epochsize = 30root = 'E:/学习/机器学习/数据集/MNIST'sample_dir = "image"if not os.path.exists(sample_dir): os.makedirs(sample_dir)# 图像相关处理操作transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.5], std=[0.5])])# 训练集下载mnist_train = datasets.MNIST(root=root, train=True, transform=transform, download=False)mnist_train = DataLoader(dataset=mnist_train, batch_size=batch_size, shuffle=True)# 测试集下载mnist_test = datasets.MNIST(root=root, train=False, transform=transform, download=False)mnist_test = DataLoader(dataset=mnist_test, batch_size=batch_size, shuffle=True)# image,_ = iter(mnist_test).next()# print("image.shape:",image.shape) # torch.Size([64, 1, 28, 28])AE = Auto_Encoder()AE.load_state_dict(torch.load('AE.ckpt'))criteon = nn.MSELoss()optimizer = optim.Adam(AE.parameters(), lr=learning_rate)print("start train...")for epoch in range(epochsize): # 训练网络 for batchidx, (realimage, _) in enumerate(mnist_train): # 生成假图像 fakeimage = AE(realimage) # 计算损失 loss = criteon(fakeimage, realimage) # 更新参数 optimizer.zero_grad() loss.backward() optimizer.step() if batchidx%300 == 0: print("epoch:{}/{}, batchidx:{}/{}, loss:{}".format(epoch, epochsize, batchidx, len(mnist_train), loss)) # 生成图像 realimage,_ = iter(mnist_test).next() fakeimage = AE(realimage) # 真假图像pddmp一张 image = torch.cat([realimage, fakeimage], dim=0) # 保存图像 save_image(image, os.path.join(sample_dir, 'image-{}.png'.format(epoch + 1)), nrow=8, normalize=True) torch.save(AE.state_dict(), 'AE.ckpt') 结果展示


Epoch1生成的图像

Epoch10生成的图像

Epoch30生成的图像

结果可以看出慢慢训练得变好,但是还是有些模糊,使用VAE的效果可能会好一点。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。