autoencoder自编码器原理以及在mnist数据集上的实现

在这里插入图片描述
Autoencoder是常见的一种非监督学习的神经网络。它实际由一组相对应的神经网络组成(可以是普通的全连接层,或者是卷积层,亦或者是LSTMRNN等等,取决于项目目的),其目的是将输入数据降维成一个低维度的潜在编码,再通过解码器将数据还原出来。因此autoencoder总是包含了两个部分,编码部分以及解码部分。编码部分负责将输入降维编码,解码部分负责让输出层通过潜在编码还原出输入层。我们的训练目标就是使得输出层与输入层之间的差距最小化。

我们会发现,有一定的风险使得训练出的AE模型是一个恒等函数,这是一个需要尽量避免的问题。

Autoencoder CNN 卷积自编码器

下面我们就用一个简单的基于mnist数据集的实现,来更好地理解autoencoder的原理。
首先是import相关的模块,定义一个用于对比显示输入图像与输出图像的可视化函数。

# Le dataset MNIST
from tensorflow.keras.datasets import mnist
import tensorflow as tf
from tensorflow.keras.layers import Input,Dense, Conv2D, Conv2DTranspose, MaxPooling2D, Flatten, UpSampling2D, Reshape
from tensorflow.keras.models import Model,Sequential
import numpy as np
import matplotlib.pyplot as pltdef MNIST_AE_disp(img_in, img_out, img_idx):num_img = len(img_idx)plt.figure(figsize=(18, 4))for i, image_idx in enumerate(img_idx):# 显示输入图像ax = plt.subplot(2, num_img, i + 1)plt.imshow(img_in[image_idx].reshape(28, 28))plt.gray()ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)# 显示输出图像ax = plt.subplot(2, num_img, num_img + i + 1)plt.imshow(img_out[image_idx].reshape(28, 28))plt.gray()ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)plt.show()

加载数据并对mnist图像数据进行预处理,包括正则化以及将图片扩充成28,28,1的三维。

(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 正则化 [0, 255] à [0, 1]
x_train=x_train.astype('float32')/float(x_train.max())
x_test=x_test.astype('float32')/float(x_test.max())x_train=x_train.reshape(len(x_train),x_train.shape[1], x_train.shape[2], 1)
x_test=x_test.reshape(len(x_test),x_test.shape[1], x_test.shape[2], 1)

接下来就是自编码器神经网络的构建了。这里编码器与解码器都由两个卷积层构成,编码部分的池化层,对应了解码部分的upsampling层,以此来保证输入输出层的维度是一致的。

from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model# 编码
input_img = Input(shape=(28,28,1))
x = Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same')(input_img)
x = MaxPooling2D(pool_size=(2,2))(x)
encoded = Conv2D(filters=8, kernel_size=(3,3), activation='relu', padding='same')(x)# 解码
x = Conv2D(filters=16, kernel_size=(3,3), activation='relu', padding='same')(encoded)
x = UpSampling2D(size=(2,2))(x)
decoded = Conv2D(filters=1,kernel_size=(3,3), activation='sigmoid', padding='same')(x)autoencodeur = Model(input_img, decoded)
autoencodeur.summary()
Model: "model_8"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_10 (InputLayer)        [(None, 28, 28, 1)]       0         
_________________________________________________________________
conv2d_36 (Conv2D)           (None, 28, 28, 16)        160       
_________________________________________________________________
max_pooling2d_17 (MaxPooling (None, 14, 14, 16)        0         
_________________________________________________________________
conv2d_37 (Conv2D)           (None, 14, 14, 8)         1160      
_________________________________________________________________
conv2d_38 (Conv2D)           (None, 14, 14, 16)        1168      
_________________________________________________________________
up_sampling2d_9 (UpSampling2 (None, 28, 28, 16)        0         
_________________________________________________________________
conv2d_39 (Conv2D)           (None, 28, 28, 1)         145       
=================================================================
Total params: 2,633
Trainable params: 2,633
Non-trainable params: 0
_________________________________________________________________

接下来就是AE神经网络的训练,与一般的神经网络不同的地方在于,在上述问题中训练自编码器时,输入输出都是同样的mnist图像,以保证在最后输出层能够无限接近输入层,损失降低到最小。

autoencodeur.compile(optimizer='Adam',loss='binary_crossentropy')
autoencodeur.fit(x_train, x_train, batch_size=256, epochs=5)

由于mnist数据集较为简单,在经过五个epoch之后AE模型基本收敛。

Epoch 1/5
235/235 [==============================] - 59s 250ms/step - loss: 0.3742
Epoch 2/5
235/235 [==============================] - 59s 250ms/step - loss: 0.0706
Epoch 3/5
235/235 [==============================] - 59s 250ms/step - loss: 0.0676
Epoch 4/5
235/235 [==============================] - 59s 251ms/step - loss: 0.0666
Epoch 5/5
235/235 [==============================] - 59s 249ms/step - loss: 0.0658

我们从数据集中随机选取10张图片,来对比一下通过自编码器后输入输出的图片的区别。

# 挑选十个随机的图片
num_images=10
np.random.seed(42)
random_test_images=np.random.randint(x_test.shape[0], size=num_images)
# 预测输出图片
decoded_img=autoencodeur.predict(x_test)
# 显示并对比输入与输出图片
MNIST_AE_disp(x_test, decoded_img, random_test_images)

在这里插入图片描述
我们从上述例子中可以看到,输出层与输入层相差无几,但是也并不是完全一致的,这说明了我们的自编码器运作正常且并没有生成一个恒等模型。接下来我们通过AE来构建一个去噪模型。

Autoencoder denoising 降噪自编码器

在这个部分中,我们将利用自编码器来实现对图片的降噪功能。首先我们生成一些带噪点的图片。

noise_factor = 0.4
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) # clip 用于规定最小值和最大值,array中的值如果小于0则变为0 如果大于1则变为1
x_train_noisy = np.clip(x_train_noisy, 0., 1.)
x_test_noisy = np.clip(x_test_noisy, 0., 1.)

直接使用上述已经训练好的模型,来看看当输入是带噪点的图像时,我们的卷积自编码器的输出是什么样的。

num_images=10
np.random.seed(42)
random_test_images_noisy=np.random.randint(x_test_noisy.shape[0], size=num_images) # list that contains the index of images chosen
print(random_test_images)
# On détermine l'image encodée et l'image décodée
decoded_img_noisy=autoencodeur.predict(x_test_noisy) 
# visialisation
MNIST_AE_disp(x_test_noisy, decoded_img_noisy, random_test_images_noisy)

在这里插入图片描述
第一行对应的图片是我们手动生成的有噪点的图像,第二行对应的图片则是我们通过卷积自编码器后的输出图像。可以发现,输出的图像并没有完全一致,而是一定程度上已经去噪了,其实这可以进一步地佐证卷积神经网络处理带噪数据体现出的鲁棒性,即相较全连接层而言,对噪声的敏感程度更低。当然,这个降噪效果还不是很理想,因此我们创建一个新的autoencoder用于处理这一类降噪问题。

DAE = Model(input_img, decoded)
DAE.summary()
DAE.compile(optimizer='Adam', loss='binary_crossentropy')
DAE.fit(x_train_noisy, x_train, batch_size=256, epochs=5)

这个降噪用的自编码器,其架构与上述卷积自编码器相同,唯一有区别的地方在于训练时,我们的输入层变成了带噪图片,而输出层是没有噪声的图片,以此来达到降噪的训练目的。

同样的随机在数据集中选取图片进行对比,我们发现通过这个降噪自编码器后,图像的噪点明显减少了,而且与使用单纯的卷积自编码器不同的是,图像没有明显的钝化,清晰度很高。
在这里插入图片描述
在mnist数据集上的实现,同样可以给我们在其他的图片降噪问题上以启发,可以推测的是,更复杂的有噪图片通过类似的处理,也可以达到类似优秀的降噪效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode编写插件详细过程

vscode编写插件详细过程 前言 之前编写了一个vscode插件用vscode写博客和发布,然后有园友要求写一篇来介绍如何开发一个vscode扩展插件,或者说介绍开发这个插件的过程。然而文章还没有写,园子里面已经有人发布一个文章,是园友上…

pytorch学习笔记 1. pytorch基础 tensor运算

pytorch与tensorflow是两个近些年来使用最为广泛的机器学习模块。开个新坑记录博主学习pytorch模块的过程,不定期更新学习进程。 文章较为适合初学者,欢迎对代码和理解指点讨论,下面进入正题。 import torch import numpy as npt1 torch.te…

2019年区块链的主旋律是中间层协议

2019年区块链的主旋律是中间层协议 过去一年加密资产市场从其峰值下跌超过85%的市值。但对我,一个坚定的区块链企业家,这实际上是一件好事,区块链的未来看起来比以往任何时候都更有希望。2017年ICO热潮开始的疯狂至少产生了一个强烈的积极影响…

tensorflow gpu windows配置步骤教学

本文主要针对在windows10环境下的tensorflow配置问题,在linux和mac等其他环境中的配置就不过多赘述(windows总是那个问题最多的环境,建议使用linux 😃)。 本文中配置的环境为 python 3.8.5 tensorflow-gpu 2.4.1 1. 更新nvidia显卡驱动至最…

【BJOI 2019】奥术神杖

题意 你有一个长度为 $n$ 的模板串(由 $0-9$ 这 $10$ 个数字和通配符 $.$ 组成),还有 $m$ 个匹配串(只由 $0-9$ 这 $10$ 个数字组成),每个匹配串有一个魔力值 $v_i$。你要把模板串的每个 $.$ 都换成一个数字…

C# 篇基础知识10——多线程

1.线程的概念 单核CPU的计算机中,一个时刻只能执行一条指令,操作系统以“时间片轮转”的方式实现多个程序“同时”运行。操作系统以进程(Process)的方式运行应用程序,进程不但包括应用程序的指令流,也包括运…

快速理解binary cross entropy 二元交叉熵

Binary cross entropy 二元交叉熵是二分类问题中常用的一个Loss损失函数,在常见的机器学习模块中都有实现。本文就二元交叉熵这个损失函数的原理,简单地进行解释。 首先是二元交叉熵的公式 : Loss−1N∑i1Nyi⋅log⁡(p(yi))(1−yi)⋅log(1−p(yi))Loss …

Docker搭建自己的GitLab

Docker搭建自己的GitLab docker 介绍 **GitLab: ** GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务 **Docker: ** Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖…

flowable 任务节点多实例使用

我们在使用Flowable 工作流引擎的时候,最常用的肯定是任务节点,因为在OA系统、审批系统、办公自动化系统中核心的处理就是流程的运转,在流程运转的时候,可能我们有这样的一个需求,在一个任务节点的时候,我们…

Linux的目录结构

Linux文件系统是呈树形结构,了解Linux文件系统的目录结构,对于我们驾驭Linux还是有必要的。 目录 说明 / Linux文件系统的入口,也是处于最高一级的目录 /bin 基本系统所需要的命令。功能和/usr/bin类似,这个目录中的文件都是…

一文看懂卷积神经网络CNN的核心

在之前,我总结了关于计算机神经网络与梯度下降的核心,详见下文链接 : 一文看懂计算机神经网络与梯度下降 本文主要会对图像相关的机器学习中最为重要的网络,卷积神经网络作个人的理解分析。 1. 为什么要使用卷积神经网络 在讲述原理之前&am…

[LeetCode] Two Sum

一刷&#xff1a; import java.util.Arrays;public class Solution1 { public int[] twoSum(int[] nums, int target) {int[] indexnew int[2];int sum0;for (int i 0; i < nums.length; i) {for (int j i1; j < nums.length; j) {sumnums[i]nums[j];index[0] i;index[…

机器学习理论梳理2 : KNN K近邻分类模型

本文主要梳理KNN&#xff0c;K近邻模型的基本原理。 从机器学习的大分类来看&#xff0c;K近邻模型属于监督学习中的一种判别式模型&#xff0c;常用于分类问题。初始的数据集中&#xff0c;包含了已经分类标签好的数据。一句话来说&#xff0c;K近邻模型就是通过计算实例与现…

docker安装配置gitlab详细过程

1、方法一 1 docker pull beginor/gitlab-ce:11.0.1-ce.0 2、方法二 如果服务器网路不好或者pull不下来镜像&#xff0c;只能在其它网路比较好的机器上pull下来镜像&#xff0c;导出成一个文件&#xff0c; 再下载上传到网路不好的机器上&#xff0c;然后再从文件中导出来&am…

集合对偶律:分别用图文证明

集合几个法则&#xff1a; 求证&#xff1a; 注&#xff1a;右上角C表示此集合的补集/余集 语言描述&#xff1a;A 并 B的补集 A的补集 交 B的补集 A交B的补集 A的补集 并 B的补集 文字证明&#xff1a;&#xff08;思路&#xff1a;证明两个集合相等&#xff0c;可证两集合…

keras实现嘴唇图像autoencoder

本文分享了我在silent speech 项目过程中实现的基于嘴唇图像数据集的autoencoder自编码器。输入输出都是64∗6464*6464∗64的嘴唇灰度图。自编码器由编码解码两个部分构成&#xff0c;同时实现了利用checkpoint在每个epoch运算时&#xff0c;自动保存测试集loss更小的模型。 数…

historyReverser array reverse

historyReverser & array reverse "use strict";/**** author xgqfrms* license MIT* copyright xgqfrms** description historyReverser* augments Reverse 逆向 / Recursive 递归* example* link**/const historyReverser (datas [], text , debug false)…

pip国内加载速度慢解决方法

在国内使用pip安装包时有时会发现安装速度非常慢&#xff0c;甚至连接不上源。 为了加快pip的下载速度&#xff0c;我们可以主动使用 -i命令来切换到国内源。 下面放出实测好用的国内源 : 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http:…

oracle--导出、导入blob类型的字段

oracle--导出、导入blob类型的字段 blob是oracle中的一个数据类型&#xff0c;保存的是压缩后的二进制形式的大数据。 数据迁移如果涉及到blob字段&#xff0c;都不好处理&#xff0c;因为无法用常规方法进行操作&#xff0c;如&#xff1a;使用select查看该字段&#xff0c;…