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.pswp.cn/news/386825.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386825.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386825.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vscode編寫插件詳細過程

vscode編寫插件詳細過程 前言 之前編寫了一個vscode插件用vscode寫博客和發布,然后有園友要求寫一篇來介紹如何開發一個vscode擴展插件,或者說介紹開發這個插件的過程。然而文章還沒有寫,園子里面已經有人發布一個文章,是園友上…

cannot find output in imported module librosa報錯解決

librosa一直都是用處很廣泛的python聲音信號處理模塊,但在最近的版本更新中,將原本的librosa.output給刪去了。 為了代替之前的librosa.output.write_wav函數將音頻寫入wav文件中,現可以用模塊soundfile代替。 soundfile.write(file, data, …

2018-2019-2 20175328 《Java程序設計》第十一周學習總結

十三章主要內容——Java網絡編程 一、URL類 URL類是java.net包中的一個重要的類,URL的實例封裝著一個統一資源定位符(Uniform Resource Locator),使用URL創建對象的應用程序稱作客戶端程序。 一個URL對象通常包含最基本的三部分信息:協議、地…

修改Header方法

/*** 修改header信息&#xff0c;key-value鍵值對兒加入到header中,如果存在&#xff0c;替換* param request* param key* param value*/ public static void reflectRequestParam(HttpServletRequest request, String key, String value){Class<? extends HttpServletReq…

pytorch學習筆記 1. pytorch基礎 tensor運算

pytorch與tensorflow是兩個近些年來使用最為廣泛的機器學習模塊。開個新坑記錄博主學習pytorch模塊的過程&#xff0c;不定期更新學習進程。 文章較為適合初學者&#xff0c;歡迎對代碼和理解指點討論&#xff0c;下面進入正題。 import torch import numpy as npt1 torch.te…

2019年區塊鏈的主旋律是中間層協議

2019年區塊鏈的主旋律是中間層協議 過去一年加密資產市場從其峰值下跌超過85%的市值。但對我&#xff0c;一個堅定的區塊鏈企業家&#xff0c;這實際上是一件好事&#xff0c;區塊鏈的未來看起來比以往任何時候都更有希望。2017年ICO熱潮開始的瘋狂至少產生了一個強烈的積極影響…

Java枚舉的內容可以使用map的方式

枚舉的內容可以使用map的方式 package com.chinamobile.framework.common.enums;import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import jav…

tensorflow gpu windows配置步驟教學

本文主要針對在windows10環境下的tensorflow配置問題&#xff0c;在linux和mac等其他環境中的配置就不過多贅述(windows總是那個問題最多的環境&#xff0c;建議使用linux &#x1f603;)。 本文中配置的環境為 python 3.8.5 tensorflow-gpu 2.4.1 1. 更新nvidia顯卡驅動至最…

numpy一維數組永遠為列向量

import numpy as np a np.array([1,3,4,5]) print(a.shape) a np.transpose(a) print(a.shape) print(a)a np.ravel(a) print(a.shape) print(a)a a.reshape((1,4)) print(a.shape)輸出如下 (4,) (4,) [1 3 4 5] (4,) [1 3 4 5] (1, 4)我們會發現&#xff0c;對于一維的數…

【BJOI 2019】奧術神杖

題意 你有一個長度為 $n$ 的模板串&#xff08;由 $0-9$ 這 $10$ 個數字和通配符 $.$ 組成&#xff09;&#xff0c;還有 $m$ 個匹配串&#xff08;只由 $0-9$ 這 $10$ 個數字組成&#xff09;&#xff0c;每個匹配串有一個魔力值 $v_i$。你要把模板串的每個 $.$ 都換成一個數字…

keras模型中的默認初始化權重

權重的初始化&#xff0c;決定了模型訓練的起點。一個良好的初始化可以加快訓練過程&#xff0c;同時避免模型收斂至局部最小值。為了在訓練過程中避免使得權重的變化總沿著同一個方向&#xff0c;我們盡量避免將所有權重都初始化為同一個值&#xff0c;如全0矩陣或全1矩陣。 …

java oracle的枚舉錯誤

public enum OracleErrorTypeEnum implements BaseEnum {ORA00001("ORA-00001","不允許有重復的數據"),ORA00017("ORA-00017","請求會話以設置跟蹤事件"),ORA00018("ORA-00018","超出最大會話數"),ORA00019(&quo…

C# 篇基礎知識10——多線程

1.線程的概念 單核CPU的計算機中&#xff0c;一個時刻只能執行一條指令&#xff0c;操作系統以“時間片輪轉”的方式實現多個程序“同時”運行。操作系統以進程&#xff08;Process&#xff09;的方式運行應用程序&#xff0c;進程不但包括應用程序的指令流&#xff0c;也包括運…

keras中mean square error均方誤差理解

機器學習中&#xff0c;針對不同的問題選用不同的損失函數非常重要&#xff0c;而均方誤差就是最基本&#xff0c;也是在解決回歸問題時最常用的損失函數。本文就keras模塊均方誤差的計算梳理了一些細節。 首先看一下均方誤差的數學定義 : 均方誤差是預測向量與真實向量差值的…

Java并發Semaphore信號量的學習

public class MyThreadTest {private final static Semaphore semaphore new Semaphore(2);// 設置2個車位public static void main(String[] args) {System.out.println("start");p(semaphore, true, 1);p(semaphore, false, 2);p(semaphore, false, 3);p(semaphor…

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

Binary cross entropy 二元交叉熵是二分類問題中常用的一個Loss損失函數&#xff0c;在常見的機器學習模塊中都有實現。本文就二元交叉熵這個損失函數的原理&#xff0c;簡單地進行解釋。 首先是二元交叉熵的公式 : Loss?1N∑i1Nyi?log?(p(yi))(1?yi)?log(1?p(yi))Loss …

Docker搭建自己的GitLab

Docker搭建自己的GitLab docker 介紹 **GitLab: ** GitLab 是一個用于倉庫管理系統的開源項目&#xff0c;使用Git作為代碼管理工具&#xff0c;并在此基礎上搭建起來的web服務 **Docker: ** Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴…

kolla-ansible-----常用命令

常用命令 kolla-ansible prechecks -i multinode #部署前環境檢測 kolla-genpwd #生成/etc/kolla/password.yml密碼配置文件 kolla-ansible post-deploy -i multinode #生成認證文件 kolla-ansible mariadb_recovery -i /opt/mutinode #恢復數據庫 kolla-ansible -i multi…

python numpy 分離與合并復數矩陣實部虛部的方法

在進行數字信號處理的過程中&#xff0c;我們往往有對短時傅里葉變換頻譜(spectrogram)進行分析的需求。常見的分析手段對應歐拉公式分為兩種&#xff0c;要么使用模與相位的形式&#xff0c;要么使用實部虛部。本文分享一個簡單的將復數光譜圖分解為實部與虛部以及將兩個部分重…