自动编码器(Autoencoder)是一类无监督学习的特征提取方法,它由编码器(Encoder)和解码器(Decoder)两个部分组成。其工作的原理是,首先通过编码器将初始的特征映射到一个潜在的特征空间(通常该空间的维度远小于原始空间),再使用解码器将其重新映射到原始的特征空间当中。编码器和解码器通常使用神经网络结构来实现,在训练模型参数时会定义某种距离函数,来衡量输出数据与预期目标的误差。它主要的应用有数据压缩、数据去噪以及数据生成等等,这里给出一些示例代码以方便学习。

数据压缩

# 引用相关的函数库
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tffrom tensorflow.keras import layers, losses
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.models import Model# 载入fashion_mnist数据集
(x_train, _), (x_test, _) = fashion_mnist.load_data()# 将数据归一化至[0, 1]区间
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.# 定义一个自动编码器模型以实现数据压缩
# 该模型将数据由784维空间降至64维空间
latent_dim = 64
class Autoencoder(Model):def __init__(self, latent_dim):super(Autoencoder, self).__init__()self.latent_dim = latent_dim   self.encoder = tf.keras.Sequential([layers.Flatten(),layers.Dense(latent_dim, activation='relu'),])self.decoder = tf.keras.Sequential([layers.Dense(784, activation='sigmoid'),layers.Reshape((28, 28))])def call(self, x):encoded = self.encoder(x)decoded = self.decoder(encoded)return decodedautoencoder = Autoencoder(latent_dim)
autoencoder.compile(optimizer='adam', loss=losses.MeanSquaredError())# 训练自动编码器模型
autoencoder.fit(x_train, x_train,epochs=10,shuffle=True,validation_data=(x_test, x_test))# 测试自动编码器模型
encoded_imgs = autoencoder.encoder(x_test).numpy()
decoded_imgs = autoencoder.decoder(encoded_imgs).numpy()# 可视化测试图像及其重建的图像
n = 10
plt.figure(figsize=(10, 4))
for i in range(n):ax = plt.subplot(2, n, i + 1)plt.imshow(x_test[i])plt.gray()ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)ax = plt.subplot(2, n, i + 1 + n)plt.imshow(decoded_imgs[i])plt.gray()ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)
plt.show()

数据去噪

# 引用相关的函数库
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tffrom tensorflow.keras import layers, losses
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Model# 载入cifar10数据集
(x_train, _), (x_test, _) = cifar10.load_data()# 将数据归一化至[0, 1]区间
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.# 生成加入随机高斯噪声的训练和测试样本
noise_factor = 0.2
x_train_noisy = x_train + noise_factor * tf.random.normal(shape=x_train.shape)
x_test_noisy = x_test + noise_factor * tf.random.normal(shape=x_test.shape)
x_train_noisy = tf.clip_by_value(x_train_noisy, clip_value_min=0., clip_value_max=1.)
x_test_noisy = tf.clip_by_value(x_test_noisy, clip_value_min=0., clip_value_max=1.)# 定义一个自动编码器模型以实现数据去噪
class Denoise(Model):def __init__(self):super(Denoise, self).__init__()self.encoder = tf.keras.Sequential([layers.Input(shape=(32, 32, 3)), layers.Conv2D(16, (3,3), activation='relu', padding='same', strides=2),layers.Conv2D(8, (3,3), activation='relu', padding='same', strides=2)])self.decoder = tf.keras.Sequential([layers.Conv2DTranspose(8, kernel_size=3, strides=2, activation='relu', padding='same'),layers.Conv2DTranspose(16, kernel_size=3, strides=2, activation='relu', padding='same'),layers.Conv2D(3, kernel_size=(3,3), activation='sigmoid', padding='same')])def call(self, x):encoded = self.encoder(x)decoded = self.decoder(encoded)return decodedautoencoder = Denoise()
autoencoder.compile(optimizer='adam', loss=losses.MeanSquaredError())# 训练自动编码器模型
autoencoder.fit(x_train_noisy, x_train,epochs=10,shuffle=True,validation_data=(x_test_noisy, x_test))
autoencoder.encoder.summary()
autoencoder.decoder.summary()# 测试自动编码器模型
encoded_imgs = autoencoder.encoder(x_test).numpy()
decoded_imgs = autoencoder.decoder(encoded_imgs).numpy()# 可视化测试图像及其重建的图像
n = 10
plt.figure(figsize=(10, 4))
for i in range(n):ax = plt.subplot(2, n, i + 1)plt.imshow(tf.squeeze(x_test_noisy[i]))plt.gray()ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)bx = plt.subplot(2, n, i + n + 1)plt.imshow(tf.squeeze(decoded_imgs[i]))plt.gray()bx.get_xaxis().set_visible(False)bx.get_yaxis().set_visible(False)
plt.show()

以上是使用自动编码器进行数据降维和去噪的例子,看上去效果是不错的。然而,由于这种模型对训练数据有着比较强的依赖性,很难成为通用的数据降维或去噪的方法,在实践当中这种模型并没有得到广泛的推广。近年来,随着机器学习其他领域研究的深入(例如GAN),人们又提出了一种变体的自动编码器(Variational Autoencoder),以应用于数据生成的应用场景中。相对于传统的编码器而言,它在潜在空间(Latent Space)中学习的是某种概率分布的参数(例如高斯分布的均值和标准差),而这种概率分布被认为是可以生成输入数据的。在另一个方面,解码器的构造是与传统方法类似的,在随机采样潜在空间的概率分布后,便可以利用其作为解码器的输入生成图像了。以下是一个在MNIST数据集上使用变体自动编码器生成图像的具体例子:

数据生成

# 引用相关的函数库
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfpfrom tensorflow.keras import layers, losses
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K# 载入mnist数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()# 将数据归一化至[0, 1]区间
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.# 将图像数据转换为向量
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))# 定义一个变体自动编码器模型以实现数据生成
original_dim = 28 * 28
intermediate_dim = 64
latent_dim = 2inputs = layers.Input(shape=(original_dim,))
h = layers.Dense(intermediate_dim, activation='relu')(inputs)
z_mean = layers.Dense(latent_dim)(h)
z_log_sigma = layers.Dense(latent_dim)(h)# 自定义取样层
def sampling(args):z_mean, z_log_sigma = argsepsilon = K.random_normal(shape=(K.shape(z_mean)[0], latent_dim), mean=0., stddev=0.1)return z_mean + K.exp(z_log_sigma) * epsilonz = layers.Lambda(sampling)([z_mean, z_log_sigma])# 定义编码器
encoder = Model(inputs, [z_mean, z_log_sigma, z], name='encoder')# 定义解码器
latent_inputs = layers.Input(shape=(latent_dim,), name='z_sampling')
x = layers.Dense(intermediate_dim, activation='relu')(latent_inputs)
outputs = layers.Dense(original_dim, activation='sigmoid')(x)
decoder = Model(latent_inputs, outputs, name='decoder')# 创建变体自动编码器
outputs = decoder(encoder(inputs)[2])
vae = Model(inputs, outputs, name='vae_mlp')# 定义误差函数
reconstruction_loss = losses.binary_crossentropy(inputs, outputs)
reconstruction_loss *= original_dim
kl_loss = 1 + z_log_sigma - tf.square(z_mean) - tf.exp(z_log_sigma)
kl_loss = tf.reduce_sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = tf.reduce_mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
vae.compile(optimizer='adam')# 训练自动编码器
vae.fit(x_train, x_train,epochs=100,batch_size=32,shuffle=True,validation_data=(x_test, x_test))# 采样概率分布函数并生产新图像
n = 20
digit_size = 28
figure = np.zeros((digit_size * n, digit_size * n))
norm = tfp.distributions.Normal(0, 1)
grid_x = norm.quantile(np.linspace(0.05, 0.95, n))
grid_y = norm.quantile(np.linspace(0.05, 0.95, n))for i, yi in enumerate(grid_x):for j, xi in enumerate(grid_y):z_sample = np.array([[xi, yi]])x_decoded = decoder.predict(z_sample)digit = x_decoded[0].reshape(digit_size, digit_size)figure[i * digit_size: (i + 1) * digit_size,j * digit_size: (j + 1) * digit_size] = digitplt.figure(figsize=(10, 10))
plt.imshow(figure)
plt.show()

使用自动编码器(Autoencoder)及其变体进行特征学习相关推荐

  1. 德尔塔克戎,新冠“双毒合一”变体首次证实

    金磊 发自 凹非寺 量子位 | 公众号 QbitAI 德尔塔 + 奥密克戎 = 德尔塔克戎(deltacron). 最近,来自法国的一项研究,通过基因组测序首次证实这种新冠"双毒合一&quo ...

  2. 自编码器的原始形式和各种变体

    本文参考维基百科 文章目录 最简单的原始形式:非循环前馈神经网络 欠完备自编码器 undercomplete autoencoders 过完备自编码器 overcomplete autoencoder ...

  3. boltzmann_推荐系统系列第7部分:用于协同过滤的Boltzmann机器的3个变体

    boltzmann RecSys系列 (RecSys Series) Update: This article is part of a series where I explore recommen ...

  4. 在注意力中重新思考Softmax:分解非线性,这个线性transformer变体实现多项SOTA

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源丨机器之心 编辑丨极市平台 导读 来自商汤.上海人工智能实验室等 ...

  5. Transformer模型有多少种变体?复旦邱锡鹏教授团队做了全面综述

    视学算法报道 转载自:机器之心 编辑:Liyuan.杜伟 自提出至今,Transformer 模型已经在自然语言处理.计算机视觉以及其他更多领域「大展拳脚」,学界也提出了各种各样基于原始模型的变体.但 ...

  6. bottleneck resnet网络_关于ResNet及其变体的总结(上)

    ResNet作为卷积神经网络的一个里程碑式的模型一直在各个领域被应用,因此学习这样一个模型架构很有必要.网上也有很多关于这个网络的介绍,也从中衍生了很多改进的模型(无论改动幅度大小).因此,有必要就R ...

  7. Transformer变体为何无法应用于多种任务?谷歌:这些架构更改不能有效迁移

    来自 Google Research 的研究人员探索了多个 transformer 变体,发现它们无法在多个实现和应用中实现很好地迁移,大多数架构更改无法有效提升性能. Transformer 诞生短 ...

  8. 【CV中的注意力机制】史上最强ResNet变体--ResNeSt

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! [前言]:我们前面已经详细介绍了Attention机制和视觉注意力机制在图像分类结 ...

  9. ResNet超强变体:京东AI新开源的计算机视觉模块

    论文地址:https://arxiv.org/pdf/2107.12292.pdf 源代码地址:https://github.com/JDAI-CV/CoTNet 前言 具有自注意力的Transfor ...

最新文章

  1. CentOS 6.x 使用安装光盘作为yum源
  2. apache服务Forbidden 403问题精彩总结
  3. 小乌龟游泳java_乌龟翻身那么痛苦,它们为什么还没有灭绝?
  4. 计算机科学与技术python方向是什么意思-计算机科学与技术专业大学应该掌握什么样的基本技能?...
  5. Android 测试教程
  6. 确认访问用户身份的认证
  7. 使用WEB方式更改域用户帐户密码
  8. ASP.NET-权限管理五张表
  9. python的json.dump参数使用
  10. python在线编程免费课程-吐血整理!程序员最爱的13个免费Python课程
  11. window.open('') 火狐,IE事件冒泡处理,点击事件冒泡处理
  12. JS调用摄像头屏幕截图
  13. 领克发布智能电混技术 全新设计语言概念车亮相
  14. Rainmeter,让你的桌面更精彩~
  15. vue 商城浏览足迹_vue实现用户获取浏览记录功能
  16. HTML常用标签总结 [建议收藏]
  17. Mac苹果电脑没有声音怎么办
  18. 【C4D】材质+渲染自学宝典(纯干货)
  19. 每日刷题记录 (二十)
  20. 【0173】推荐6款最好使用的PostgreSQL GUI工具

热门文章

  1. 梦想还需有,因它必实现——发现最新版iOS漏洞,OverSky团队专访
  2. rabbitmq基础2——rabbitmq二进制安装和docker安装、基础命令
  3. JAVA + 阿里云 实现单个短信发送 和 批量短信发送(直接拷贝就能使用)
  4. Object的属性和静态方法
  5. java script 截断_JavaScript截取字符串的最后几个字符
  6. mysql服务器 网关,数据库智能网关-PLC与SQLServer/MySQL数据库双向通讯SELECT/INSERT...
  7. OpenHaptic环境搭建以及调试通例子程序过程中的参考(零零碎碎吧)
  8. C语言值传递与地址传递
  9. linux convert 命令 把gif转成jpg或png格式的问题
  10. 科大讯飞笔试题iflytek序列查找