# 十、TensorFlow 和 Keras 中的自編碼器
自編碼器是一種神經網絡架構,通常與無監督學習,降維和數據壓縮相關聯。自編碼器通過使用隱藏層中較少數量的神經元來學習產生與輸入層相同的輸出。這允許隱藏層以較少數量的參數學習輸入的特征。使用較少數量的神經元來學習輸入數據的特征的這個過程反過來減少了輸入數據集的維度。
自編碼器架構有兩個階段:編碼器和解碼器。在編碼器階段,模型學習表示具有較小維度的壓縮向量的輸入,并且在解碼器階段,模型學習將壓縮向量表示為輸出向量。損失計算為輸出和輸入之間的熵距離,因此通過最小化損失,我們學習將輸入編碼成能夠產生輸入的表示的參數,以及另一組學習參數。
在本章中,您將學習如何使用 TensorFlow 和 Keras 在以下主題中創建自編碼器架構:
* 自編碼器類型
* TensorFlow 和 Keras 中的棧式自編碼器
* 在 TensorFlow 和 Keras 中對自編碼器進行去噪
* TensorFlow 和 Keras 中的變分自編碼器
# 自編碼器類型
自編碼器架構可以在各種配置中找到,例如簡單自編碼器,稀疏自編碼器,去噪自編碼器和卷積自編碼器。
* **簡單自編碼器**:在簡單的自編碼器中,與輸入相比,隱藏層具有較少數量的節點或神經元。例如,在 MNIST 數據集中,784 個特征的輸入可以連接到 512 個節點的隱藏層或 256 個節點,其連接到 784 特征輸出層。因此,在訓練期間,僅由 256 個節點學習 784 個特征。 簡單自編碼器也稱為欠完整自編碼器。
簡單的自編碼器可以是單層或多層。通常,單層自編碼器在生產中表現不佳。多層自編碼器具有多個隱藏層,分為編碼器和解碼器分組。編碼器層將大量特征編碼為較少數量的神經元,然后解碼器層將學習的壓縮特征解碼回原始特征或減少數量的特征。多層自編碼器被稱為**棧式自編碼器** 。
* **稀疏自編碼器**:在稀疏自編碼器中,添加正則化項作為懲罰,因此,與簡單自編碼器相比,表示變得更稀疏。
* **去噪自編碼器**(DAE):在 DAE 架構中,輸入帶有隨機噪聲。 DAE 重新創建輸入并嘗試消除噪音。 DAE 中的損失函數將去噪重建輸出與原始未損壞輸入進行比較。
* **卷積自編碼器**(CAE):前面討論過的自編碼器使用全連接層,這種模式類似于多層感知機模型。我們也可以使用卷積層而不是完全連接或密集層。當我們使用卷積層來創建自編碼器時,它被稱為卷積自編碼器。作為一個例子,我們可以為 CAE 提供以下層:
**輸入 -> 卷積 -> 池化 -> 卷積 -> 池化 -> 輸出**
第一組卷積和池化層充當編碼器,將高維輸入特征空間減少到低維特征空間。第二組卷積和池化層充當解碼器,將其轉換回高維特征空間。
* **變分自編碼器**(VAE):變分自編碼器架構是自編碼器領域的最新發展。 VAE 是一種生成模型,即它產生概率分布的參數,從中可以生成原始數據或與原始數據非常相似的數據。
在 VAE 中,編碼器將輸入樣本轉換為潛在空間中的參數,使用該參數對潛在點進行采樣。然后解碼器使用潛點重新生成原始輸入數據。因此,在 VAE 中學習的重點轉移到最大化輸入數據的概率,而不是試圖從輸入重建輸出。
現在讓我們在以下部分中在 TensorFlow 和 Keras 中構建自編碼器。我們將使用 MNIST 數據集來構建自編碼器。自編碼器將學習表示具有較少數量的神經元或特征的 MNIST 數據集的手寫數字。
您可以按照 Jupyter 筆記本中的代碼`ch-10_AutoEncoders_TF_and_Keras`。
像往常一樣,我們首先使用以下代碼讀取 MNIST 數據集:
```py
from tensorflow.examples.tutorials.mnist.input_data import input_data
dataset_home = os.path.join(datasetslib.datasets_root,'mnist')
mnist = input_data.read_data_sets(dataset_home,one_hot=False)
X_train = mnist.train.images
X_test = mnist.test.images
Y_train = mnist.train.labels
Y_test = mnist.test.labels
pixel_size = 28
```
我們從訓練和測試數據集中提取四個不同的圖像及其各自的標簽:
```py
while True:
train_images,train_labels = mnist.train.next_batch(4)
if len(set(train_labels))==4:
break
while True:
test_images,test_labels = mnist.test.next_batch(4)
if len(set(test_labels))==4:
break
```
現在讓我們看看使用 MNIST 數據集構建自編碼器的代碼。
您可以按照 Jupyter 筆記本中的代碼`ch-10_AutoEncoders_TF_and_Keras`。
# TensorFlow 中的棧式自編碼器
在 TensorFlow 中構建棧式自編碼器模型的步驟如下:
1. 首先,定義超參數如下:
```py
learning_rate = 0.001
n_epochs = 20
batch_size = 100
n_batches = int(mnist.train.num_examples/batch_size)
```
1. 定義輸入(即特征)和輸出(即目標)的數量。輸出數量與輸入數量相同:
```py
# number of pixels in the MNIST image as number of inputs
n_inputs = 784
n_outputs = n_inputs
```
1. 定義輸入和輸出圖像的占位符:
```py
x = tf.placeholder(dtype=tf.float32, name="x", shape=[None, n_inputs])
y = tf.placeholder(dtype=tf.float32, name="y", shape=[None, n_outputs])
```
1. 添加編碼器和解碼器層的神經元數量為`[512,256,256,512]`:
```py
# number of hidden layers
n_layers = 2
# neurons in each hidden layer
n_neurons = [512,256]
# add number of decoder layers:
n_neurons.extend(list(reversed(n_neurons)))
n_layers = n_layers * 2
```
1. 定義`w`和`b`參數:
```py
w=[]
b=[]
for i in range(n_layers):
w.append(tf.Variable(tf.random_normal([n_inputs \
if i==0 else n_neurons[i-1],n_neurons[i]]),
name="w_{0:04d}".format(i)
)
)
b.append(tf.Variable(tf.zeros([n_neurons[i]]),
name="b_{0:04d}".format(i)
)
)
w.append(tf.Variable(tf.random_normal([n_neurons[n_layers-1] \
if n_layers > 0 else n_inputs,n_outputs]),
name="w_out"
)
)
b.append(tf.Variable(tf.zeros([n_outputs]),name="b_out"))
```
1. 構建網絡并為每個層使用 sigmoid 激活函數:
```py
# x is input layer
layer = x
# add hidden layers
for i in range(n_layers):
layer = tf.nn.sigmoid(tf.matmul(layer, w[i]) + b[i])
# add output layer
layer = tf.nn.sigmoid(tf.matmul(layer, w[n_layers]) + b[n_layers])
model = layer
```
1. 使用`mean_squared_error`定義`loss`函數,使用`AdamOptimizer`定義`optimizer`函數:
```py
mse = tf.losses.mean_squared_error
loss = mse(predictions=model, labels=y)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer = optimizer.minimize(loss)
```
1. 訓練模型并預測`train`和`test`集的圖像:
```py
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(n_epochs):
epoch_loss = 0.0
for batch in range(n_batches):
X_batch, _ = mnist.train.next_batch(batch_size)
feed_dict={x: X_batch,y: X_batch}
_,batch_loss = tfs.run([optimizer,loss], feed_dict)
epoch_loss += batch_loss
if (epoch%10==9) or (epoch==0):
average_loss = epoch_loss / n_batches
print('epoch: {0:04d} loss = {1:0.6f}'
.format(epoch,average_loss))
# predict images using trained autoencoder model
Y_train_pred = tfs.run(model, feed_dict={x: train_images})
Y_test_pred = tfs.run(model, feed_dict={x: test_images})
```
1. 我們看到以下輸出,因為損失在 20 個周期后顯著減少:
```py
epoch: 0000 loss = 0.156696
epoch: 0009 loss = 0.091367
epoch: 0019 loss = 0.078550
```
1. 現在模型已經過訓練,讓我們顯示訓練模型中的預測圖像。我們寫了一個輔助函數`display_images`來幫助我們顯示圖像:
```py
import random
# Function to display the images and labels
# images should be in NHW or NHWC format
def display_images(images, labels, count=0, one_hot=False):
# if number of images to display is not provided, then display all the images
if (count==0):
count = images.shape[0]
idx_list = random.sample(range(len(labels)),count)
for i in range(count):
plt.subplot(4, 4, i+1)
plt.title(labels[i])
plt.imshow(images[i])
plt.axis('off')
plt.tight_layout()
plt.show()
```
使用此函數,我們首先顯示訓練集中的四個圖像和自編碼器預測的圖像。
第一行表示實際圖像,第二行表示生成的圖像:

生成的圖像有一點點噪音,可以通過更多訓練和超參數調整來消除。現在預測訓練集圖像并不神奇,因為我們在這些圖像上訓練了自編碼器,因此它知道它們。讓我們看一下預測測試集圖像的結果。 第一行表示實際圖像,第二行表示生成的圖像:

哇!經過訓練的自編碼器能夠生成相同的數字,只有從 768 中學到的 256 個特征。生成的圖像中的噪聲可以通過超參數調整和更多訓練來改善。
# Keras 中的棧式自編碼器
現在讓我們在 Keras 中構建相同的自編碼器。
我們使用以下命令清除筆記本中的圖,以便我們可以構建一個新圖,該圖不會占用上一個會話或圖中的任何內存:
`tf.reset_default_graph()`
`keras.backend.clear_session()`
1. 首先,我們導入 keras 庫并定義超參數和層:
```py
import keras
from keras.layers import Dense
from keras.models import Sequential
learning_rate = 0.001
n_epochs = 20
batch_size = 100
n_batches = int(mnist.train.num_examples/batch_sizee
# number of pixels in the MNIST image as number of inputs
n_inputs = 784
n_outputs = n_i
# number of hidden layers
n_layers = 2
# neurons in each hidden layer
n_neurons = [512,256]
# add decoder layers:
n_neurons.extend(list(reversed(n_neurons)))
n_layers = n_layers * 2
```
1. 接下來,我們構建一個順序模型并為其添加密集層。對于更改,我們對隱藏層使用`relu`激活,為最終層使用`linear`激活:
```py
model = Sequential()
# add input to first layer
model.add(Dense(units=n_neurons[0], activation='relu',
input_shape=(n_inputs,)))
for i in range(1,n_layers):
model.add(Dense(units=n_neurons[i], activation='relu'))
# add last layer as output layer
model.add(Dense(units=n_outputs, activation='linear'))
```
1. 現在讓我們顯示模型摘要以查看模型的外觀:
```py
model.summary()
```
該模型在五個密集層中共有 1,132,816 個參數:
```py
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 512) 401920
_________________________________________________________________
dense_2 (Dense) (None, 256) 131328
_________________________________________________________________
dense_3 (Dense) (None, 256) 65792
_________________________________________________________________
dense_4 (Dense) (None, 512) 131584
_________________________________________________________________
dense_5 (Dense) (None, 784) 402192
=================================================================
Total params: 1,132,816
Trainable params: 1,132,816
Non-trainable params: 0
_________________________________________________________________
```
1. 讓我們用上一個例子中的均方損失編譯模型:
```py
model.compile(loss='mse',
optimizer=keras.optimizers.Adam(lr=learning_rate),
metrics=['accuracy'])
model.fit(X_train, X_train,batch_size=batch_size,
epochs=n_epochs)
```
在 20 個周期,我們能夠獲得 0.0046 的損失,相比之前我們得到的 0.078550:
```py
Epoch 1/20
55000/55000 [==========================] - 18s - loss: 0.0193 - acc: 0.0117
Epoch 2/20
55000/55000 [==========================] - 18s - loss: 0.0087 - acc: 0.0139
...
...
...
Epoch 20/20
55000/55000 [==========================] - 16s - loss: 0.0046 - acc: 0.0171
```
現在讓我們預測并顯示模型生成的訓練和測試圖像。第一行表示實際圖像,第二行表示生成的圖像。以下是 t 降雨設置圖像:

以下是測試集圖像:

這是我們在能夠從 256 個特征生成圖像時實現的非常好的準確率。
# TensorFlow 中的去噪自編碼器
正如您在本章的第一部分中所了解的那樣,可以使用去噪自編碼器來訓練模型,以便它們能夠從輸入到訓練模型的圖像中去除噪聲:
1. 出于本示例的目的,我們編寫以下輔助函數來幫助我們為圖像添加噪聲:
```py
def add_noise(X):
return X + 0.5 * np.random.randn(X.shape[0],X.shape[1])
```
1. 然后我們為測試圖像添加噪聲并將其存儲在單獨的列表中:
```py
test_images_noisy = add_noise(test_images)
```
我們將使用這些測試圖像來測試我們的去噪模型示例的輸出。
1. 我們按照前面的例子構建和訓練去噪自編碼器,但有一點不同:在訓練時,我們將噪聲圖像輸入到輸入層,我們用非噪聲圖像檢查重建和去噪誤差,如下面的代碼所示:
```py
X_batch, _ = mnist.train.next_batch(batch_size)
X_batch_noisy = add_noise(X_batch)
feed_dict={x: X_batch_noisy, y: X_batch}
_,batch_loss = tfs.run([optimizer,loss], feed_dict=feed_dict)
```
筆記本`ch-10_AutoEncoders_TF_and_Keras`中提供了去噪自編碼器的完整代碼。
現在讓我們首先顯示從 DAE 模型生成的測試圖像;第一行表示原始的非噪聲測試圖像,第二行表示生成的測試圖像:
```py
display_images(test_images.reshape(-1,pixel_size,pixel_size),test_labels)
display_images(Y_test_pred1.reshape(-1,pixel_size,pixel_size),test_labels)
```
上述代碼的結果如下:

接下來,當我們輸入噪聲測試圖像時,我們顯示生成的圖像:
```py
display_images(test_images_noisy.reshape(-1,pixel_size,pixel_size),
test_labels)
display_images(Y_test_pred2.reshape(-1,pixel_size,pixel_size),test_labels)
```
上述代碼的結果如下:

那太酷了!!該模型學習了圖像并生成了幾乎正確的圖像,即使是非常嘈雜的圖像。通過適當的超參數調整可以進一步提高再生質量。
# Keras 中的去噪自編碼器
現在讓我們在 Keras 中構建相同的去噪自編碼器。
由于 Keras 負責按批量大小喂養訓練集,我們創建了一個嘈雜的訓練集作為我們模型的輸入:
```py
X_train_noisy = add_noise(X_train)
```
Keras 中 DAE 的完整代碼在筆記本`ch-10_AutoEncoders_TF_and_Keras`中提供。
DAE Keras 模型如下所示:
```py
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 512) 401920
_________________________________________________________________
dense_2 (Dense) (None, 256) 131328
_________________________________________________________________
dense_3 (Dense) (None, 256) 65792
_________________________________________________________________
dense_4 (Dense) (None, 512) 131584
_________________________________________________________________
dense_5 (Dense) (None, 784) 402192
=================================================================
Total params: 1,132,816
Trainable params: 1,132,816
Non-trainable params: 0
```
由于 DAE 模型很復雜,為了演示,我們不得不將周期數增加到 100 來訓練模型:
```py
n_epochs=100
model.fit(x=X_train_noisy, y=X_train,
batch_size=batch_size,
epochs=n_epochs,
verbose=0)
Y_test_pred1 = model.predict(test_images)
Y_test_pred2 = model.predict(test_images_noisy)
```
打印生成的圖像:
```py
display_images(test_images.reshape(-1,pixel_size,pixel_size),test_labels)
display_images(Y_test_pred1.reshape(-1,pixel_size,pixel_size),test_labels)
```
第一行是原始測試圖像,第二行是生成的測試圖像:

```py
display_images(test_images_noisy.reshape(-1,pixel_size,pixel_size),
test_labels)
display_images(Y_test_pred2.reshape(-1,pixel_size,pixel_size),test_labels)
```
第一行是噪聲測試圖像,第二行是生成的測試圖像:

正如我們所看到的,去噪自編碼器可以很好地從噪聲版本的圖像中生成圖像。
# TensorFlow 中的變分自編碼器
變分自編碼器是自編碼器的現代生成版本。讓我們為同一個前面的問題構建一個變分自編碼器。我們將通過提供來自原始和嘈雜測試集的圖像來測試自編碼器。
我們將使用不同的編碼風格來構建此自編碼器,以便使用 TensorFlow 演示不同的編碼風格:
1. 首先定義超參數:
```py
learning_rate = 0.001
n_epochs = 20
batch_size = 100
n_batches = int(mnist.train.num_examples/batch_size)
# number of pixels in the MNIST image as number of inputs
n_inputs = 784
n_outputs = n_inputs
```
1. 接下來,定義參數字典以保存權重和偏差參數:
```py
params={}
```
1. 定義每個編碼器和解碼器中隱藏層的數量:
```py
n_layers = 2
# neurons in each hidden layer
n_neurons = [512,256]
```
1. 變分編碼器中的新增加是我們定義潛變量`z`的維數:
```py
n_neurons_z = 128 # the dimensions of latent variables
```
1. 我們使用激活`tanh`:
```py
activation = tf.nn.tanh
```
1. 定義輸入和輸出占位符:
```py
x = tf.placeholder(dtype=tf.float32, name="x",
shape=[None, n_inputs])
y = tf.placeholder(dtype=tf.float32, name="y",
shape=[None, n_outputs])
```
1. 定義輸入層:
```py
# x is input layer
layer = x
```
1. 定義編碼器網絡的偏差和權重并添加層。變分自編碼器的編碼器網絡也稱為識別網絡或推理網絡或概率編碼器網絡:
```py
for i in range(0,n_layers):
name="w_e_{0:04d}".format(i)
params[name] = tf.get_variable(name=name,
shape=[n_inputs if i==0 else n_neurons[i-1],
n_neurons[i]],
initializer=tf.glorot_uniform_initializer()
)
name="b_e_{0:04d}".format(i)
params[name] = tf.Variable(tf.zeros([n_neurons[i]]),
name=name
)
layer = activation(tf.matmul(layer,
params["w_e_{0:04d}".format(i)]
) + params["b_e_{0:04d}".format(i)]
)
```
1. 接下來,添加潛在變量的均值和方差的層:
```py
name="w_e_z_mean"
params[name] = tf.get_variable(name=name,
shape=[n_neurons[n_layers-1], n_neurons_z],
initializer=tf.glorot_uniform_initializer()
)
name="b_e_z_mean"
params[name] = tf.Variable(tf.zeros([n_neurons_z]),
name=name
)
z_mean = tf.matmul(layer, params["w_e_z_mean"]) +
params["b_e_z_mean"]
name="w_e_z_log_var"
params[name] = tf.get_variable(name=name,
shape=[n_neurons[n_layers-1], n_neurons_z],
initializer=tf.glorot_uniform_initializer()
)
name="b_e_z_log_var"
params[name] = tf.Variable(tf.zeros([n_neurons_z]),
name="b_e_z_log_var"
)
z_log_var = tf.matmul(layer, params["w_e_z_log_var"]) +
params["b_e_z_log_var"]
```
1. 接下來,定義表示與`z`方差的變量相同形狀的噪聲分布的`epsilon`變量:
```py
epsilon = tf.random_normal(tf.shape(z_log_var),
mean=0,
stddev=1.0,
dtype=tf.float32,
name='epsilon'
)
```
1. 根據均值,對數方差和噪聲定義后驗分布:
```py
z = z_mean + tf.exp(z_log_var * 0.5) * epsilon
```
1. 接下來,定義解碼器網絡的權重和偏差,并添加解碼器層。變分自編碼器中的解碼器網絡也稱為概率解碼器或生成器網絡。
```py
# add generator / probablistic decoder network parameters and layers
layer = z
for i in range(n_layers-1,-1,-1):
name="w_d_{0:04d}".format(i)
params[name] = tf.get_variable(name=name,
shape=[n_neurons_z if i==n_layers-1 else n_neurons[i+1],
n_neurons[i]],
initializer=tf.glorot_uniform_initializer()
)
name="b_d_{0:04d}".format(i)
params[name] = tf.Variable(tf.zeros([n_neurons[i]]),
name=name
)
layer = activation(tf.matmul(layer, params["w_d_{0:04d}".format(i)]) +
params["b_d_{0:04d}".format(i)])
```
1. 最后,定義輸出層:
```py
name="w_d_z_mean"
params[name] = tf.get_variable(name=name,
shape=[n_neurons[0],n_outputs],
initializer=tf.glorot_uniform_initializer()
)
name="b_d_z_mean"
params[name] = tf.Variable(tf.zeros([n_outputs]),
name=name
)
name="w_d_z_log_var"
params[name] = tf.Variable(tf.random_normal([n_neurons[0],
n_outputs]),
name=name
)
name="b_d_z_log_var"
params[name] = tf.Variable(tf.zeros([n_outputs]),
name=name
)
layer = tf.nn.sigmoid(tf.matmul(layer, params["w_d_z_mean"]) +
params["b_d_z_mean"])
model = layer
```
1. 在變異自編碼器中,我們有重建損失和正則化損失。將損失函數定義為重建損失和正則化損失的總和:
```py
rec_loss = -tf.reduce_sum(y * tf.log(1e-10 + model) + (1-y)
* tf.log(1e-10 + 1 - model), 1)
reg_loss = -0.5*tf.reduce_sum(1 + z_log_var - tf.square(z_mean)
- tf.exp(z_log_var), 1)
loss = tf.reduce_mean(rec_loss+reg_loss)
```
1. 根據`AdapOptimizer`定義優化器函數:
```py
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
.minimize(loss)
```
1. 現在讓我們訓練模型并從非噪聲和噪聲測試圖像生成圖像:
```py
with tf.Session() as tfs:
tf.global_variables_initializer().run()
for epoch in range(n_epochs):
epoch_loss = 0.0
for batch in range(n_batches):
X_batch, _ = mnist.train.next_batch(batch_size)
feed_dict={x: X_batch,y: X_batch}
_,batch_loss = tfs.run([optimizer,loss],
feed_dict=feed_dict)
epoch_loss += batch_loss
if (epoch%10==9) or (epoch==0):
average_loss = epoch_loss / n_batches
print("epoch: {0:04d} loss = {1:0.6f}"
.format(epoch,average_loss))
# predict images using autoencoder model trained
Y_test_pred1 = tfs.run(model, feed_dict={x: test_images})
Y_test_pred2 = tfs.run(model, feed_dict={x: test_images_noisy})
```
我們得到以下輸出:
```py
epoch: 0000 loss = 180.444682
epoch: 0009 loss = 106.817749
epoch: 0019 loss = 102.580904
```
現在讓我們顯示圖像:
```py
display_images(test_images.reshape(-1,pixel_size,pixel_size),test_labels)
display_images(Y_test_pred1.reshape(-1,pixel_size,pixel_size),test_labels)
```
結果如下:

```py
display_images(test_images_noisy.reshape(-1,pixel_size,pixel_size),
test_labels)
display_images(Y_test_pred2.reshape(-1,pixel_size,pixel_size),test_labels)
```
結果如下:

同樣,可以通過超參數調整和增加學習量來改善結果。
# Keras 中的變分自編碼器
在 Keras 中,構建變分自編碼器更容易,并且代碼行更少。 Keras 變分自編碼器最好使用函數式風格構建。到目前為止,我們已經使用了在 Keras 中構建模型的順序樣式,現在在這個例子中,我們將看到在 Keras 中構建 VAE 模型的函數式風格。在 Keras 建立 VAE 的步驟如下:
1. 定義隱藏層和潛在變量層中的超參數和神經元數量:
```py
import keras
from keras.layers import Lambda, Dense, Input, Layer
from keras.models import Model
from keras import backend as K
learning_rate = 0.001
batch_size = 100
n_batches = int(mnist.train.num_examples/batch_size)
# number of pixels in the MNIST image as number of inputs
n_inputs = 784
n_outputs = n_inputs
# number of hidden layers
n_layers = 2
# neurons in each hidden layer
n_neurons = [512,256]
# the dimensions of latent variables
n_neurons_z = 128
```
1. 構建輸入層:
```py
x = Input(shape=(n_inputs,), name='input')
```
1. 構建編碼器層,以及潛在變量的均值和方差層:
```py
# build encoder
layer = x
for i in range(n_layers):
layer = Dense(units=n_neurons[i], activation='relu',name='enc_{0}'.format(i))(layer)
z_mean = Dense(units=n_neurons_z,name='z_mean')(layer)
z_log_var = Dense(units=n_neurons_z,name='z_log_v')(layer)
```
1. 創建噪聲和后驗分布:
```py
# noise distribution
epsilon = K.random_normal(shape=K.shape(z_log_var),
mean=0,stddev=1.0)
# posterior distribution
z = Lambda(lambda zargs: zargs[0] + K.exp(zargs[1] * 0.5) * epsilon,
name='z')([z_mean,z_log_var])
```
1. 添加解碼器層:
```py
# add generator / probablistic decoder network layers
layer = z
for i in range(n_layers-1,-1,-1):
layer = Dense(units=n_neurons[i], activation='relu',
name='dec_{0}'.format(i))(layer)
```
1. 定義最終輸出層:
```py
y_hat = Dense(units=n_outputs, activation='sigmoid',
name='output')(layer)
```
1. 最后,從輸入層和輸出層定義模型并顯示模型摘要:
```py
model = Model(x,y_hat)
model.summary()
```
我們看到以下摘要:
```py
_________________________________________________________________________
Layer (type) Output Shape Param # Connected to
=========================================================================
input (InputLayer) (None, 784) 0
_________________________________________________________________________
enc_0 (Dense) (None, 512) 401920 input[0][0]
_________________________________________________________________________
enc_1 (Dense) (None, 256) 131328 enc_0[0][0]
_________________________________________________________________________
z_mean (Dense) (None, 128) 32896 enc_1[0][0]
_________________________________________________________________________
z_log_v (Dense) (None, 128) 32896 enc_1[0][0]
_________________________________________________________________________
z (Lambda) (None, 128) 0 z_mean[0][0]
z_log_v[0][0]
_________________________________________________________________________
dec_1 (Dense) (None, 256) 33024 z[0][0]
_________________________________________________________________________
dec_0 (Dense) (None, 512) 131584 dec_1[0][0]
_________________________________________________________________________
output (Dense) (None, 784) 402192 dec_0[0][0]
=========================================================================
Total params: 1,165,840
Trainable params: 1,165,840
Non-trainable params: 0
_________________________________________________________________________
```
1. 定義一個計算重建和正則化損失之和的函數:
```py
def vae_loss(y, y_hat):
rec_loss = -K.sum(y * K.log(1e-10 + y_hat) + (1-y) *
K.log(1e-10 + 1 - y_hat), axis=-1)
reg_loss = -0.5 * K.sum(1 + z_log_var - K.square(z_mean) -
K.exp(z_log_var), axis=-1)
loss = K.mean(rec_loss+reg_loss)
return loss
```
1. 使用此損失函數來編譯模型:
```py
model.compile(loss=vae_loss,
optimizer=keras.optimizers.Adam(lr=learning_rate))
```
1. 讓我們訓練 50 個周期的模型并預測圖像,正如我們在前面的部分中所做的那樣:
```py
n_epochs=50
model.fit(x=X_train_noisy,y=X_train,batch_size=batch_size,
epochs=n_epochs,verbose=0)
Y_test_pred1 = model.predict(test_images)
Y_test_pred2 = model.predict(test_images_noisy)
```
讓我們顯示結果圖像:
```py
display_images(test_images.reshape(-1,pixel_size,pixel_size),test_labels)
display_images(Y_test_pred1.reshape(-1,pixel_size,pixel_size),test_labels)
```
我們得到如下結果:

```py
display_images(test_images_noisy.reshape(-1,pixel_size,pixel_size),
test_labels)
display_images(Y_test_pred2.reshape(-1,pixel_size,pixel_size),test_labels)
```
我們得到以下結果:

這很棒!!生成的圖像更清晰,更清晰。
# 總結
自編碼器是無監督數據學習的絕佳工具。它們通常用于降低維數,因此數據可以用較少數量的特征來表示。在本章中,您了解了各種類型的自編碼器。我們使用 TensorFlow 和 Keras 練習構建三種類型的自編碼器:棧式自編碼器,去噪自編碼器和變分自編碼器。我們使用 MNIST 數據集作為示例。
在最后的章節中,您學習了如何使用 TensorFlow 和 Keras 構建各種機器學習和深度學習模型,例如回歸,分類,MLP,CNN,RNN 和自編碼器。在下一章中,您將了解 TensorFlow 和 Keras 的高級功能,這些功能允許我們將模型投入生產。
- TensorFlow 1.x 深度學習秘籍
- 零、前言
- 一、TensorFlow 簡介
- 二、回歸
- 三、神經網絡:感知器
- 四、卷積神經網絡
- 五、高級卷積神經網絡
- 六、循環神經網絡
- 七、無監督學習
- 八、自編碼器
- 九、強化學習
- 十、移動計算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度學習
- 十三、AutoML 和學習如何學習(元學習)
- 十四、TensorFlow 處理單元
- 使用 TensorFlow 構建機器學習項目中文版
- 一、探索和轉換數據
- 二、聚類
- 三、線性回歸
- 四、邏輯回歸
- 五、簡單的前饋神經網絡
- 六、卷積神經網絡
- 七、循環神經網絡和 LSTM
- 八、深度神經網絡
- 九、大規模運行模型 -- GPU 和服務
- 十、庫安裝和其他提示
- TensorFlow 深度學習中文第二版
- 一、人工神經網絡
- 二、TensorFlow v1.6 的新功能是什么?
- 三、實現前饋神經網絡
- 四、CNN 實戰
- 五、使用 TensorFlow 實現自編碼器
- 六、RNN 和梯度消失或爆炸問題
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用協同過濾的電影推薦
- 十、OpenAI Gym
- TensorFlow 深度學習實戰指南中文版
- 一、入門
- 二、深度神經網絡
- 三、卷積神經網絡
- 四、循環神經網絡介紹
- 五、總結
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高級庫
- 三、Keras 101
- 四、TensorFlow 中的經典機器學習
- 五、TensorFlow 和 Keras 中的神經網絡和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于時間序列數據的 RNN
- 八、TensorFlow 和 Keras 中的用于文本數據的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自編碼器
- 十一、TF 服務:生產中的 TensorFlow 模型
- 十二、遷移學習和預訓練模型
- 十三、深度強化學習
- 十四、生成對抗網絡
- 十五、TensorFlow 集群的分布式模型
- 十六、移動和嵌入式平臺上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、調試 TensorFlow 模型
- 十九、張量處理單元
- TensorFlow 機器學習秘籍中文第二版
- 一、TensorFlow 入門
- 二、TensorFlow 的方式
- 三、線性回歸
- 四、支持向量機
- 五、最近鄰方法
- 六、神經網絡
- 七、自然語言處理
- 八、卷積神經網絡
- 九、循環神經網絡
- 十、將 TensorFlow 投入生產
- 十一、更多 TensorFlow
- 與 TensorFlow 的初次接觸
- 前言
- 1.?TensorFlow 基礎知識
- 2. TensorFlow 中的線性回歸
- 3. TensorFlow 中的聚類
- 4. TensorFlow 中的單層神經網絡
- 5. TensorFlow 中的多層神經網絡
- 6. 并行
- 后記
- TensorFlow 學習指南
- 一、基礎
- 二、線性模型
- 三、學習
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 構建簡單的神經網絡
- 二、在 Eager 模式中使用指標
- 三、如何保存和恢復訓練模型
- 四、文本序列到 TFRecords
- 五、如何將原始圖片數據轉換為 TFRecords
- 六、如何使用 TensorFlow Eager 從 TFRecords 批量讀取數據
- 七、使用 TensorFlow Eager 構建用于情感識別的卷積神經網絡(CNN)
- 八、用于 TensorFlow Eager 序列分類的動態循壞神經網絡
- 九、用于 TensorFlow Eager 時間序列回歸的遞歸神經網絡
- TensorFlow 高效編程
- 圖嵌入綜述:問題,技術與應用
- 一、引言
- 三、圖嵌入的問題設定
- 四、圖嵌入技術
- 基于邊重構的優化問題
- 應用
- 基于深度學習的推薦系統:綜述和新視角
- 引言
- 基于深度學習的推薦:最先進的技術
- 基于卷積神經網絡的推薦
- 關于卷積神經網絡我們理解了什么
- 第1章概論
- 第2章多層網絡
- 2.1.4生成對抗網絡
- 2.2.1最近ConvNets演變中的關鍵架構
- 2.2.2走向ConvNet不變性
- 2.3時空卷積網絡
- 第3章了解ConvNets構建塊
- 3.2整改
- 3.3規范化
- 3.4匯集
- 第四章現狀
- 4.2打開問題
- 參考
- 機器學習超級復習筆記
- Python 遷移學習實用指南
- 零、前言
- 一、機器學習基礎
- 二、深度學習基礎
- 三、了解深度學習架構
- 四、遷移學習基礎
- 五、釋放遷移學習的力量
- 六、圖像識別與分類
- 七、文本文件分類
- 八、音頻事件識別與分類
- 九、DeepDream
- 十、自動圖像字幕生成器
- 十一、圖像著色
- 面向計算機視覺的深度學習
- 零、前言
- 一、入門
- 二、圖像分類
- 三、圖像檢索
- 四、對象檢測
- 五、語義分割
- 六、相似性學習
- 七、圖像字幕
- 八、生成模型
- 九、視頻分類
- 十、部署
- 深度學習快速參考
- 零、前言
- 一、深度學習的基礎
- 二、使用深度學習解決回歸問題
- 三、使用 TensorBoard 監控網絡訓練
- 四、使用深度學習解決二分類問題
- 五、使用 Keras 解決多分類問題
- 六、超參數優化
- 七、從頭開始訓練 CNN
- 八、將預訓練的 CNN 用于遷移學習
- 九、從頭開始訓練 RNN
- 十、使用詞嵌入從頭開始訓練 LSTM
- 十一、訓練 Seq2Seq 模型
- 十二、深度強化學習
- 十三、生成對抗網絡
- TensorFlow 2.0 快速入門指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 簡介
- 一、TensorFlow 2 簡介
- 二、Keras:TensorFlow 2 的高級 API
- 三、TensorFlow 2 和 ANN 技術
- 第 2 部分:TensorFlow 2.00 Alpha 中的監督和無監督學習
- 四、TensorFlow 2 和監督機器學習
- 五、TensorFlow 2 和無監督學習
- 第 3 部分:TensorFlow 2.00 Alpha 的神經網絡應用
- 六、使用 TensorFlow 2 識別圖像
- 七、TensorFlow 2 和神經風格遷移
- 八、TensorFlow 2 和循環神經網絡
- 九、TensorFlow 估計器和 TensorFlow HUB
- 十、從 tf1.12 轉換為 tf2
- TensorFlow 入門
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 數學運算
- 三、機器學習入門
- 四、神經網絡簡介
- 五、深度學習
- 六、TensorFlow GPU 編程和服務
- TensorFlow 卷積神經網絡實用指南
- 零、前言
- 一、TensorFlow 的設置和介紹
- 二、深度學習和卷積神經網絡
- 三、TensorFlow 中的圖像分類
- 四、目標檢測與分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻