基于Python的自编码器拟合数据分布的两类技术疑问
问题与解答
代码实现回顾
生成随机数据
import numpy as np from keras import models,layers from keras import applications from sklearn.model_selection import train_test_split data = np.random.normal(100, 10, 100) # generate 100 numbers
划分训练集与测试集
data_train, data_test = train_test_split(data, test_size=0.33) # split into train and test
搭建自编码器模型
embedding_dim = 42 # dimensionality of the latents space #Input layer input_data = layers.Input(shape=(1,)) #Encoding layer encoded = layers.Dense(embedding_dim, activation='relu')(input_data) #Decoding layer decoded = layers.Dense(1,activation='linear')(encoded) #Autoencoder --> in this API Model, we define the Input tensor and the output layer #wraps the 2 layers of Encoder e Decoder autoencoder = models.Model(input_data,decoded) autoencoder.summary() #Encoder encoder = models.Model(input_data,encoded) #Decoder encoded_input = layers.Input(shape=(embedding_dim,)) decoder_layers = autoencoder.layers[-1] #applying the last layer decoder = models.Model(encoded_input,decoder_layers(encoded_input)) autoencoder.compile( optimizer='adadelta', #backpropagation Gradient Descent loss='binary_crossentropy' ) history = autoencoder.fit(data_train,data_train, epochs=50,batch_size=256,shuffle=True, validation_data=(data_test,data_test))
预测代码
# do predictions predictions = encoder.predict(data_test) predictions = decoder.predict(predictions) predictions
技术疑问解答
1. 潜在空间维度设为42(大于输入维度1)的原理
自编码器并非只能做降维,你当前用的是过完备自编码器:
- 传统降维场景用的是欠完备自编码器(潜在空间维度小于输入),靠约束模型学习数据核心特征实现重构;
- 过完备自编码器没有降维限制,理论上可以直接“记住”输入,但如果配合正则化(比如Dropout、权重衰减),模型会被迫学习数据的通用特征表示而非单纯记忆。
- 对你的1维正态分布数据来说,设42维潜在空间完全没必要——1维数据的潜在特征极其简单,这么做反而容易导致模型过拟合。另外注意,你的任务是回归重构,损失函数应该用
mse(均方误差),binary_crossentropy是二分类任务用的,完全不匹配当前场景。
2. 利用训练好的自编码器生成更多新数据
核心逻辑是给解码器输入符合潜在空间分布的随机向量,具体步骤如下:
- 统计训练好的编码器输出的潜在向量分布:将所有训练数据输入编码器,得到一批潜在向量,计算它们的均值和标准差;
- 基于该分布生成大量随机潜在向量;
- 将这些随机向量输入解码器,得到新的生成数据。
具体代码示例:
# 步骤1:统计潜在空间的分布 train_latent = encoder.predict(data_train) latent_mean = np.mean(train_latent, axis=0) latent_std = np.std(train_latent, axis=0) # 步骤2:生成1000个符合分布的随机潜在向量 num_samples = 1000 random_latent = np.random.normal(latent_mean, latent_std, size=(num_samples, embedding_dim)) # 步骤3:用解码器生成新数据 new_data = decoder.predict(random_latent) # 把输出从2D数组转成1D new_data = new_data.flatten()
执行后就能得到1000个与原始数据分布一致的新样本。
内容的提问来源于stack exchange,提问作者quant
相关产品推荐
相关产品推荐

