精华内容
下载资源
问答
  • 自编码器及其变形很多,本篇博客目前主要基于普通自编码器、欠完备自编码器、稀疏自编码器和去噪自编码器,会提供理论+实践(有的理论本人没有完全理解,就先没有写上,后更)。另外,关于收缩自编码器、变分自编码...

    写在前面

    因为时间原因本文有些图片自己没有画,来自网络的图片我尽量注出原链接,但是有的链接已经记不得了,如果有使用到您的图片,请联系我,必注释。

    自编码器及其变形很多,本篇博客目前主要基于普通自编码器、栈式自编码器、欠完备自编码器、稀疏自编码器和去噪自编码器,会提供理论+实践(有的理论本人没有完全理解,就先没有写上,后更)。另外,关于收缩自编码器、变分自编码器、CNN自编码器、RNN自编码器及其自编码器的应用,后更。

    本文展示的所有完整代码详见:完整代码
    (目前只有Keras版本,有时间会写Tensorflow版本)

    文章较长,PDF版点击链接:PDF版

    一、自编码器(Autoencoder, AE)

    1、自编码器的结构和思想

    自编码器是一种无监督的数据维度压缩和数据特征表达方法。
    自编码器是神经网络的一种,经过训练后能尝试将输入复制到输出。自编码器由编码器和解码器组成,如下图所示(图片来源:深度学习浅层理解(三)— 常用模型之自编码器):

    h = f ( x ) h=f(x) h=f(x)表示编码器, r = g ( h ) = g ( f ( x ) ) r=g(h)=g(f(x)) r=g(h)=g(f(x))表示解码器,自编码的目标便是优化损失函数 L ( x , g ( f ( x ) ) L(x,g(f(x)) L(x,g(f(x)),也就是减小图中的Error。

    2、自编码器和前馈神经网络的比较

    二者的区别和联系如下:

    (1)自编码器是前馈神经网络的一种,最开始主要用于数据的降维以及特征的抽取,随着技术的不断发展,现在也被用于生成模型中,可用来生成图片等。
    (2)前馈神经网络是有监督学习,其需要大量的标注数据。自编码器是无监督学习,数据不需要标注因此较容易收集。
    (3)前馈神经网络在训练时主要关注的是输出层的数据以及错误率,而自编码的应用可能更多的关注中间隐层的结果。

    3、自编码器和受限玻尔兹曼机的比较

    关于受限玻尔兹曼机的博客请参见:[受限玻尔兹曼机] 原理、求解、深度信念网络
    二者的区别和联系如下:

    (1)自编码器和受限自编码器的相同点如下:①都起到了降维的作用;②都可以用来对神经网络进行预训练;③训练都是无监督的。
    (2)自编码器和受限自编码器的不同点如下:①自编码器希望通过非线性变换找到输入数据的特征表示,其重构的是输入分布与reconstruct分布的KL距离,它是某种确定论性的模型;而RBM则是围绕概率分布进行的,它通过输入数据的概率分布来提取中间层表示,它是某种概率论性的模型。②AE使用的是BP算法进行优化,而RBM是基于概率模型,使用CD算法进行优化。

    4、普通自编码器存在的问题

    在普通的自编码器中,输入和输出是完全相同的,因此输出对我们来说没有什么应用价值,所以我们希望利用中间隐层的结果,比如,可以将其作为特征提取的结果、利用中间隐层获取最有用的特性等。
    但是如果只使用普通的自编码器会面临什么问题呢?比如,输入层和输出层的维度都是5,中间隐层的维度也是5,那么我们使用相同的输入和输出来不断优化隐层参数,最终得到的参数可能是这样: x 1 − > a 1 , x 2 − > a 2 , … x1->a1,x2->a2,… x1>a1x2>a2的参数为1,其余参数为0,也就是说,中间隐层的参数只是完全将输入记忆下来,并在输出时将其记忆的内容完全输出即可,神经网络在做恒等映射,产生数据过拟合。如下图所示(图片来源:Introduction to autoencoders.):

    上图是隐层单元数等于输入维度的情况,当然,如果是隐层单元数大于输入维度,也会发生类似的情况,即当隐层单元数大于等于输入维度时,网络可以采用完全记忆的方式,虽然这种方式在训练时精度很高,但是复制的输出对我们来说毫无意义
    因此,我们会给隐层加一些约束,如限制隐藏单元数、添加正则化等,后面后介绍。

    5、自编码器实现与结果分析

    (1)实现框架: Keras
    (2)数据集: Mnist手写数字识别
    (3)关键代码:

    def train(x_train):
        """
        build autoencoder.
        :param x_train:  the train data
        :return: encoder and decoder
        """
        # input placeholder
        input_image = Input(shape=(ENCODING_DIM_INPUT, ))
    
        # encoding layer
        hidden_layer = Dense(ENCODING_DIM_OUTPUT, activation='relu')(input_image)
        # decoding layer
        decode_output = Dense(ENCODING_DIM_INPUT, activation='relu')(hidden_layer)
    
        # build autoencoder, encoder, decoder
        autoencoder = Model(inputs=input_image, outputs=decode_output)
        encoder = Model(inputs=input_image, outputs=hidden_layer)
    
        # compile autoencoder
        autoencoder.compile(optimizer='adam', loss='mse')
    
        # training
        autoencoder.fit(x_train, x_train, epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True)
    
        return encoder, autoencoder
    

    (4)代码分析:
    Keras封装的比较厉害,所以傻瓜式编程,这里是最简单的自编码器,其输入维度是28*28=784,中间单隐层的维度是2,使用的激活函数是Relu,返回encoder和autoencoder。encoder部分可以用于降维后的可视化,或者降维之后接分类等,autoencoder可以用来生成图片等(这部分代码git上都有)。结构见图如下:

    (5)结果展示:

    (i)Eencoder结果的可视化如图:

    上图中不同表示表示不同的数字,由图可知,自编码器降维之后的结果并不能很好地表示10个数字。

    (ii)autoencoder还原之后的图片和原图片对比如下:

    上图说明,autoencoder的生成结果不是很清晰。

    二、栈式自编码器(Stack Autoencoder)

    1、栈式自编码器思想

    栈式自编码器又称为深度自编码器,其训练过程和深度神经网络有所区别,下面是基于栈式自编码器的分类问题的训练过程(图片来自台大李宏毅老师的PPT):
    栈式自编码器训练过程
    即过程如下:
    首先,训练784->1000->784的自编码器,而后已经固定已经训练好的参数和1000维的结果,训练第二个自编码器:1000->1000->1000,而后固定已经训练好的参数和训练的中间层结果,训练第三个自编码器:1000->500->1000,固定参数和中间隐层的结果。此时,前3层的参数已经训练完毕,此时,最后一层接一个分类器,将整体网络使用反向传播进行训练,对参数进行微调。这便是使用栈式自编码器进行分类的整体过程。
    注:encoder和decoder的参数可以是对称的,也可以是非对称的。

    2、栈式自编码器的特点

    ①增加隐层可以学到更复杂的编码,每一层可以学习到不同的信息维度。
    ②若层数太深,encoder过于强大,可以将学习将输入映射为任意数(然后decoder学习其逆映射)。这一编码器可以很好的重建数据,但它并没有在这一过程中学到有用的数据表示。

    3、栈式自编码器和深度信念网络的异同点

    ①自编码器栈式自编码器;受限玻尔兹曼机深度信念网络
    ②栈式自编码器和深度信念网络都是逐层训练。
    ③栈式自编码器和深度信念网络的训练方法不同,栈式自编码器使用BP算法训练参数,深度信念网络使用的是对比散度算法。

    4、栈式自编码器实现与结果分析

    (1)实现框架: Keras
    (2)数据集: Mnist手写数字识别
    (3)关键代码:

    def train(x_train):
    
        # input placeholder
        input_image = Input(shape=(ENCODING_DIM_INPUT, ))
    
        # encoding layer
        encode_layer1 = Dense(ENCODING_DIM_LAYER1, activation='relu')(input_image)
        encode_layer2 = Dense(ENCODING_DIM_LAYER2, activation='relu')(encode_layer1)
        encode_layer3 = Dense(ENCODING_DIM_LAYER3, activation='relu')(encode_layer2)
        encode_output = Dense(ENCODING_DIM_OUTPUT)(encode_layer3)
    
        # decoding layer
        decode_layer1 = Dense(ENCODING_DIM_LAYER3, activation='relu')(encode_output)
        decode_layer2 = Dense(ENCODING_DIM_LAYER2, activation='relu')(decode_layer1)
        decode_layer3 = Dense(ENCODING_DIM_LAYER1, activation='relu')(decode_layer2)
        decode_output = Dense(ENCODING_DIM_INPUT, activation='tanh')(decode_layer3)
    
        # build autoencoder, encoder
        autoencoder = Model(inputs=input_image, outputs=decode_output)
        encoder = Model(inputs=input_image, outputs=encode_output)
    
        # compile autoencoder
        autoencoder.compile(optimizer='adam', loss='mse')
    
        # training
        autoencoder.fit(x_train, x_train, epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True)
    
        return encoder, autoencoder
    

    栈式自编码器相当于深度网络的过程,主要注意维度对应即可,另外,这里设置的encoder和decoder的维度是对称的。其架构图如下:

    (4)结果展示:

    (i)Eencoder结果的可视化如图:

    上图中不同表示表示不同的数字,由图可知,栈式自编码器的效果相比较普通自编码器好很多,这里基本能将10个分类全部分开。

    (ii)autoencoder还原之后的图片和原图片对比如下:

    三、欠完备自编码器(Undercomplete Autoencoder)

    1、欠完备自编码器的思想

    由上述自编码器的原理可知,当隐层单元数大于等于输入维度时,网络会发生完全记忆的情况,为了避免这种情况,我们限制隐层的维度一定要比输入维度小,这就是欠完备自编码器,如下图所示(图片来源:Introduction to autoencoders.)。 学习欠完备的表示将强制自编码器捕捉训练数据中最显著的特征。

    2、欠完备自编码器和主成分分析(PCA)的比较

    实际上,若同时满足下列条件,欠完备自编码器的网络等同于PCA,其会学习出于PCA相同的生成子空间:

    • 每两层之间的变换均为线性变换。
    • 目标函数 L ( x , g ( f ( x ) ) L(x,g(f(x)) L(x,g(f(x))为均方误差。

    因此,拥有非线性编码器函数 f f f和非线性解码器函数 g g g的自编码器能够学习出比PCA更强大的知识,其是PCA的非线性推广。下图是在二维空间中PCA算法和自编码器同时作用在二维点上做映射的结果(图片来源:Introduction to autoencoders.) ,从图中可以看出,自编码器具有更好的表达能力,其可以映射到非线性函数。

    3、欠完备自编码器特点

    • 防止过拟合,并且因为隐层编码维数小于输入维数,可以学习数据分布中最显著的特征。
    • 若中间隐层单元数特别少,则其表达信息有限,会导致重构过程比较困难。

    四、稀疏自编码器(Sparse Autoencoder)

    1、稀疏自编码器思想

    稀疏自编码器是加入正则化的自编码器,其未限制网络接收数据的能力,即不限制隐藏层的单元数。
    所谓稀疏性限制是指:

    若激活函数是sigmoid,则当神经元的输出接近于1的时候认为神经元被激活,输出接近于0的时候认为神经元被抑制。使得大部分神经元别抑制的限制叫做稀疏性限制。若激活函数是tanh,则当神经元的输出接近于-1的时候认为神经元是被抑制的。

    如上图所示(图片来源:Introduction to autoencoders. ),浅色的神经元表示被抑制的神经元,深色的神经元表示被激活的神经元。通过稀疏自编码器,我们没有限制隐藏层的单元数,但是防止了网络过度记忆的情况。
    稀疏自编码器损失函数的基本表示形式如下:
    L s p a r s e ( x , g ( f ( x ) ) ) = L ( x , g ( f ( x ) ) ) + Ω ( h ) L_{sparse}(x, g(f(x)))=L(x, g(f(x))) + \Omega (h) Lsparse(x,g(f(x)))=L(x,g(f(x)))+Ω(h)
    其中 g ( h ) g(h) g(h)是解码器的输出,通常 h h h是编码器的输出,即 h = f ( x ) h=f(x) h=f(x)

    2、损失函数和BP函数推导

    损失函数可以加入L1正则化,也可以加入KL散度,下面是对加入KL散度的损失函数的分析。
    损失函数的分析如下:
    假设 a j ( 2 ) ( x ) a_j^{(2)}(x) aj(2)(x)表示在给定输入 x x x的情况下,自编码网络隐层神经元 j j j的激活度,则神经元在所有训练样本上的平均激活度为:
    ρ j ^ = 1 m ∑ i = 1 m [ a j ( 2 ) ( x i ) ] \hat{\rho_j}=\frac{1}{m}\sum_{i=1}^{m}[a_j^{(2)}(x^{i})] ρj^=m1i=1m[aj(2)(xi)]
    其中, a j ( 2 ) = f ( w j ( 1 ) x ( i ) + b j ( 1 ) ) a_j^{(2)}=f(w_j^{(1)}x^{(i)}+b_j^{(1)}) aj(2)=f(wj(1)x(i)+bj(1)),我们的目的使得网络激活神经元稀疏,所以可以引入一个稀疏性参数 ρ \rho ρ,通常 ρ \rho ρ是一个接近于0的值(即表示隐藏神经元中激活神经元的占比)。则若可以使得 ρ j ^ = ρ \hat{\rho_j}=\rho ρj^=ρ,则神经元在所有训练样本上的平均激活度 ρ j ^ \hat{\rho_j} ρj^便是稀疏的,这就是我们的目标。为了使得 ρ j ^ = ρ \hat{\rho_j}=\rho ρj^=ρ,我们使用KL散度衡量二者的距离,两者相差越大,KL散度的值越大,KL散度的公式如下:
    ∑ j = 1 s 2 K L ( ρ ∣ ∣ ρ j ^ ) = ∑ j = 1 s 2 [ ρ log ⁡ ρ ρ j ^ + ( 1 − ρ ) log ⁡ 1 − ρ 1 − ρ j ^ ] \sum_{j=1}^{s_2}KL(\rho||\hat{\rho_j})=\sum_{j=1}^{s_2} [\rho \log \frac{\rho}{\hat{\rho_j}} + (1-\rho) \log \frac{1-\rho}{1-\hat{\rho_j}}] j=1s2KL(ρρj^)=j=1s2[ρlogρj^ρ+(1ρ)log1ρj^1ρ]
    ρ \rho ρ表示平均激活度的目标值。因此损失函数如下:
    J s p a r s e ( W , b ) = J ( W , b ) + β ∑ j = 1 s 2 K L ( ρ ∣ ∣ ρ j ^ ) J_{sparse}(W,b)=J(W,b)+\beta \sum_{j=1}^{s_2}KL(\rho||\hat{\rho_j}) Jsparse(W,b)=J(W,b)+βj=1s2KL(ρρj^)
    其中 J ( W , b ) J(W, b) J(W,b)便是NN网络中的普通的代价函数,可以使用均方误差等。

    反向传播的分析如下:
    上式代价函数,左部分就是之前BP的结果,结果如下:
    ∂ J ( W , b ) ∂ z i ( 2 ) = ∑ j = 1 s 2 W j i ( 2 ) ∂ J ( W , b ) ∂ z i ( 3 ) f ′ ( z i ( 2 ) ) \frac{\partial J(W,b)}{ \partial z_i^{(2)}} = \sum_{j=1}^{s_2}W_{ji}^{(2)}\frac{\partial J(W,b)}{ \partial z_i^{(3)}}{f}'(z_i^{(2)}) zi(2)J(W,b)=j=1s2Wji(2)zi(3)J(W,b)f(zi(2))
    可参考反向传导算法

    右部分的求导如下:

    ∂ ∑ j = 1 s 2 K L ( ρ ∣ ∣ ρ j ^ ) ∂ z i ( 2 ) = ∂ K L ( ρ ∣ ∣ ρ i ^ ) ∂ z i ( 2 ) = ∂ K L ( ρ ∣ ∣ ρ i ^ ) ∂ ρ i ^ ⋅ ∂ ρ i ^ ∂ z i ( 2 ) = ∂ ( ρ log ⁡ ρ ρ i ^ + ( 1 − ρ ) log ⁡ 1 − ρ 1 − ρ i ^ ) ∂ ρ i ^ ⋅ ∂ ρ i ^ ∂ z i ( 2 ) = ( − ρ ρ i ^ + 1 − ρ 1 − ρ i ^ ) ⋅ f ′ ( z i ( 2 ) ) \begin{aligned} \frac{\partial \sum_{j=1}^{s_2}KL(\rho||\hat{\rho_j})}{\partial z_i^{(2)}} &= \frac{\partial KL(\rho||\hat{\rho_i})}{\partial z_i^{(2)}} \newline \\ &= \frac{\partial KL(\rho||\hat{\rho_i})}{\partial \hat{\rho_i}}\cdot \frac{\partial \hat{\rho_i}}{\partial z_i^{(2)}} \\ &= \frac{\partial(\rho \log \frac{\rho}{\hat{\rho_i}}+(1-\rho) \log \frac{1-\rho}{1-\hat{\rho_i}})}{\partial\hat{\rho_i}}\cdot \frac{\partial \hat{\rho_i}}{\partial z_i^{(2)}} \\ &= (-\frac{\rho}{\hat{\rho_i}} + \frac{1-\rho}{1-\hat{\rho_i}}) \cdot {f}'(z_i^{(2)}) \end{aligned} zi(2)j=1s2KL(ρρj^)=zi(2)KL(ρρi^)=ρi^KL(ρρi^)zi(2)ρi^=ρi^(ρlogρi^ρ+(1ρ)log1ρi^1ρ)zi(2)ρi^=(ρi^ρ+1ρi^1ρ)f(zi(2))
    因此 J s p a r s e ( W , b ) J_{sparse}(W,b) Jsparse(W,b)的求导结果如下:
    ∂ J s p a r s e ( W , b ) ∂ z i ( 2 ) = ( ( ∑ j = 1 s 2 W j i ( 2 ) ∂ J ( W , b ) ∂ z i ( 3 ) ) + β ( − ρ ρ i ^ + 1 − ρ 1 − ρ i ^ ) ) f ′ ( z i ( 2 ) ) \frac{\partial J_{sparse}(W,b)}{ \partial z_i^{(2)}}= ((\sum_{j=1}^{s_2}W_{ji}^{(2)}\frac{\partial J(W,b)}{ \partial z_i^{(3)}})+ \beta(-\frac{\rho}{\hat{\rho_i}} + \frac{1-\rho}{1-\hat{\rho_i}})){f}'(z_i^{(2)}) zi(2)Jsparse(W,b)=((j=1s2Wji(2)zi(3)J(W,b))+β(ρi^ρ+1ρi^1ρ))f(zi(2))
    此即反向传播的方程,根据此方程可以参数 W W W b b b进行更新。

    3、Mini-Batch的情况

    平均激活度是根据所有样本计算出来的,所以在计算任何单元的平均激活度之前,需要对所有样本计算一下正向传播,从而获得平均激活度,所以使用小批量时计算效率很低。要解决这个问题,可采取的方法是只计算Mini-Batch中包含的训练样本的平均激活度,然后在Mini-Batch之间计算加权值
    ρ ^ j t = λ ρ ^ j t − 1 + ( 1 − λ ) ρ ^ j t \hat{\rho}_j^t=\lambda\hat{\rho}_j^{t-1}+(1-\lambda)\hat{\rho}_j^t ρ^jt=λρ^jt1+(1λ)ρ^jt
    其中, ρ ^ j t \hat{\rho}_j^t ρ^jt是时刻 t t t的Mini-Batch的平均激活度, ρ ^ j t − 1 \hat{\rho}_j^{t-1} ρ^jt1是时刻t-1的Mini-Batch的平均激活度。若\lambda大,则时刻 t − 1 t-1 t1的Mini-Batch的平均激活度所占比重大,否则,时刻t的Mini-Batch的平均激活度所占比重大。

    4、稀疏限制和L1/L2正则化的关系

    ①稀疏限制是对激活函数的结果增加限制,使得尽量多的激活函数的结果为0(如果激活函数是tanh,则为-1)
    ②L2/L1是对参数增加限制,使得尽可能多的参数为0。
    若自编码器编码函数 f ( w x + b ) f(wx+b) f(wx+b),若 f f f是一个线性函数,则编码器便可以写成 w x + b wx+b wx+b,限制激活函数的结果尽量为0,即是限制 w w w尽量为0,此时稀疏限制和正则化限制相同。

    5、稀疏自编码器在分类中的应用

    稀疏自编码器一般用来学习特征,以便用于像分类这样的任务。如下图(图片来源:为什么稀疏自编码器很少见到多层的?):

    上述过程不是一次训练的,可以看到上面只有编码器没有解码器,因此其训练过程是自编码器先使用数据训练参数,然后保留编码器,将解码器删除并在后面接一个分类器,并使用损失函数来训练参数已达到最后效果。

    5、稀疏编码器实现与结果分析

    (1)框架: Keras
    (2)数据集: Mnist手写数字识别
    (3)关键代码:

    def train(x_train):
    
        # input placeholder
        input_image = Input(shape=(ENCODING_DIM_INPUT, ))
    
        # encoding layer
        # *****!!! this code is changed compared with Autoencoder, adding the activity_regularizer to make the input sparse.
        encode_layer1 = Dense(ENCODING_DIM_LAYER1, activation='relu', activity_regularizer=regularizers.l1(10e-6))(input_image)
        # *******************************************************
        encode_layer2 = Dense(ENCODING_DIM_LAYER2, activation='relu')(encode_layer1)
        encode_layer3 = Dense(ENCODING_DIM_LAYER3, activation='relu')(encode_layer2)
        encode_output = Dense(ENCODING_DIM_OUTPUT)(encode_layer3)
    
        # decoding layer
        decode_layer1 = Dense(ENCODING_DIM_LAYER3, activation='relu')(encode_output)
        decode_layer2 = Dense(ENCODING_DIM_LAYER2, activation='relu')(decode_layer1)
        decode_layer3 = Dense(ENCODING_DIM_LAYER1, activation='relu')(decode_layer2)
        decode_output = Dense(ENCODING_DIM_INPUT, activation='tanh')(decode_layer3)
    
        # build autoencoder, encoder
        autoencoder = Model(inputs=input_image, outputs=decode_output)
        encoder = Model(inputs=input_image, outputs=encode_output)
    
        # compile autoencoder
        autoencoder.compile(optimizer='adam', loss='mse')
    
        # training
        autoencoder.fit(x_train, x_train, epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True)
    
        return encoder, autoencoder
    

    这里是以多层的自编码器举例,单隐层的同样适用,主要是在第一层加一个正则化项,activity_regularizer=regularizers.l1(10e-6)说明加入的是L1正则化项,10e-6是正则化项系数,完整代码可参见最开始的git。其架构如下:

    (4)结果展示:
    (i)Encoder结果的可视化如图:

    上图中不同颜色表示不同的数字,由图可知,这个编码器的分类效果还可以,比自编码器好很多,但是看起来还是作用不大,因为大部分作用需要归功于栈式自编码器。

    (ii)autoencoder还原之后的图片和原图片对比如下:

    五、去噪自编码器(Denoising Autoencoder)

    1、去噪自编码器思想

    去噪自编码器是一类接受损失数据作为输入,并训练来预测原始未被损坏的数据作为输出的自编码器。 如下图所示(图片来自花书):

    其训练过程如下:
    引入一个损坏过程 C ( x ~ ∣ x ) C(\tilde{x}|x) C(x~x),这个条件分布代表给定数据样本 x x x产生损坏样本 x ~ \tilde{x} x~的概率。自编码器学习重构分布 p r e c o n s t r u c t ( x ∣ x ~ ) p_{reconstruct}(x|\tilde{x}) preconstruct(xx~):

    • 从训练数据中采一个训练样本 x x x
    • C ( x ~ ∣ X = x ) C(\tilde{x}|X=x) C(x~X=x)采一个损坏样本 x ~ \tilde{x} x~
    • ( x ~ , x ) (\tilde{x}, x) (x~,x)作为训练样本来估计自编码器的重构分布 p r e c o n s t r u c t ( x ∣ x ~ ) = p d e c o d e r ( x ∣ h ) p_{reconstruct}(x|\tilde{x})=p_{decoder}(x|h) preconstruct(xx~)=pdecoder(xh),其中 h h h是编码器 f ( x ~ ) f(\tilde{x}) f(x~)的输出, p d e c o d e r p_{decoder} pdecoder根据解码函数 g ( h ) g(h) g(h)定义。

    去噪自编码器中作者给出的直观解释是:和人体感官系统类似,比如人的眼睛看物体时,如果物体的某一小部分被遮住了,人依然能够将其识别出来,所以去噪自编码器就是破坏输入后,使得算法学习到的参数仍然可以还原图片。
    注: 噪声可以是添加到输入的纯高斯噪声,也可以是随机丢弃输入层的某个特性。

    2、去噪自编码器和Dropout

    噪声可以是添加到输入的纯高斯噪声,也可以是随机丢弃输入层的某个特性,即如果 C ( x ~ ∣ X = x ) C(\tilde{x}|X=x) C(x~X=x)是一个二项分布,则其表现为下图所示内容,即经过处理的 x x x的结果是保留或者舍掉,也就是说, C ( x ~ ∣ X = x ) C(\tilde{x}|X=x) C(x~X=x)会舍去一部分内容,保留一部分内容:

    这个思想类似于Dropout,但是二者还有一些区别:

    (1) 去噪自编码器操作的是输入数据,相当于对输入数据去掉一部分内容;而Dropout操作的是网络隐藏层,相当于去掉隐藏层的一部分单元。
    (2) Dropout在分层预训练权值的过程中是不参与的,只是后面的微调部分会加入;而去噪自编码器是在每层预训练的过程中作为输入层被引入,在进行微调时不参与

    3、去噪自编码器和PCA

    去噪自编码器来源于论文[Vincent P, Larochelle H, Bengio Y, et al. Extracting and composing robust features with denoising autoencoders[C]//Proceedings of the 25th international conference on Machine learning. ACM, 2008: 1096-1103.]

    上图是去噪自编码器从流形角度的原理,图中黑色的曲线表示原始的局部流型,我们通过 C ( x ~ ∣ X = x ) C(\tilde{x}|X=x) C(x~X=x)将其映射到一个圆的某一点, x ~ \tilde{x} x~表示添加噪声之后数据点。我们的目标是使得添加噪声之后的点能够映射到原始点,这样损失值为最小,即:图中红色箭头是噪声添加的向量场,而紫色部分是重构过程中需要不断查找的向量场。
    因此,可以理解为,去噪自编码器的局部就是简化的PCA原理,其是对PCA的非线性扩展。
    除此之外,文章还从信息论文、随机算子等角度理论上证明了去噪自编码器的可行性,有兴趣的读者可以参考上面提到的论文。

    4、去噪自编码器效果

    论文中的实验基于Minst数据集,其实验结果如下:

    其中,第一个和第二个baseline是使用高斯核和多项式核的SVM,DBN-1是1层隐层单元的深度信念网络,DBN-3是3层隐层单元的深度信念网络,SAA-3是使用栈式自编码器初始化之后的3层深度网络,最后的Sda-3是3层的栈式去噪自编码器。从表中可以看出,使用去噪自编码器的结果优于其他网络。
    除此之外,网站Denoising Autoencoders (dA)有去噪自编码器的代码和实验,其去噪前和去噪后过滤器的对比结果如下:

    左图是去噪之前的过滤器数据,右图是去噪之后的过滤器数据,从图中可以看出,去噪自编码器学习到的特征更具代表性。。

    5、去噪自编码器特点

    • 普通的自编码器的本质是学一个相等函数,即输入和输出是同一个内容,这种相等函数的缺点便是当测试样本和训练样本不符合同一个分布时,在测试集上效果不好,而去噪自编码器可以很好地解决这个问题。
    • 欠完备自编码器限制学习容量,而去噪自编码器允许学习容量很高,同时防止在编码器和解码器学习一个无用的恒等函数。
    • 经过了加入噪声并进行降噪的训练过程,能够强迫网络学习到更加鲁棒的不变性特征,获得输入的更有效的表达。

    6、去噪编码器实现与结果分析

    (1)框架: Keras
    (2)数据集: Mnist手写数字识别
    (3)关键代码:

    def addNoise(x_train, x_test):
        """
        add noise.
        :return:
        """
        x_train_noisy = x_train + NOISE_FACTOR * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape)
        x_test_noisy = x_test + NOISE_FACTOR * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape)
    
        x_train_noisy = np.clip(x_train_noisy, 0., 1.)     # limit into [0, 1]
        x_test_noisy = np.clip(x_test_noisy, 0., 1.)   # limit into [0, 1]
    
        return x_train_noisy, x_test_noisy
    

    去噪自编码器主要是对输入添加噪声,所以训练过程是不需要改变的,只需要改变输入和输出。上述便是对输入添加噪声的过程,NOISE_FACTOR * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape)便是添加的噪声。 np.clip()是截取函数,将数值限制在0~1之间。其架构如下:

    (4)结果展示:
    (i)Eencoder结果的可视化如图:

    上图中不同表示表示不同的数字,这里不是很直观,看下面的图片对比

    (ii)autoencoder还原之后的图片和原图片对比如下:

    上图是添加噪声的效果对比,第一行表示原数据,第二行表示噪声处理过后的数据。

    上图根据噪声数据还原图片的对比,第一行表示噪声处理过后的数据,第二行表示去噪自编码器decoder还原之后的结果,上图可以看出,去噪自编码器的效果还是可以的。

    六、卷积自编码器(convolutional Autoencoder)

    1、卷积自编码器思想

    卷积自编码器和普通自编码器的区别在于其encoder和decoder都是卷积神经网络,相应的,encoder使用的是卷积操作和池化操作,而decoder中使用的反卷积操作和反卷积操作,关于卷积、反卷积、池化和反池化的内容详见:[CNN] 卷积、反卷积、池化、反池化

    2、去噪编码器实现与结果分析

    (1)框架: Keras
    (2)数据集: Mnist手写数字识别
    (3)关键代码:

    def train(x_train):
        """
        build autoencoder.
        :param x_train:  the train data
        :return: encoder and decoder
        """
        # input placeholder
        input_image = Input(shape=(28, 28, 1))
    
        # encoding layer
        x = Conv2D(CHANNEL_1, (3, 3), activation='relu', padding="same")(input_image)
        x = MaxPool2D((2, 2), padding='same')(x)
        x = Conv2D(CHANNEL_2, (3, 3), activation='relu', padding='same')(x)
        encoded = MaxPool2D((2, 2), padding='same')(x)
    
        # decoding layer
        x = Conv2D(CHANNEL_2, (3, 3), activation='relu', padding='same')(encoded)
        x = UpSampling2D((2, 2))(x)
        x = Conv2D(CHANNEL_1, (3, 3),activation='relu', padding='same')(x)
        x = UpSampling2D((2, 2))(x)
        decoded = Conv2D(CHANNEL_OUTPUT, (3, 3), activation='sigmoid', padding='same')(x)
    
        # build autoencoder, encoder, decoder
        autoencoder = Model(inputs=input_image, outputs=decoded)
        encoder = Model(inputs=input_image, outputs=encoded)
    
        # compile autoencoder
        autoencoder.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    
        # training
        # need return history, otherwise can not use history["acc"]
        history_record = autoencoder.fit(x_train, x_train, epochs=EPOCHS, batch_size=BATCH_SIZE, shuffle=True, )
    
        return encoder, autoencoder, history_record
    

    注意:

    i)在Keras编码中,反卷积的实现代码便是卷积操作,具体解释详见上述博客。
    ii) UpSampling2D()实现的是反平均卷积的操作。

    autoencoder.summary()如下:

    代码架构图如下:

    (4)结果展示:
    (i)autoencoder还原之后的图片和原图片对比如下:

    上图根据原图片和生成图片的对比,第一行表示原图片,第二行表示卷积自编码器decoder还原之后的结果,上图可以看出,效果还是不错的。

    (ii)loss变化图:

    由上图可以看出,虽然loss在不断降低,但是accuracy还不是非常高,一方面是和参数相关,因为性能原因,在此文章版本上对epochs设置为20,另外,网络的深度也不够,也没有加入一些其他的提高性能的小技巧。



    其他参考文章:
    [1] Kandeng. 自编码算法与稀疏性[EB/OL]. (2018/11/24)[ 2018/11/24] http://ufldl.stanford.edu/wiki/index.php/自编码算法与稀疏性
    [2] Goodfellow I, Bengio Y, Courville A, et al. Deep learning[M]. Cambridge: MIT press, 2016.
    [3] 山下隆义. 图解深度学习[M]. 人民邮电出版社,2018:68-78
    [4] Francois Chollet. Building Autoencoders in Keras[EB/OL]. (2018/11/24)[ 2018/11/25] https://blog.keras.io/building-autoencoders-in-keras.html

    展开全文
  • 文章目录一、自编码器(Autoencoder, AE)自编码器的结构和思想结构思想自编码器的作用与类型作用类型二、Tensorflower代码实现普通自编码器多层自编码器卷积自编码器稀疏自编码器 一、自编码器(Autoencoder, AE) ...

    一、自编码器(Autoencoder, AE)

    自编码器的结构和思想

    结构

    • 自编码器是一种无监督的数据维度压缩数据特征表达方法。
    • 自编码器是神经网络的一种,经过训练后能尝试将输入复制到输出。自编码器由编码器和解码器组成,如下图所示:
    • 自编码器指的是试图让输出和输入一样的神经网络。
    • 他们通过将输入压缩成一个隐藏空间表示来进行工作,然后通过这种表示重构输出。
      1. 编码器:自编码器的前半部分,功能在于把输入变成一个隐藏的空间表示。 它可以用一个编码函数 h = f ( x ) h = f(x) h=f(x)表示。
      2. 解码器:这部分旨在从隐藏空间的表示重构输入。 它可以用解码函数 r = g ( h ) r = g(h) r=g(h)表示。

    思想

    • 如果AE的唯一目的是将输入复制到输出中,那么它们将毫无用处。
    • 实际上,我们希望通过训练AE将输入复制到输出中,隐藏表示h将具有有用的属性
    • 从自编码器获得有用特征的一种方法是将h限制为小于x的维度,在这种情况下,自编码器是不完整的。通过训练不完整的表示,我们强制自编码器学习训练数据的最显著特征。
    • 如果自编码器的容量过大,自编码器可以出色地完成赋值任务而没有从数据的分布抽取到任何有用的信息。如果隐藏表示的维度与输入相同,或者隐藏表示维度大于输入维度的情况下,也会发生这种情况。
    • 在这些情况下,即使线性编码器和线性解码器也可以将输入复制到输出,而无需了解有关数据分配的任何有用信息。
    • 理想情况下,自编码器可以成功地训练任何体系结构,根据要分配的复杂度来选择编码器和解码器的代码维数和容量。

    自编码器的作用与类型

    作用

    • 数据去噪
    • 数据降维
    • 通过适当的维度和稀疏性约束,自编码器可以学习比PCA或其他基本技术更有趣的数据投影。

    类型

    1.普通自编码器
    2.多层自编码器
    3.卷积自编码器
    4.稀疏自编码器

    二、Tensorflower代码实现

    普通自编码器

    • 普通自编码器是三层网络,即具有一个隐藏层的神经网络。
    • 输入和输出是相同的。
    • 激活函数可以选择sigmoid或者relu
    from keras.layers import Dense, Input, Activation
    input_size = 256
    hidden_size = 32
    output_size = 256
    x = Input(shape=(input_size,))
    
    # Encoder
    h = Dense(hidden_size, activation='sigmoid')(x)  
    
    # Decoder
    r = Dense(output_size, activation='sigmoid')(h)
    
    autoencoder = Model(input=x, output=r)
    autoencoder.compile(optimizer='adam', loss='mse')
    autoencoder.fit(input_data, input_data, batch_size=128, epochs=10000, verbose=2)
    

    多层自编码器

    • 如果一个隐藏层不够用,可以将自编码器扩展到更多的隐藏层。
    • 我们的实现使用3个隐藏层,而不是一个。
    • 任何隐藏层都可以作为特征表示,但将使网络结构对称并使用最中间的隐藏层。
    from keras.layers import Dense, Input, Activation
    input_size = 256
    hidden_size = 32
    output_size = 256
    x = Input(shape=(input_size,))
    
    # Encoder
    hidden_1 = Dense(hidden_size, activation='sigmoid')(x)
    h = Dense(code_size, activation='sigmoid')(hidden_1)
    
    # Decoder
    hidden_2 = Dense(hidden_size, activation='relu')(h)
    r = Dense(input_size, activation='sigmoid')(hidden_2)
    
    autoencoder = Model(input=x, output=r)
    autoencoder.compile(optimizer='adam', loss='mse')
    autoencoder.fit(input_data, input_data, batch_size=128, epochs=10000, verbose=2)
    

    卷积自编码器

    • 使用图像(3D矢量)而不是平坦的1维矢量。
    • 对输入图像进行下采样以提供较小尺寸的隐藏表示并强制自编码器学习图像的压缩版本。
    x = Input(shape=(28, 28,1)) 
    
    # Encoder
    conv1_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(x)
    pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)
    conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1)
    pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2)
    conv1_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool2)
    h = MaxPooling2D((2, 2), padding='same')(conv1_3)
    
    
    # Decoder
    conv2_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(h)
    up1 = UpSampling2D((2, 2))(conv2_1)
    conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1)
    up2 = UpSampling2D((2, 2))(conv2_2)
    conv2_3 = Conv2D(16, (3, 3), activation='relu')(up2)
    up3 = UpSampling2D((2, 2))(conv2_3)
    r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)
    
    autoencoder = Model(input=x, output=r)
    autoencoder.compile(optimizer='adam', loss='mse')
    

    稀疏自编码器

    • 稀疏自编码器通常用于学习分类等其他任务的特征。
    • 稀疏自编码器必须响应数据集独特统计特征,而不仅仅是作为标识函数。 通过这种方式,用稀疏性惩罚来执行复制任务的训练可以产生有用的特征模型。
    • 我们可以限制自编码器重构的另一种方式是对损失函数施加约束
    • 例如,我们可以在损失函数中添加一个修正术语。 这样做会使我们的自编码器学习数据的稀疏表示,,在正则项中,我们添加了一个L1激活函数正则器,它将在优化阶段对损失函数应用一个惩罚。 在结果上,与正常普通自编码器相比,该表示现在更稀松。
    from keras.layers import Dense, Input, Activation
    input_size = 256
    hidden_size = 32
    output_size = 256
    x = Input(shape=(input_size,))
    
    # Encoder
    h = Dense(hidden_size, activation='sigmoid', activity_regularizer=regularizers.l1(10e-6))(x)
    
    # Decoder
    r = Dense(output_size, activation='sigmoid')(h)
    
    autoencoder = Model(input=x, output=r)
    autoencoder.compile(optimizer='adam', loss='mse')
    autoencoder.fit(input_data, input_data, batch_size=128, epochs=10000, verbose=2)
    
    展开全文
  • start = time() from keras.models import Sequential from keras.layers import Dense, Dropout,Input from keras.layers import Embedding from keras.layers import Conv1D, GlobalAverage...keras各种自编码代码
    start = time()
    
    from keras.models import Sequential
    from keras.layers import Dense, Dropout,Input
    from keras.layers import Embedding
    from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D
    from keras import layers
    from keras.models import Model
    
    
    # Parameters for denoising autoencoder
    nb_visible = 120
    nb_hidden = 64
    batch_size = 16
    # Build autoencoder model
    input_img = Input(shape=(nb_visible,))
    
    encoded = Dense(nb_hidden, activation='relu')(input_img)
    decoded = Dense(nb_visible, activation='sigmoid')(encoded)
    
    autoencoder = Model(input=input_img, output=decoded)
    autoencoder.compile(loss='mean_squared_error',optimizer='adam',metrics=['mae'])
    autoencoder.summary()
    
    # Train
    ### 加一个early_stooping
    import keras 
    
    early_stopping = keras.callbacks.EarlyStopping(
        monitor='val_loss',
        min_delta=0.0001,
        patience=5, 
        verbose=0, 
        mode='auto'
    )
    autoencoder.fit(X_train_np, y_train_np, nb_epoch=50, batch_size=batch_size , shuffle=True,
                    callbacks = [early_stopping],verbose = 1,validation_data=(X_test_np, y_test_np))
    # Evaluate
    evaluation = autoencoder.evaluate(X_test_np, y_test_np, batch_size=batch_size , verbose=1)
    print('val_loss: %.6f, val_mean_absolute_error: %.6f' % (evaluation[0], evaluation[1]))
    
    end = time()
    print('耗时:'+str((end-start)/60))
    

    keras各种自编码代码


    展开全文
  • tensorflow实现自编码器,带有详细注释,使用MNIST作为数据集,安装好python及tensorflow即可运行
  • 自编码器实现与应用

    千次阅读 2020-08-14 12:48:53
    自编码器实现与应用自编码器实现与应用自编码器实现与应用

    自 编 码 器 的 实 现 与 应 用 自编码器的实现与应用

    1.视频教程:
    B站、网易云课堂、腾讯课堂
    2.代码地址:
    Gitee
    Github
    3.存储地址:
    Google云
    百度云:
    提取码:

    1.自编码器的定义与原理


    • 自编码器是指使用自身的高阶特征编码自己。
    • 自编码器是一种神经网络, 它的输入和输出是一致的, 目标是使用稀疏的高阶特征重新组合来重构自己。

    • 自动编码器是一种数据的压缩算法,其中数据 的压缩和解压缩函数是数据相关的、有损的、从样本中自动学习的。
    • 在大部分提到自动编码器的场合,压缩和解压缩的函数是通过神经网络实现的。

    在这里插入图片描述


    • 1)自动编码器是数据相关的,这意味着自动编 码器只能压缩那些与训练数据类似的数据。
    • 2)自动编码器是有损的,与无损压缩算法不同。
    • 3)自动编码器是从数据样本中自动学习的

    自编码器的设计

    1)搭建编码器。
    2)搭建解码器。
    3)设定损失函数。(输入和输出图像构成编码器)

    在这里插入图片描述


    自编码器的应用
    1)数据去噪。
    2)降维。
    3)图像生成。


    上面的自编码器对输入是有要求的,是否可以输入随机的噪声来产生图片的呢?

    在这里插入图片描述

    所以有了VAE(变分自编码器,GAN网络之前最常用的图像生成编码器)

    • 变分编码器可以随机生成隐含变量
    • 提高网络的泛化能力,比普通的自动编码器要好
    • 缺点就是生成的图片会有点模糊

    VAE的的提出主要就是在code中加入某种分布,在计算损失函数时不仅考虑了输入输出图像的差异度,也考虑了是否满足分布的损失,进而有了泛化性,可以接受噪音图片

    2.基本自编码器

    import tensorflow as tf
    import matplotlib.pyplot as plt
    
    tf.__version__
    

    在这里插入图片描述

    (x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()
    

    自编码器的数据相似性,我们用来测试的数据仍然是 手写数字

    x_train.shape, x_test.shape
    

    在这里插入图片描述

    x_train = x_train.reshape(x_train.shape[0], -1)
    x_test = x_test.reshape(x_test.shape[0], -1)
    
    x_train.shape, x_test.shape
    

    在这里插入图片描述

    x_train = tf.cast(x_train, tf.float32)/255
    x_test = tf.cast(x_test, tf.float32)/255
    
    input_size = 784
    hidden_size = 32
    output_size = 784
    
    input = tf.keras.layers.Input(shape=(input_size,))
    
    # Encoder
    en = tf.keras.layers.Dense(hidden_size, activation='relu')(input)
    
    # Decoder
    de = tf.keras.layers.Dense(output_size, activation='sigmoid')(en)
    
    model = tf.keras.Model(inputs=input, outputs=de)
    
    model.compile(optimizer='adam', loss='mse')
    
    model.fit(x_train, x_train,
                    nb_epoch=50,
                    batch_size=256,
                    shuffle=True,
                    validation_data=(x_test, x_test))
    

    在这里插入图片描述

    encode = tf.keras.Model(inputs=input, outputs=en)
    
    input_de = tf.keras.layers.Input(shape=(hidden_size,))
    output = model.layers[-1](input_de)
    decode = tf.keras.Model(inputs=input_de, outputs=output)
    
    encode_test = encode(x_test)
    
    decode_test = decode.predict(encode_test)
    
    x_test = x_test.numpy()
    
    n = 10  
    
    plt.figure(figsize=(20, 4))
    for i in range(1, n):    
    # 展示原始图像
        ax = plt.subplot(2, n, i)
        plt.imshow(x_test[i].reshape(28, 28))  
        # 展示自编码器重构后的图像
        ax = plt.subplot(2, n, i + n)
        plt.imshow(decode_test[i].reshape(28, 28))
    plt.show()
    

    在这里插入图片描述

    3.基本去噪自编码器

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import numpy as np
    
    tf.__version__
    
    (x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()
    

    自编码器的数据相似性,我们用来测试的数据仍然是 手写数字

    x_train.shape, x_test.shape
    

    在这里插入图片描述

    x_train = x_train.reshape(x_train.shape[0], -1)
    x_test = x_test.reshape(x_test.shape[0], -1)
    
    x_train.shape, x_test.shape
    

    在这里插入图片描述

    x_train = tf.cast(x_train, tf.float32)/255
    x_test = tf.cast(x_test, tf.float32)/255
    
    noise_factor = 0.5
    x_train_noisy = x_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape) 
    x_test_noisy = x_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape) 
    
    x_train_noisy = np.clip(x_train_noisy, 0., 1.)
    x_test_noisy = np.clip(x_test_noisy, 0., 1.)
    
    n = 10
    
    plt.figure(figsize=(10, 2))
    for i in range(1, n):    
    # 展示原始图像
        ax = plt.subplot(1, n, i)
        plt.imshow(x_train_noisy[i].reshape(28, 28))
    plt.show()
    

    在这里插入图片描述

    input_size = 784
    hidden_size = 32
    output_size = 784
    
    input = tf.keras.layers.Input(shape=(input_size,))
    
    # Encoder
    en = tf.keras.layers.Dense(hidden_size, activation='relu')(input)
    
    # Decoder
    de = tf.keras.layers.Dense(output_size, activation='sigmoid')(en)
    
    model = tf.keras.Model(inputs=input, outputs=de)
    
    model.compile(optimizer='adam', loss='mse')
    
    model.fit(x_train_noisy, x_train,
                    nb_epoch=50,
                    batch_size=256,
                    shuffle=True,
                    validation_data=(x_test_noisy, x_test))
    

    在这里插入图片描述

    encode = tf.keras.Model(inputs=input, outputs=en)
    
    input_de = tf.keras.layers.Input(shape=(hidden_size,))
    output = model.layers[-1](input_de)
    decode = tf.keras.Model(inputs=input_de, outputs=output)
    
    encode_test = encode(x_test_noisy)
    
    decode_test = decode.predict(encode_test)
    
    plt.figure(figsize=(20, 4))
    for i in range(1, n):    
    # 展示原始图像
        ax = plt.subplot(2, n, i)
        plt.imshow(x_test_noisy[i].reshape(28, 28))  
        # 展示自编码器重构后的图像
        ax = plt.subplot(2, n, i + n)
        plt.imshow(decode_test[i].reshape(28, 28))
    plt.show()
    

    在这里插入图片描述

    主要是通过设置label为去噪前的图片,达到去噪效果

    4.上采样和反卷积

    上采样:

    • 由于在卷积过程中,我们的特征图像变得很小(比如长宽变为原图像的1/32), 为了得到原图像大小的稠密像素预测, 我们需要进行上采样。

    容易想到三种方式,分别对应最大池化、平均池化和卷积操作的反过来使用。

    1.插值法
    2.反池化
    3.反卷积(转置卷积):通过训练来放大图像


    5.卷积去噪自编码器

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import numpy as np
    
    tf.__version__
    

    在这里插入图片描述

    (x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()
    

    自编码器的数据相似性,我们用来测试的数据仍然是 手写数字

    x_train.shape, x_test.shape
    
    x_train = np.expand_dims(x_train, -1)
    x_test = np.expand_dims(x_test, -1)
    
    x_train.shape, x_test.shape
    

    在这里插入图片描述

    x_train = tf.cast(x_train, tf.float32)/255
    x_test = tf.cast(x_test, tf.float32)/255
    
    noise_factor = 0.5
    x_train_noisy = x_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape) 
    x_test_noisy = x_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape) 
    
    x_train_noisy = np.clip(x_train_noisy, 0., 1.)
    x_test_noisy = np.clip(x_test_noisy, 0., 1.)
    
    n = 10
    
    plt.figure(figsize=(10, 2))
    for i in range(1, n):    
    # 展示原始图像
        ax = plt.subplot(1, n, i)
        plt.imshow(x_train_noisy[i].reshape(28, 28))
    plt.show()
    

    在这里插入图片描述

    input = tf.keras.layers.Input(shape=(28, 28, 1))
    
    # Encoder
    x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same')(input)
    x = tf.keras.layers.MaxPool2D((2, 2), padding='same')(x)   # 14*14*16
    
    x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
    x = tf.keras.layers.MaxPool2D((2, 2), padding='same')(x)   # 7*7*32
    
    
    # Decoder
    x = tf.keras.layers.Conv2DTranspose(16, (3, 3), strides=2,
                               activation='relu', padding='same')(x)   # 14*14*16
    output = tf.keras.layers.Conv2DTranspose(1, (3, 3), strides=2,
                               activation='sigmoid', padding='same')(x)   # 28*28*1
    
    model = tf.keras.Model(inputs=input, outputs=output)
    
    model.compile(optimizer='adam', loss='mse')
    
    model.fit(x_train_noisy, x_train,
                    nb_epoch=50,
                    batch_size=256,
                    validation_data=(x_test_noisy, x_test))
    

    在这里插入图片描述

    pre_test = model.predict(x_test_noisy)
    
    plt.figure(figsize=(20, 4))
    for i in range(1, n):    
    # 展示原始图像
        ax = plt.subplot(2, n, i)
        plt.imshow(x_test_noisy[i].reshape(28, 28))  
        # 展示自编码器重构后的图像
        ax = plt.subplot(2, n, i + n)
        plt.imshow(pre_test[i].reshape(28, 28))
    plt.show()
    

    在这里插入图片描述

    model.layers
    

    在这里插入图片描述


    6.基本自编码器的代码实现

    7.去噪自编码器

    8.卷积去噪自编码器

    展开全文
  • 本文内容参考了Conditional VAE (Variational Auto Encoder) 条件付きVAE 是对官方网页Train Variational Autoencoder (VAE) to Generate Images的改进,该网页的翻译可见MATLAB实现自编码器(四)——变分自编码器...
  • % 绿色圆圈代表新建数据 title('新旧数据对比') 运行结果 构建前后数据的对比 Reconstruct Handwritten Digit Images Using Sparse Autoencoder使用稀疏自编码器重建手写数字图像 以下代码实现了稀疏自编码器对...
  • generate.py; model.py; train.py; read.py四个代码文件,实现vae。
  • 使用TensorFlow实现自编码器,这里实现的是最有代表性的去噪自编码器,因为去噪自编码器的适用范围最广泛也最通用。代码简单,并且有标注,通俗易懂,适合初学者参考。
  • 自编码器python实现

    千次阅读 2019-04-15 11:53:51
    自编码器 自编码器是一种非常通用的神经网络工具。主要思想是通过一个编码器,将原始信息编码为一组向量,然后通过一个解码器,将向量解码为原始数据。通过衡量输入与输出的差别,来对网络参数进行训练。主要可以...
  •   在非监督学习中,最典型的一类神经网络莫过于autoencoder(自编码器),它的目的是基于输入的unlabeled数据X={x(1),x(2),x(3),...}X={x(1),x(2),x(3),...}X=\{x^{(1)}, x^{(2)}, x^{(3)}, ...\},通过训练得到数据...
  • TensorFlow实现自编码器

    千次阅读 热门讨论 2017-07-27 19:48:23
    TensorFlow实现自编码器,具体一点是实现去噪自编码器。自编码器属于非监督学习的方法。自编码器作为深度学习在无监督领域的尝试是非常成功的,使用TensorFlow实现自编码器,能认识到其作用和领悟当中的原理。
  • 深度自编码器python实现

    千次阅读 2017-08-22 15:28:29
    深度自编码器的原理上一节已经讲过,这次我们来看一下它的python代码实现,这是基于mnist的编码实现。 from __future__ import division, print_function, absolute_import import tensorflow as tf import ...
  • tensorflow实现自编码器

    千次阅读 2017-03-08 22:11:48
    tensorflow实现自编码器
  • MATLAB给出了堆栈自编码器实现Train Stacked Autoencoders for Image Classification ,本文对其进行分析 堆栈自编码器Stacked Autoencoders 堆栈自编码器是 具有多个隐藏层的神经网络可用于解决图像等复杂数据的...
  • Convolutional Auto-Encoders卷积自编码器的Matlab代码,可以运行caeexamples.m对手写数据mnist_uint8进行训练测试
  • Recap自编码器自编码器中,需要输入一个原始图片,原始图片经过编码之后得到一个隐向量,隐向量解码产生原图片对应的图片。在这种情况下,只能生成原图片对应的图片而无法任意生成新的图片,因为隐向量都是原始...
  • 自动编码器重建图像及Python实现

    千次阅读 2019-03-14 18:54:32
    随着深度学习的出现,AE可以通过网络层堆叠形成深度自动编码器实现数据降维。通过编码过程减少隐藏层中的单元数量,可以以分层的方式实现降维,在更深的隐藏层中获得更高级的特征,从而在解码过程中更好的重建数据...
  • Keras实现各类自编码器

    千次阅读 2016-12-16 18:31:59
    Keras实现各类自编码器及遇到的问题小结
  • 自编码器、变分自编码器(VAE)简介以及Python实现

    千次阅读 多人点赞 2019-06-25 14:50:00
    本篇博客简单介绍了自编码器(AutoEncoder, AE)以及近几年比较火的变分自编码器(Variational AutoEncoder, VAE),并用Python实现自编码器(AE) 自编码器是一种无监督学习模型,可用于数据降维,数据可视化,深度...
  • 稀疏自编码器及其实现——如何搞基

    万次阅读 多人点赞 2014-08-09 10:57:30
    自编码器是什么? 自编码器本身就是一种BP神经网络。它是一种无监督学习算法。 我们都知道神经网络可以从任意精度逼近任意函数,这里我们让神经网络目标值等于输出值x,也就是模拟一个恒等函数: 太无聊了,...
  • 本资源是3层的自编码器加上稀疏正则项约束的matlab代码。隐层激活函数选sigmoid函数,输出层选线性函数,程序中以一个标准数据集sonar为例,使用该方法可以做无监督表征学习,数据压缩,多任务学习等
  • 自编码器(AutoEncoder)入门及TensorFlow实现

    万次阅读 多人点赞 2018-03-03 23:01:19
    自编码器(Autoencoder,AE),是一种利用反向传播算法使得输出值等于输入值的神经网络,它先将输入压缩成潜在空间表征,然后通过这种表征来重构输出。自编码器由两部分组成:编码器(encoder):这部分能将输入压缩成...
  • 自编码器的原理及实现

    万次阅读 2019-01-23 11:29:37
    自编码器的原理及实现 1. 什么是自编码器 自编码器就是将原始数据进行编码,进行降低维度,发现数据之间的规律的过程。 数据降维比如mnist的图片为28*28像素,将图片向量化之后的得到一个长度为784的向量。在网络...
  • Keras上实现AutoEncoder自编码器

    万次阅读 多人点赞 2017-03-31 19:06:59
    一、自编码器简介 无监督特征学习(Unsupervised Feature Learning)是一种仿人脑的对特征逐层抽象提取的过程,学习过程中有两点:一是无监督学习,即对训练数据不需要进行标签化标注,这种学习是对数据内容的组织...
  • 自动编码器模型和代码解释

    万次阅读 2016-12-07 05:43:12
    在自动编码器的基础上,对训练数据加入噪声,自动编码器必须学习去去除这种噪声而获得真正的没有被噪声污染过的输入。因此,这就迫使编码器去学习输入信号的更加鲁棒的表达,这也是它的泛化能力比一般编码器强的原因...
  • AB旋转编码器用于测量电机的正反转,以及对脉冲计数
  • 基于tensorflow的栈式自编码器实现

    万次阅读 热门讨论 2017-03-30 11:37:36
    这周完全没有想法要看栈式编码器的,谁知误入桃花源,就暂且把栈式自编码器看了吧。由于手上有很多数值型的数据,仅仅是数据,没有标签,所以,迫切需要通过聚类抽出特征。无意间看到别人家公司的推荐系统里面用到...
  • 自动编码器原理及实现(一)

    万次阅读 2017-02-07 11:41:05
    一下自动编码器的一些概念及原理,在最后,附上python实现代码。 自动编码器是神经网络的一种,经过训练后能尝试将输入复制到输出,换句话说,就是使输出的内容和输入的 内容一样。自动编码器内部有一个隐含层h,...
  • 6-2 稀疏自动编码器--Keras实现

    千次阅读 2018-07-16 09:44:56
    自编码器(AutoEncoder),即可以使用自身的高阶特征自我编码,自编码器其实也是一种神经网络,其输入和输出是一致的,借助了稀疏编码的思想,目标是使用稀疏的高阶特征重新组合来重构自己。 如果我们对隐层单元施....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 504,540
精华内容 201,816
关键字:

自编码器代码实现