Python 如何为解码器加载经过训练的自动编码器权重?
我有一个CNN 1d自动编码器,它有一个密集的中心层。我想训练这个自动编码器并保存它的模型。我还想保存解码器部分,目标是:将一些中心特征(独立计算)提供给经过训练和加载的解码器,以查看这些独立计算的特征在解码器中的图像Python 如何为解码器加载经过训练的自动编码器权重?,python,tensorflow,keras,autoencoder,Python,Tensorflow,Keras,Autoencoder,我有一个CNN 1d自动编码器,它有一个密集的中心层。我想训练这个自动编码器并保存它的模型。我还想保存解码器部分,目标是:将一些中心特征(独立计算)提供给经过训练和加载的解码器,以查看这些独立计算的特征在解码器中的图像 ## ENCODER encoder_input = Input(batch_shape=(None,501,1)) x = Conv1D(256,3, activation='tanh', padding='valid')(encoder_input) x = MaxPoo
## ENCODER
encoder_input = Input(batch_shape=(None,501,1))
x = Conv1D(256,3, activation='tanh', padding='valid')(encoder_input)
x = MaxPooling1D(2)(x)
x = Conv1D(32,3, activation='tanh', padding='valid')(x)
x = MaxPooling1D(2)(x)
_x = Flatten()(x)
encoded = Dense(32,activation = 'tanh')(_x)
## DECODER (autoencoder)
y = Conv1D(32, 3, activation='tanh', padding='valid')(x)
y = UpSampling1D(2)(y)
y = Conv1D(256, 3, activation='tanh', padding='valid')(y)
y = UpSampling1D(2)(y)
y = Flatten()(y)
y = Dense(501)(y)
decoded = Reshape((501,1))(y)
autoencoder = Model(encoder_input, decoded)
autoencoder.save('autoencoder.hdf5')
## DECODER (independent)
decoder_input = Input(batch_shape=K.int_shape(x)) # import keras.backend as K
y = Conv1D(32, 3, activation='tanh', padding='valid')(decoder_input)
y = UpSampling1D(2)(y)
y = Conv1D(256, 3, activation='tanh', padding='valid')(y)
y = UpSampling1D(2)(y)
y = Flatten()(y)
y = Dense(501)(y)
decoded = Reshape((501,1))(y)
decoder = Model(decoder_input, decoded)
decoder.save('decoder.hdf5')
编辑:
为了确保清楚,我首先需要加入encoded
和第一个y
,也就是说y
必须将encoded
作为输入。完成后,我需要一种方法来加载一个经过训练的解码器,并用一些新的中心功能替换编码的
,我将为解码器提供这些功能
编辑以下答案:
我实现了这个建议,请参见下面的代码
## ENCODER
encoder_input = Input(batch_shape=(None,501,1))
x = Conv1D(256,3, activation='tanh', padding='valid')(encoder_input)
x = MaxPooling1D(2)(x)
x = Conv1D(32,3, activation='tanh', padding='valid')(x)
x = MaxPooling1D(2)(x)
_x = Flatten()(x)
encoded = Dense(32,activation = 'tanh')(_x)
## DECODER (autoencoder)
encoded = Reshape((32,1))(encoded)
y = Conv1D(32, 3, activation='tanh', padding='valid')(encoded)
y = UpSampling1D(2)(y)
y = Conv1D(256, 3, activation='tanh', padding='valid')(y)
y = UpSampling1D(2)(y)
y = Flatten()(y)
y = Dense(501)(y)
decoded = Reshape((501,1))(y)
autoencoder = Model(encoder_input, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
epochs = 10
batch_size = 100
validation_split = 0.2
# train the model
history = autoencoder.fit(x = training, y = training,
epochs=epochs,
batch_size=batch_size,
validation_split=validation_split)
autoencoder.save_weights('autoencoder_weights.h5')
## DECODER (independent)
decoder_input = Input(batch_shape=K.int_shape(encoded)) # import keras.backend as K
y = Conv1D(32, 3, activation='tanh', padding='valid', name='decod_conv1d_1')(decoder_input)
y = UpSampling1D(2, name='decod_upsampling1d_1')(y)
y = Conv1D(256, 3, activation='tanh', padding='valid', name='decod_conv1d_2')(y)
y = UpSampling1D(2, name='decod_upsampling1d_2')(y)
y = Flatten(name='decod_flatten')(y)
y = Dense(501, name='decod_dense1')(y)
decoded = Reshape((501,1), name='decod_reshape')(y)
decoder = Model(decoder_input, decoded)
decoder.save_weights('decoder_weights.h5')
encoder = Model(inputs=encoder_input, outputs=encoded, name='encoder')
features = encoder.predict(training) # features
np.savetxt('features.txt', np.squeeze(features))
predictions = autoencoder.predict(training)
predictions = np.squeeze(predictions)
np.savetxt('predictions.txt', predictions)
然后我打开另一个文件,然后
import h5py
import keras.backend as K
def load_weights(model, filepath):
with h5py.File(filepath, mode='r') as f:
file_layer_names = [n.decode('utf8') for n in f.attrs['layer_names']]
model_layer_names = [layer.name for layer in model.layers]
weight_values_to_load = []
for name in file_layer_names:
if name not in model_layer_names:
print(name, "is ignored; skipping")
continue
g = f[name]
weight_names = [n.decode('utf8') for n in g.attrs['weight_names']]
weight_values = []
if len(weight_names) != 0:
weight_values = [g[weight_name] for weight_name in weight_names]
try:
layer = model.get_layer(name=name)
except:
layer = None
if layer is not None:
symbolic_weights = (layer.trainable_weights +
layer.non_trainable_weights)
if len(symbolic_weights) != len(weight_values):
print('Model & file weights shapes mismatch')
else:
weight_values_to_load += zip(symbolic_weights, weight_values)
K.batch_set_value(weight_values_to_load)
## DECODER (independent)
decoder_input = Input(batch_shape=(None,32,1))
y = Conv1D(32, 3, activation='tanh',padding='valid',name='decod_conv1d_1')(decoder_input)
y = UpSampling1D(2, name='decod_upsampling1d_1')(y)
y = Conv1D(256, 3, activation='tanh', padding='valid', name='decod_conv1d_2')(y)
y = UpSampling1D(2, name='decod_upsampling1d_2')(y)
y = Flatten(name='decod_flatten')(y)
y = Dense(501, name='decod_dense1')(y)
decoded = Reshape((501,1), name='decod_reshape')(y)
decoder = Model(decoder_input, decoded)
#decoder.save_weights('decoder_weights.h5')
load_weights(decoder, 'autoencoder_weights.h5')
# Read autoencoder
decoder.summary()
# read encoded features
features = np.loadtxt('features.txt'.format(batch_size, epochs))
features = np.reshape(features, [1500,32,1])
# evaluate loaded model on features
prediction = decoder.predict(features)
autoencoderpredictions = np.loadtxt('predictions.txt'.format(batch_size, epochs))
fig, ax = plt.subplots(5, figsize=(10,20))
for i in range(5):
ax[i].plot(prediction[100*i], color='blue', label='Decoder')
ax[i].plot(autoencoderpredictions[100*i], color='red', label='AE')
ax[i].set_xlabel('Time components', fontsize='x-large')
ax[i].set_ylabel('Amplitude', fontsize='x-large')
ax[i].set_title('Seismogram n. {:}'.format(1500+100*i+1), fontsize='x-large')
ax[i].legend(fontsize='x-large')
plt.subplots_adjust(hspace=1)
plt.close()
预测
和自动编码预测
不一致。似乎预测
只是小噪声,而自动编码器预测
具有合理的值。您需要:(1)保存AE(自动编码器)的权重;(2) 加载权重文件;(3) 反序列化文件并仅分配与新模型(解码器)兼容的权重
- (1) :
确实包含权重,但是使用.save
可以代替。另外,可以省去额外的反序列化步骤。save\u weights
保存优化器状态和模型架构,后者与新解码器无关.save
- (2) :
默认情况下,尝试分配所有保存的权重,但这不起作用load_weights
文件\u层\u名称
(列表)模型层\u名称中
(列表)名称
的形式迭代文件层名称
;如果name
位于model\u layer\u names
中,则将带有该名称的加载重量附加到weight\u values\u to\u load
K.batch\u set\u值
try-except
循环中将此代码重写为按顺序强制分配,但这既低效又容易出现错误
用法:
##省略;使用有问题的代码,但将所有##解码器层命名如下
autoencoder.save_weights('autoencoder_weights.h5'))
##解码器(独立)
解码器输入=输入(批处理形状=K.int形状(x))
y=Conv1D(32,3,激活=tanh',填充=valid',名称=decod\u Conv1D\u 1')(解码器输入)
y=UpSampling1D(2,name='decod_UpSampling1D_1')(y)
y=Conv1D(256,3,激活=tanh',填充=valid',名称=decod\u Conv1D\u 2')(y)
y=UpSampling1D(2,name='decod_UpSampling1D_2')(y)
y=flatte(name='decod_flatte')(y)
y=密度(501,name='decod_dense1')(y)
解码=重塑((501,1),name='decod_重塑')(y)
解码器=型号(解码器\输入,解码)
解码器.save_weights('decoder_weights.h5'))
加载权重(解码器,“自动编码器权重.h5”)
功能:
导入h5py
将keras.backend作为K导入
def load_权重(模型、文件路径):
将h5py.File(filepath,mode='r')作为f:
文件\u layer\u names=[n.decode('utf8')表示f.attrs['layer\u names']]中的n
model_layer_names=[model.layers中层的layer.name]
重量值到负载=[]
对于文件\图层\名称中的名称:
如果名称不在模型\图层\名称中:
打印(名称,“被忽略;跳过”)
持续
g=f[名称]
权重名称=[n.decode('utf8')表示g.attrs['weight\u name']]中的n
权重值=[]
如果len(权重名称)!=0:
权重值=[g[weight\u name]表示权重名称中的权重名称]
尝试:
图层=模型。获取图层(名称=名称)
除:
层=无
如果图层不是无:
符号权重=(层可训练权重+
层(非可训练重量)
如果len(符号权重)!=len(重量值):
打印('模型和文件权重形状不匹配')
其他:
重量值到载荷+=zip(符号重量、重量值)
K.批次设置值(重量值到负载)
您需要:(1)保存AE(自动编码器)的权重;(2) 加载权重文件;(3) 反序列化文件并仅分配与新模型(解码器)兼容的权重
- (1) :
确实包含权重,但是使用.save
可以代替。另外,可以省去额外的反序列化步骤。save\u weights
保存优化器状态和模型架构,后者与新解码器无关.save
- (2) :
默认情况下,尝试分配所有保存的权重,但这不起作用load_weights
文件\u层\u名称
(列表)模型层\u名称中
(列表)名称
的形式迭代文件层名称
;如果name
位于model\u layer\u names
中,则将带有该名称的加载重量附加到weight\u values\u to\u load
K.batch\u set\u值