1. 程式人生 > >深度學習之卷積自編碼器

深度學習之卷積自編碼器

一、自編碼器

自編碼器(Autoencoder)是一種旨在將它們的輸入複製到的輸出的神經網路。他們通過將輸入壓縮成一種隱藏空間表示(latent-space representation),然後這種重構這種表示的輸出進行工作。這種網路由兩部分組成,如下圖:

  1. 編碼器:將輸入壓縮為潛在空間表示。可以用編碼函式h = f(x)表示。
  2. 解碼器:這部分旨在重構來自隱藏空間表示的輸入。可以用解碼函式r = g(h)表示。

 因此整個網路可以看成是要g(f(x))和x儘量接近。具體操作如下圖,我們將input輸入一個encoder編碼器,就會得到一個code,這個code也就是輸入的一個表示,然後加一個decoder解碼器,這時候decoder就會輸出一個資訊,那麼如果輸出的這個資訊和一開始的輸入訊號input是很像的(理想情況下就是一樣的),那很明顯,我們就有理由相信這個code是靠譜的。所以,我們就通過調整encoder和decoder的引數,使得重構誤差最小,這時候我們就得到了輸入input訊號的第一個表示了,也就是編碼code了。因為是無標籤資料,所以誤差的來源就是直接重構後與原輸入相比得到。

自動編碼器是一種資料的壓縮演算法,其中資料的壓縮和解壓縮函式是資料相關的、有損的、從樣本中自動學習的。在大部分提到自動編碼器的場合,壓縮和解壓縮的函式是通過神經網路實現的。自編碼器具有如下特點:

1)自動編碼器是資料相關的(data-specific 或 data-dependent),這意味著自動編碼器只能壓縮那些與訓練資料類似的資料。比如,使用人臉訓練出來的自動編碼器在壓縮別的圖片,比如樹木時效能很差,因為它學習到的特徵是與人臉相關的。

2)自動編碼器是有損的,意思是解壓縮的輸出與原來的輸入相比是退化的,MP3,JPEG等壓縮演算法也是如此。這與無失真壓縮演算法不同。

3)自動編碼器是從資料樣本中自動學習的,這意味著很容易對指定類的輸入訓練出一種特定的編碼器,而不需要完成任何新工作。

二、幾種自編碼器

1、卷積自編碼器

卷積自編碼器是採用卷積層代替全連線層,原理和自編碼器一樣,對輸入的象徵進行降取樣以提供較小維度潛在表示,並強制自編碼器學習象徵的壓縮版本。程式碼如下:

# ENCODER
conv_1 = tf.layers.conv2d(x_input, 32, (4, 4), strides=(1, 1), padding='valid',
                          kernel_initializer=tf.truncated_normal_initializer)  # => (142, 142, 32)
batch_norm_1 = tf.nn.relu(tf.layers.batch_normalization(conv_1, training=is_training))   # (142, 142, 32)
conv_2 = tf.layers.conv2d(batch_norm_1, 64, (3, 3), strides=(1, 1), padding='valid',
                          kernel_initializer=tf.truncated_normal_initializer)  # =>(140, 140, 64)
batch_norm_2 = tf.nn.relu(tf.layers.batch_normalization(conv_2, training=is_training))  # (140, 140, 64)
pooling_1 = tf.layers.max_pooling2d(batch_norm_2, pool_size=(5, 5), strides=(5, 5))   # =>(28, 28, 64)
conv_3 = tf.layers.conv2d(pooling_1, 128, (3, 3), strides=(1, 1), padding='valid',
                          kernel_initializer=tf.truncated_normal_initializer)   # =>(26, 26, 128)
batch_norm_3 = tf.nn.relu(tf.layers.batch_normalization(conv_3, training=is_training))    # (26, 26, 128)
pooling_2 = tf.layers.max_pooling2d(batch_norm_3, pool_size=(2, 2), strides=(2, 2))   # =>(13, 13, 128)
self.code = pooling_2
# DECODER
conv_trans_1 = tf.layers.conv2d_transpose(pooling_2, 128, kernel_size=(2, 2), strides=(2, 2))  # =>(26, 26, 128)
conv_trans_1 = tf.nn.relu(tf.layers.batch_normalization(conv_trans_1, training=is_training))  # (26, 26, 256)

conv_trans_2 = tf.layers.conv2d_transpose(conv_trans_1, 64, kernel_size=(3, 3), strides=(1, 1)) # =>(28, 28, 64)
conv_trans_2 = tf.nn.relu(tf.layers.batch_normalization(conv_trans_2, training=is_training))  # (28, 28, 128)

conv_trans_3 = tf.layers.conv2d_transpose(conv_trans_2, 64, kernel_size=(5, 5), strides=(5, 5))  # =>(140, 140, 64)
conv_trans_3 = tf.nn.relu(tf.layers.batch_normalization(conv_trans_3, training=is_training))  # (140, 140, 128)

conv_trans_4 = tf.layers.conv2d_transpose(conv_trans_3, 32, kernel_size=(3, 3), strides=(1, 1))  # (142, 142, 32)
conv_trans_4 = tf.nn.relu(tf.layers.batch_normalization(conv_trans_4, axis=3))  # (142, 142, 64)

conv_trans_5 = tf.layers.conv2d_transpose(conv_trans_4, 1, kernel_size=(4, 4), strides=(1, 1))  # (145, 145, 32)
conv_trans_5 = tf.nn.relu(tf.layers.batch_normalization(conv_trans_5, axis=3))  # (145, 145, 2)

conv_final = tf.layers.conv2d(conv_trans_5, 1, kernel_size=(2, 2), strides=(1, 1), padding='same')  #(145, 145, 1)

2、稀疏自編碼器

如果在AutoEncoder的基礎上加上L1的Regularity限制(L1主要是約束每一層中的節點中大部分都要為0,只有少數不為0,這就是Sparse名字的來源),我們就可以得到Sparse AutoEncoder法。

 如果隱藏節點比可視節點(輸入、輸出)少的話,由於被迫的降維,自編碼器會自動習得訓練樣本的特徵(變化最大,資訊量最多的維度)。但是如果隱藏節點數目過多,甚至比可視節點數目還多的時候,自編碼器不僅會喪失這種能力,更可能會習得一種“恆等函式”——直接把輸入複製過去作為輸出。這時候,我們需要對隱藏節點進行稀疏性限制。所謂稀疏性,就是對一對輸入影象,隱藏節點中被啟用的節點數(輸出接近1)遠遠小於被抑制的節點數目(輸出接近0)。那麼使得神經元大部分的時間都是被抑制的限制則被稱作稀疏性限制。

3、降噪自編碼器

  降噪自動編碼器DA是在自動編碼器的基礎上,訓練資料加入噪聲,所以自動編碼器必須學習去去除這種噪聲而獲得真正的沒有被噪聲汙染過的輸入。因此,這就迫使編碼器去學習輸入訊號的更加魯棒的表達,這也是它的泛化能力比一般編碼器強的原因。DA可以通過梯度下降演算法去訓練。

 

參考資料:

https://blog.csdn.net/marsjhao/article/details/73480859 

http://www.atyun.com/16921.html

https://blog.csdn.net/u010555688/article/details/24438311

​​​​​​