使用自动编码器(Autoencoder)及其变体进行特征学习
自動編碼器(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)及其变体进行特征学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2008年最吸引眼球的10只股票
- 下一篇: ibm dsa生成html,IBMxSe