前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自动编码器

自动编码器

作者头像
Lansonli
发布2021-10-09 15:27:26
7580
发布2021-10-09 15:27:26
举报
文章被收录于专栏:Lansonli技术博客Lansonli技术博客

学习目标

  • 目标
    • 了解自动编码器作用
    • 说明自动编码器的结构
  • 应用
    • 使用自动编码器对Mnist手写数字进行数据降噪处理

5.2.1 自动编码器什么用

自编码器的应用主要有两个方面

  • 数据去噪
  • 进行可视化而降维
    • 自编码器可以学习到比PCA等技术更好的数据投影

5.2.1 什么是自动编码器(Autoencoder)

5.2.1.1 定义

自动编码器是一种数据的压缩算法,一种使用神经网络学习数据值编码的无监督方式。

5.2.1.2 原理作用案例

搭建一个自动编码器需要完成下面三样工作:

  • 搭建编码器
  • 搭建解码器
  • 设定一个损失函数,用以衡量由于压缩而损失掉的信息。
    • 编码器和解码器一般都是参数化的方程,并关于损失函数可导,通常情况是使用神经网络。

5.2.1.3 类别

  • 普通自编码器
    • 编解码网络使用全连接层
  • 多层自编码器
  • 卷积自编码器
    • 编解码器使用卷积结构
  • 正则化自编码器
    • 降噪自编码器

5.2.2 Keras快速搭建普通自编码器-基于Mnist手写数字

5.2.2.1 自编码器效果

  • 迭代50次效果
代码语言:javascript
复制
Train on 60000 samples, validate on 10000 samples
Epoch 1/50
  256/60000 [..............................] - ETA: 44s - loss: 0.6957
 1280/60000 [..............................] - ETA: 11s - loss: 0.6867
 2560/60000 [>.............................] - ETA: 6s - loss: 0.6699 
 3584/60000 [>.............................] - ETA: 5s - loss: 0.6493
...
...
...
55808/60000 [==========================>...] - ETA: 0s - loss: 0.0925
57088/60000 [===========================>..] - ETA: 0s - loss: 0.0925
58112/60000 [============================>.] - ETA: 0s - loss: 0.0925
59392/60000 [============================>.] - ETA: 0s - loss: 0.0925
60000/60000 [==============================] - 3s 47us/step - loss: 0.0925 - val_loss: 0.0914

5.2.2.2 流程

  • 初始化自编码器结构
  • 训练自编码器
    • 获取数据
    • 模型输入输出训练
  • 显示自编码前后效果对比

5.2.2.3 代码编写

导入所需包

代码语言:javascript
复制
from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
  • 1、初始化自编码器结构

定义编码器:输出32个神经元,使用relu激活函数,(32这个值可以自己制定)

定义解码器:输出784个神经元,使用sigmoid函数,(784这个值是输出与原图片大小一致)

损失:

  • 每个像素值的交叉熵损失(输出为sigmoid值(0,1),输入图片要进行归一化(0,1))
代码语言:javascript
复制
class AutoEncoder(object):
    """自动编码器
    """
    def __init__(self):

        self.encoding_dim = 32
        self.decoding_dim = 784

        self.model = self.auto_encoder_model()

    def auto_encoder_model(self):
        """
        初始化自动编码器模型
        将编码器和解码器放在一起作为一个模型
        :return: auto_encoder
        """
        input_img = Input(shape=(784,))

        encoder = Dense(self.encoding_dim, activation='relu')(input_img)

        decoder = Dense(self.decoding_dim, activation='sigmoid')(encoder)

        auto_encoder = Model(inputs=input_img, outputs=decoder)

        auto_encoder.compile(optimizer='adam', loss='binary_crossentropy')

        return auto_encoder
  • 2、训练流程
    • 读取Mnist数据,并进行归一化处理以及形状修改
    • 模型进行fit训练
      • 指定迭代次数
      • 指定每批次数据大小
      • 是否打乱数据
      • 验证集合
代码语言:javascript
复制
def train(self):
    """
    训练自编码器
    :param model: 编码器结构
    :return:
    """
    (x_train, _), (x_test, _) = mnist.load_data()

    # 进行归一化
    x_train = x_train.astype('float32') / 255.
    x_test = x_test.astype('float32') / 255.

    # 进行形状改变
    x_train = np.reshape(x_train, (len(x_train), np.prod(x_train.shape[1:])))
    x_test = np.reshape(x_test, (len(x_test), np.prod(x_test.shape[1:])))

    print(x_train.shape)
    print(x_test.shape)

    # 训练
    self.model.fit(x_train, x_train,
                   epochs=5,
                   batch_size=256,
                   shuffle=True,
                   validation_data=(x_test, x_test))
  • 3、显示模型生成的图片与原始图片对比
    • 导入matplotlib包
代码语言:javascript
复制
    def display(self):
        """
        显示前后效果对比
        :return:
        """
        (x_train, _), (x_test, _) = mnist.load_data()

        x_test = np.reshape(x_test, (len(x_test), np.prod(x_test.shape[1:])))

        decoded_imgs = self.model.predict(x_test)

        plt.figure(figsize=(20, 4))
        # 显示5张结果
        n = 5
        for i in range(n):
            # 显示编码前结果
            ax = plt.subplot(2, n, i + 1)
            plt.imshow(x_test[i].reshape(28, 28))
            plt.gray()
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)

            # 显示编解码后结果
            ax = plt.subplot(2, n, i + n + 1)
            plt.imshow(decoded_imgs[i].reshape(28, 28))
            plt.gray()
            ax.get_xaxis().set_visible(False)
            ax.get_yaxis().set_visible(False)
        plt.show()

5.2.3 基于Mnist手写数字-深度自编码器

  • 将多个自编码进行重叠
代码语言:javascript
复制
input_img = Input(shape=(784,))
encoded = Dense(128, activation='relu')(input_img)
encoded = Dense(64, activation='relu')(encoded)
encoded = Dense(32, activation='relu')(encoded)

decoded = Dense(64, activation='relu')(encoded)
decoded = Dense(128, activation='relu')(decoded)
decoded = Dense(784, activation='sigmoid')(decoded)

auto_encoder = Model(input=input_img, output=decoded)
auto_encoder.compile(optimizer='adam', loss='binary_crossentropy')

我们可以替换原来的编码器进行测试

代码语言:javascript
复制
59392/60000 [============================>.] - ETA: 0s - loss: 0.0860

最后的损失会较之前同样的epoch迭代好一些

5.2.4 基于Mnist手写数字-卷积自编码器

  • 卷积编解码结构设计
    • 编码器
      • Conv2D(32, (3, 3), activation='relu', padding='same')
      • MaxPooling2D((2, 2), padding='same')
      • Conv2D(32, (3, 3), activation='relu', padding='same')
      • MaxPooling2D((2, 2), padding='same')
      • 输出大小为:Tensor("max_pooling2d_2/MaxPool:0", shape=(?, 7, 7, 32), dtype=float32)
    • 解码器:反卷积过程
      • Conv2D(32, (3, 3), activation='relu', padding='same')
      • UpSampling2D((2, 2))
      • Conv2D(32, (3, 3), activation='relu', padding='same')
      • UpSampling2D((2, 2))
      • Conv2D(1, (3, 3), activation='sigmoid', padding='same')
      • 输出大小:Tensor("conv2d_5/Sigmoid:0", shape=(?, 28, 28, 1), dtype=float32)
代码语言:javascript
复制
input_img = Input(shape=(28, 28, 1))

x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)
print(encoded)

x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
print(decoded)

auto_encoder = Model(input_img, decoded)
auto_encoder.compile(optimizer='adam', loss='binary_crossentropy')

由于修改了模型的输入输出数据形状,所以在训练的地方同样也需要修改(显示的时候数据输入也要修改)

代码语言:javascript
复制
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))

5.2.4 基于Mnist手写数字-降噪自编码器

  • 降噪自编码器效果
  • 过程
    • 对原始数据添加噪音
    • 随机加上正态分布的噪音
    • x_train + np.random.normal(loc=0.0, scale=1.0, size=x_train.shape)
代码语言:javascript
复制
# 添加噪音
x_train_noisy = x_train + np.random.normal(loc=0.0, scale=3.0, size=x_train.shape)
x_test_noisy = x_test + np.random.normal(loc=0.0, scale=3.0, size=x_test.shape)

# 重新进行限制每个像素值的大小在0~1之间
x_train_noisy = np.clip(x_train_noisy, 0., 1.)
x_test_noisy = np.clip(x_test_noisy, 0., 1.)

在进行显示的时候也要进行修改

代码语言:javascript
复制
# 获取数据改变形状,增加噪点数据
(x_train, _), (x_test, _) = mnist.load_data()
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))
x_test_noisy = x_test + np.random.normal(loc=3.0, scale=10.0, size=x_test.shape)

# 预测结果
decoded_imgs = self.model.predict(x_test_noisy)

# 修改需要显示的图片变量
plt.imshow(x_test_noisy[i].reshape(28, 28))

5.2.5 总结

  • 掌握自动编码器的结构
  • 掌握正则化自动编码器结构作用
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 学习目标
    • 5.2.1 自动编码器什么用
      • 5.2.1 什么是自动编码器(Autoencoder)
        • 5.2.2 Keras快速搭建普通自编码器-基于Mnist手写数字
          • 5.2.3 基于Mnist手写数字-深度自编码器
            • 5.2.4 基于Mnist手写数字-卷积自编码器
              • 5.2.4 基于Mnist手写数字-降噪自编码器
                • 5.2.5 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档