目录
Variational Auto Encoder(变分自编码器)
De-noising Auto-encoder(降噪自动编码器)
Contractive Auto-encoders(收缩自编码器)
Discrete Representation(离散表示法)
Vector Quantized Variational Auto-encoder(矢量量化变分自编码器)
摘要
这周学习了自监督学习中的Auto-Encoder(自编码器),自编码器其实也是一种神经网络,它的输入和输出是一致的,目标是使用稀疏的高阶特征重新组合来重构自己。通过视频和自主查找资料学习,了解自编码器的概念和原理,其中最主要的是如何做数据降维。除此之外还有自编码器的几种变形,例如降噪自编码器。通过视频学习大概了解自编码器是如何做压缩、特征解耦、异常检测应用,然后通过代码搭建自编码器的网络结构,并阅读量一篇关于通过自编码器做情感分析的文献,进一步了解自编码器的实际应用,并培养阅读文献的习惯。
Abstract
This week, we learn about Auto Encoder in self supervised learning, which is actually a type of neural network with consistent inputs and outputs. The goal is to use sparse higher-order features to recombine and reconstruct oneself. Learn the concept and principle of autoencoders through videos and self searching materials, with the most important being how to perform data dimensionality reduction. In addition, there are several deformations of self encoders, such as noise reduction self encoders. Through video learning, gain a general understanding of how autoencoders perform compression, feature decoupling, and anomaly detection applications. Then, build the network structure of autoencoders through code, and read a literature on emotional analysis using autoencoders to further understand their practical applications and cultivate the habit of reading literature.
Auto-encoder(自编码器)
在前面我们学到Self-supervided Learning(自监督学习),也就是不需要标注资料就可以学习,也可以叫做Pre-train。Self-supervided的模型虽然只能做一些填空题,但是只要微微调整就可以做不同的下游任务,更古老的不需要标注资料的任务叫做Auto-encode(2016年),因此可以把Auto-encode看作是Self-supervided(2019年)中的一种Pre-train方法。
自编码器(Autoencoder)是一种无监督学习的神经网络模型,Auto-encode通常有两个神经网络即Encoder和Decoder,输入一张图片到Encoder中得到一个向量,将这个向量再经过Decoder得到一张照片,我们希望这个照片跟输入的照片越相似越好。也有人把这件事情叫做 Reconstruction,叫做重建,因为我们就是把一张图片,压缩成一个向量,接下来 Decoder 要根据这个向量,重建原来的图片,那我们希望原输入的结果,跟重建后的结果越接近越好,这个听起来跟之前学习的Cycle GNN。
Q:既然Auto-encoder是Self-supervided的一种,那Auto-encode怎么用在下游任务中呢?
A:一般Auto-encode的输入都是高维的向量,例如图片就是一个高维的向量,经过Encoder之后,得到的这个vector就是维度低的向量,因此就是利用这个新的向量来做下游任务,这就是Auto-encode用在下游任务的方法。
Encoder要做的事情就是将高维的东西转换成低维的,这个技术又叫做Dimension reduction,而得到的低维向量可以叫做bottleneck。
Auto-encode原理
自编码器算法属于Self-supervided(自监督)范畴,在监督学习中神经网络的功能:,其中
是输入的特征向量长度,
是网络输出的向量长度。对于分类问题,网络模型通过把长度为
输入特征向量
变换到长度为
的输出向量
,这个过程可以看成是特征降维的过程,把原始的高维输入向量
变换到低维的变量
。
Q:为什么要进行自编码呢?
A:希望通过添加一些限制条件,在训练Auto-encoder时将输入复制到输出中,同时得到的隐藏表示h 具有了有用的属性。重点是对于隐藏的表示h关注,从自编码器获得有用特征的一种方法是将h限制为小于x的维度,在这种情况下,自编码器是不完整的,我们强制自编码器学习训练数据的最显著特征。
Auto-encode训练过程
1.将输入数据提供给编码器,获得低维编码。
2.将编码结果传递给解码器,尝试重构输入数据。
3.计算重构损失,并通过反向传播优化网络参数,使重构误差最小化。
重复上述步骤,直到自编码器能够准确地重构输入数据。
Auto-encode作用:降维
假设图片大小是3✖3,而Encoder得到的向量是二维向量,那怎么能够将九个数值转换为两个数值,再转换为九个数值呢?其实图片的转换可能非常简单,又可能只要两种转换情况,因此可以用一个二维的数组进行表示。
因此Encoder做的事情就是化繁为简,实际看上去很复杂的东西只是表面复杂,它的变化确实有限的,因此只要找到它的有限变化,则可以将复杂的东西用简单的方法表示,运用在下游任务的时候,就只需要少量的训练资料就可以让机器学到要学的东西。
Auto-encoder变形
Variational Auto Encoder(变分自编码器)
VAE模型与Auto-encoder的区别在于,现在NN Encoder会输出两组向量、
,然后再从normal distribution中sample生成一个向量
,将
取exponential,然后再乘上向量
,最后加上
,得到的向量
就是code,将其放入NN Decoder得到输出。除了输入输出的误差要最小化之外还要满足右下角的目标。
De-noising Auto-encoder(降噪自动编码器)
De-noising Auto-encoder是Auto-encoder的一个变形,与Auto-encoder不同的是,Encouder的输入是输入的图片加上noise之后的图片,而Decoder的输出却要与输入的图片越相似越好。因此Auto-encoder要做的事情除了还原图片之外,还要自己学会去除杂质。
其实De-noising Auto-encoder的概念听起来很熟悉,这就跟上节学到的BERT非常相似。BERT的输入会加上MASK,MASK其实noise,BERT就对应了Encoder,输出的向量即为Enbedding,Linear模型即Decoder还原输入,Decoder不一定要是Linear,BERT至少有12层,那可以(前6层为Encoder,后6层为Decoder。
Sparse Auto-encoder(稀疏自编码器)
稀疏自编码器是在普通自动编码的基础上加上稀疏性限制,用来约束自动编码器重构的方法,是对其损失函数施加约束。比如,可对损失函数添加一个正则化约束,这样能使自编码器学习到数据的稀疏表征。
稀疏自编码器一般用来学习特征,以便用于像分类这样的任务。稀疏正则化的自编码器必须反映训练数据集的独特统计特征,而不是简单地充当恒等函数。以这种方式训练,执行附带稀疏惩罚的复现任务可以得到能学习有用特征的模型。对于稀疏自编码器而言,在隐含层中,加入了L1正则化作为优化阶段中损失函数的惩罚项。与普通自编码器相比,这样操作后的数据表征更为稀疏。
Contractive Auto-encoders(收缩自编码器)
为了使模型可以很好的重建输入信号,抑制训练样本在所有方向上的扰动。因此提出了收缩自编码器,提出在传统自编码器的目标函数上增加一个惩罚项来达到局部空间收缩的效果。该惩罚项是关于输入的隐藏层表达的Jacobian矩阵的F范数,其目的是为了使特征空间在训练数据附近的映射达到收缩效果。稀疏自编码器通过对大部分隐藏层神经元进行抑制,隐藏层输出对应于激活函数的左饱和区域,收缩自编码器通过对隐藏层神经元的输出推向它的饱和区域来达到收缩性。
Auto-encoder的应用
Feature Disentangle(特征解耦)
Auto-encoder的概念不仅可以用在图片上,也可以用在声音讯号以及文本内容上,例如声音讯号经过Encoder可以得到声音内容和说话人信息等,文本得到的向量可能包含语法等信息,但这些信息都是纠缠在一起,并不知道哪一维代表什么信息。
Feature Disentangle就是把一堆纠缠在一起的东西解开,在训练Auto-encoder的时候,知道enbedding中每一维代表什么,例如前五十维代表声音内容,后五十维代表说话人信息。
Feature Disentangle应用
Voice Conversion(声音变换)
在过去都是supervise learning,做Voice Conversion的时候需要成对资料,如果想要把A的声音转成B的声音,需要把A和B说同一句话的声音资料都找来,训练个几百次才行,但这种做法是不切实际的。
而今天有了Feature Disentangle之后,A和B不需要念同样的句子,甚至不需要同样的语言,机器也能学会把A的声音转成B的声音。
那具体怎么做的呢?
假设收集了大量人类声音讯号,训练出一个Auto-encoder,加上有了Feature Disentangle的技术,因此通过Encoder得到的向量可以分辨出哪些维度代表声音内容,哪些维度代表语者特征,接下来就可以做声音互换,例如有A和B两个声音讯号通过Encoder得到两个enbedding,从中取出A声音讯号的语言内容,取出B声音讯号中的语者特征,将两个向量拼接成一个完整的enbedding再放入Decoder就得到了用B的声音说出A说话内容的声音讯号。
Discrete Representation(离散表示法)
向量的表示有三种可能性: Real Numbers、Binary和One-hot! 比如Binary中某一个值就代表了是不是的问题, 是男的还是女的?戴眼镜了吗? 而One-hot也代表了分类任务,比如0-9手写体的识别!
Vector Quantized Variational Auto-encoder(矢量量化变分自编码器)
通过Encoder可以得到一个普通向量,而现有一个Codebook,它里面有一系列向量,这些向量是从Codebook中学习出来的数据, 同时也是预定义的向量。 然后我们去计算Encoder出的向量和Codebook中每个向量的相似度,相似度最高的那个向量就用来作为Decoder的输入, 类似于Self-attention,如果用Self-attention来理解的话就相当于key和value用的是同一个向量! 这样做的好处就是Decoder的输入是离散的,如果Codebook里有30个向量,那Decoder的输入就有30种选择。
Text as Representation
我们可不可以embedding出文字,而不是向量呢?如果输入是一个document,经过Encoder得到一个word aequence, 该文字序列经过Decoder后会得到又整个文章。 而该sequence就是文章的核心和摘要! 因为输入和输出都是sequence,因此这是一个seq2seq2seq的auto-encoder, 而这个任务仅仅需要一大堆的文件拉进行训练这个模型。但是这是不行的,因为Decoder会发明自己的暗号,中间生成的文字是看不懂的文字, 这要怎么办呢? 这个时候就可以添加一个Discriminator,Discriminator是可以分出输出是不是真汉字的,所以Discriminator可以判断中间的单词是不是问题。这样就可以添加双向限制, 既能生成文章, 又可以判断出是不是汉字! 这就是CycleGAN
Generator(生成器)
Auto-encoder里的Decoder可以通过输入的向量得到一张图片,这与Generator实现了一样的功能,我们可以将Decoder作为Generator, 我们通过模型训练之后则可以得到Decoder。
Comoression(压缩)
Auto-encoder也可以用来做压缩,当输入的图片很大的时候,我们可以把Encoder得到的结果往往是一个低维的向量,因此可以把它当作压缩后的结果,而Decoder做的事情就是解压缩,但这样的压缩是Lossy的压缩,得到的图片是会失真的。
Anomaly Detection(异常检测)
给一组训练资料训练一个Anomaly Detection,通过这个模型可以检查输入的和训练数据是不是一样。但是输入的
正确不正确完全取决于训练数据!如果判断的东西类型是训练资料里面没有的,那么它就会被判断是异常的。
例如人脸检测,我们检测是不是真人的人脸,而不是二次元的。如果我们的训练数据是一个真人照片,如果用一张同一个人的照片通过将它们encoder和Decoder,能合成真人图片。如果输入的是二次元图片,那么在经过encoder和decoder后是合成不了正常的图片的!
基于Pytorch的Auto-encoder实现
定义Auto-encoder网络结构
包括编码器、解码器的定义。其中输入数据经过编码器压缩为64维特征向量,再经过解码器还原为原始数据。编码器和解码器都为采用ReLU的普通神经网络,不同的是编码器的维度是递减的,而解码器的维度是递增的。
# 定义自编码器结构
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
定义参数
采用pytorch框架和MNIST数据集,定义了学习率、batch和epoch的大小。
learning_rate = 0.0003
batch_size = 64
epochsize = 30
root = 'D:/机器学习/数据集/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)
模型训练
实例化一个Auto-encoder,nn.MSELoss():定义训练的损失函数采用MSE(均方误差),optim.Adam:定义优化器采用Adam,函数参数为模型参数和学习率,利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。
AE = Auto_Encoder()
AE.load_state_dict(torch.load('AE.ckpt'))
criteon = nn.MSELoss()
optimizer = optim.Adam(AE.parameters(), lr=learning_rate)
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)
# 真假图像合并成一张
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')
测试结果
跑30次epoch 其中左边为第十次epoch的结果,右边是第三十次epoch的结果,可以明显看出训练结果越来越好了。
文献阅读:基于上下文自动编码器的情感分析新方法
题目:A New Method for Sentiment Analysis Using Contextual Auto-Encoders
作者:Hanen Ameur, Salma Jamoussi, Abdelmajid Ben Hamadou
2018,第33卷(6): 1307-1319
研究背景
情感分领域的主要目标是确定主观文本中描述的整体情感的极性取向(积极或消极)。现有技术可以分为两种主要的方法,即基于情感词典或词典的计算语言学方法,以及旨在使用机器学习方法(如SVM,朴素贝叶斯,Softmax)。为了避免构建情感词典的问题,研究者采用了统计方法而不是语言方法,虽然这种方法比语言方法表现出更好的能力,但它仍然存在一些局限性,比如选择能够捕捉文本特征中的有效特征来获得更好的分类性能。
现有的大多数使用统计方法的方法都遵循和使用词袋特征表示“BoW”,“BoW”通常关注特定词汇(频繁词、情感词汇、意见传达词等)的存在或频率。尽管其思想简单,但BoW特征空间的维数变得更大,数据表示更稀疏。因此,由于原始数据的高维度,情感分析的机器学习方法的准确性下降。然而,在用于表示文本的意义空间中提取低维向量非常重要,而机器学习的模型自编码器已经被引入来降低表征维数并学习有效特征。在这个方向下,许多研究集中在组合方法上,将单词表示向量组合成一个句子表示。在这些方法中有平均向量、递归自编码器RAE,然而这些方法有一些缺点。例如平均向量表示忽略了词序,而RAE表示模型需要一个相对缓慢、依赖于域的解析步骤,并且可能不正确或不可用。为了解决这些方法存在的缺陷,因此需要突出词序来递归地将构成句子的每个单词与其相邻的上下文单词向量组合起来。然后再通过分类器以获得更好的整体情感分类。
研究目的
介绍了一种新的基于深度成分表示方法的情感分析机器学习框架,一、学习单词的连续和低维向量,使用堆叠自编码器算法来降低单词向量的维数;二、使用这些单词向量来构建给定句子的组合向量表示,提出了一种新的句子表示模型,称为上下文递归自动编码器(CoRAE)。该模型通过尊重词序而不使用解析树结构来生成简化的向量表示。它的目的是通过突出词序来递归地将构成句子的每个单词与其相邻的上下文单词向量组合起来。然后,将CoRAE模型和支持向量机(SVM)分类器相结合,以获得更好的整体情感分类。
研究思路
首先分析现有的情感分析方法中存在的问题,即原始数据维度过高以及忽略了词序不关联上下文导致的“词义”不分的问题,基于自编码器模型在降低维度上的有效成果,提出一种新的基于深度成分表示方法的情感分析机器学习框架。
介绍了基于机器学习方法在做情感分析的相关工作,并对文本表示学习的方法进行了综述。介绍了一种新的情感分类嵌入表示方法,描述了词嵌入模型和句子嵌入的深度组合模型。
使用了两个常用的数据集进行情感分析,即Facebook评论语料库和Sanders twitter情感语料库。根据两个数据集的实验结果,以评估所提出方法的性能。最后,对全文进行了总结,并提出了今后的工作方向
研究意义
在该研究中引入了一种新的情感分析方法,该方法有两个新的贡献。
- 分布式单词表示模型,称为PMI-SA。该模型使用SA算法对最初由PMI表示的词向量进行约简。
- 使用这些连续词表示来生成句子向量表示。我们提出了一种新的深度组合模型,称为CoRAE。CoRAE模型旨在通过突出词序,将构成句子的每个单词与其相邻的上下文单词向量递归地组合起来。为了证明这些贡献的有效性,我们进行了一些实验来评估CoRAE模型,将其纳入监督分类器“SVM”中,用于两个常用数据集的二元情感分类。我们还根据基线方法评估了所提出的单词表示的有效性。
总结
这周主要学习了自监督学习模型之自编码器,其与一般神经网络的不同之处主要是,它并不是之间映射,而是通过编码和解码两个过程得到结果,其中自编码器的目的是为了使输入和输出越相似越好。自编码器最重要的是能够通过编码过程实现降维,因此可以将高维的输入转化成低维向量,用来做下游任务,因此自编码器可以与其他模型进行合理组合,减少模型的计算维度。