火车正确堆叠自动编码器-Keras

Tas*_*lrs 7 python machine-learning deep-learning keras tensorflow

我尝试在Keras(tf.keras)中构建一个堆栈式自动编码器。通过堆叠我的意思并不是很深。我为Keras找到的所有示例都在生成例如3个编码器层,3个解码器层,它们对其进行训练,并称之为一天。但是,本文介绍的一种训练堆叠式自动编码器(SAE)的正确方法似乎是:堆叠式降噪自动编码器:使用局部降噪标准在深度网络中学习有用的表示形式

简而言之,应该对SAE进行分层训练,如下图所示。训练完第1层后,将其用作训练第2层的输入。应将重建损失与第1层而不是输入层进行比较

这就是我的麻烦开始的地方。如何告诉Keras在哪些层上使用损失函数?

这是我的工作。由于Keras中已不存在自动编码器模块,因此我构建了第一个自动编码器,并将其编码器的权重(trainable = False)设置在第二个自动编码器的第一层(总共2层)中。然后,当我训练它时,它显然将重建的图层out_s2与输入图层in_s而不是图层1进行比较hid1

# autoencoder layer 1
in_s = tf.keras.Input(shape=(input_size,))
noise = tf.keras.layers.Dropout(0.1)(in_s)
hid = tf.keras.layers.Dense(nodes[0], activation='relu')(noise)
out_s = tf.keras.layers.Dense(input_size, activation='sigmoid')(hid)

ae_1 = tf.keras.Model(in_s, out_s, name="ae_1")
ae_1.compile(optimizer='nadam', loss='binary_crossentropy', metrics=['acc'])

# autoencoder layer 2
hid1 = tf.keras.layers.Dense(nodes[0], activation='relu')(in_s)
noise = tf.keras.layers.Dropout(0.1)(hid1)
hid2 = tf.keras.layers.Dense(nodes[1], activation='relu')(noise)
out_s2 = tf.keras.layers.Dense(nodes[0], activation='sigmoid')(hid2)

ae_2 = tf.keras.Model(in_s, out_s2, name="ae_2")
ae_2.layers[0].set_weights(ae_1.layers[0].get_weights())
ae_2.layers[0].trainable = False

ae_2.compile(optimizer='nadam', loss='binary_crossentropy', metrics=['acc'])
Run Code Online (Sandbox Code Playgroud)

该解决方案应该相当简单,但是我看不到它,也无法在线找到它。我该如何在Keras中做到这一点?

Kad*_*ikh 1

从评论来看,这个问题似乎已经过时了。但我仍然会回答这个问题,因为这个问题中提到的用例不仅特定于自动编码器,而且可能对其他一些情况有帮助。

因此,当你说“逐层训练整个网络”时,我宁愿将其解释为“按顺序训练单个层的小型网络”。

看看这个问题中发布的代码,似乎OP已经建立了小型网络。但这两个网络都不由单层组成。

这里的第二个自动编码器将第一个自动编码器的输入作为输入。但是,它实际上应该将第一个自动编码器的输出作为输入。

然后,您训练第一个自动编码器并在训练后收集它的预测。然后训练第二个自动编码器,它将第一个自动编码器的输出(预测)作为输入。

现在我们重点关注这一部分:“第1层训练完成后,作为输入来训练第2层。重建损失应该与第1层进行比较,而不是与输入层进行比较。”

由于网络将第 1 层的输出(OP 中的自动编码器 1)作为输入,因此它将与其输出进行比较。任务完成了。

但要实现这一目标,您需要编写model.fit(...)问题中提供的代码中缺少的行。

另外,如果您希望模型计算输入层上的损失,只需将参数替换ymodel,fit(...)自动编码器 1 的输入即可。

简而言之,您只需将这些自动编码器解耦为具有单层的微型网络,然后根据您的意愿训练它们。现在不用用trainable = False,或者你想用就用吧。