【发布时间】:2016-05-06 13:55:34
【问题描述】:
我目前正在使用 Keras 框架。并做了一些简单的分类测试等。我想找到一种方法来反向运行网络,使用输出作为输入,反之亦然。有什么办法吗?
【问题讨论】:
标签: python machine-learning neural-network keras
我目前正在使用 Keras 框架。并做了一些简单的分类测试等。我想找到一种方法来反向运行网络,使用输出作为输入,反之亦然。有什么办法吗?
【问题讨论】:
标签: python machine-learning neural-network keras
没有所谓的“反向运行神经网络”,因为神经网络的通用架构没有定义任何非正向数据处理。然而,有一个模型的子类 - 生成模型,目前 不是 keras 的一部分。您唯一能做的就是创建一个以某种方式“模拟”您感兴趣的生成过程的网络。但这是特定于模型的方法,没有通用解决方案。
【讨论】:
有一种方法,但您的里程可能会有所不同,并且它可能只会在输入处返回垃圾,尽管“垃圾”仍会产生您开始的输出。关键短语是“将输入视为权重,并在模型的其余部分固定的情况下对其进行训练”。
也就是说,您可以用一层权重替换输入层,冻结模型的其余部分并在固定输出的同时训练这些权重。
为了适应 Keras 的结构,我创建了一个自定义层并将其命名为“Recover”。在训练模型时不会触发它,但它用作反向训练步骤的虚假输入层。 (我确信该方法可以进一步优化,但这是我能想到的最快的 hack)。
class Recover(Layer):
def __init__(self, **kwargs):
super(Recover, self).__init__(**kwargs)
self.reverse = False
def build(self, input_shape):
self.kernel = self.add_weight(name='kernel',
shape=(input_shape[1],),
initializer='uniform',
trainable=True)
super(Recover, self).build(input_shape)
def call(self, x):
if self.reverse:
return K.ones_like(x)*self.kernel
else:
return x
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[0])
在输入层之后直接添加该层,在该层上设置trainable为False。首先,正常训练网络,这一层应该被忽略,作为一个传递层。
完成此操作后,重置该层内的权重,将该层的reverse 设置为True,将trainable 设置为True,将所有其他层的trainable 设置为False,重新编译模型并重新开始训练。
类似的东西:
for x in model.layers:
x.trainable = False
model.layers[0].trainable = True
model.layers[0].reverse = True
model.compile( ...your compile parameters... )
此时在调用model.fit 时将忽略实际输入,只需为输入数组指定正确形状的零即可。
使用这种方法有时会陷入次优解决方案。只需重新初始化Recover 层的权重并重复。在你训练它之后,Recover 层的权重可以通过调用get_weights() 获得,并将对应于原始模型的输入,这将导致它产生所需的输出。
结果很可能类似于噪声,并且可能需要引入额外的损失(通过在 call 函数中调用 self.add_loss)来强制模型产生有意义的输入。
【讨论】:
我不确定这个用例,但只是添加一个快速修复,就是重新设计一个架构,这样输入就会被视为输出,反之亦然。
假设您的输入数据是形状(例如):
n_obs, n_feat = 1000, 20
n_labels = 2
n_hidden = 100 # you can make this whatever you want
你通常会像这样设计输入层:
Dense(input_dim = n_feat, output_dim = n_hidden)
输出层如下:
Dense(input_dim = n_hidden, output_dim = n_labels)
如果您想“反向”运行,只需制作另一个具有相反架构的模型,例如:
新的输入层:
Dense(input_dim = n_labels, output_dim = n_hidden)
新的输出层:
Dense(input_dim = n_hidden, output_dim = n_feat)
但是和上面lejlot说的类似,这里没有单一的模型解决方案。您不能在输入数据上训练模型,然后在输出数据上对其进行测试。这有意义吗?
基础权重矩阵必须具有正确的数据维度,并且当您尝试为其提供不同形状的数据(即输出数据代替输入数据)时,它无法执行矩阵乘法,即每个神经网络的核心。
如果您对这一点感到困惑,您应该回顾一下神经网络的实际工作原理。
【讨论】:
我认为您正在寻找的是“自动关联”神经网络。它有一个 n 维的输入,有好几层,其中一层是 m 维的“中间层”,然后再有几层通向一个输出层,该输出层的维数与输入层 n 相同。
这里的关键是m远小于n。
它的工作原理是您训练网络重新创建输入,准确地在输出处。然后你把网络分成两半。前半部分从 n 到 m 维度(将输入编码到更小的空间)。后半部分从 m 维变为 n 维(解码,或者“反向”,如果你愿意的话)。
对加密、压缩、无监督学习等非常有用。
【讨论】: