我们能得到神经网络所代表的函数的逆吗?

人工智能 神经网络 深度学习 Python 数学
2021-10-17 23:33:39

我想知道是否有可能获得神经网络的逆。如果我们将 NN 看作一个函数,我们能得到它的逆吗?

我尝试构建一个简单的 MNIST 架构,输入为 (784,),输出为 (10,),对其进行训练以达到良好的准确度,然后将预测值反转以尝试取回输入 - 但结果是离我开始的地方还差得很远。(我对 W 矩阵使用了伪逆矩阵。)

我的NN基本上是以下功能:

f(x)=θ(xW+b),θ(z)=11+ez

IE

def rev_sigmoid(y):
    return np.log(y/(1-y))

def rev_linear(z, W, b):
    return (z - b) @ np.linalg.pinv(W)

y = model.predict(x_train[0:1])
z = rev_sigmoid(y)
x = rev_linear(z, W, b)
x = x.reshape(28, 28)
plt.imshow(x)

在此处输入图像描述

^ 这应该是 5:

吨

失败有什么原因吗?有没有可能得到NN的逆?

编辑:还值得注意的是,相反的做法确实会产生良好的效果。即从 y 开始(数字的 1-hot 编码)并使用它来预测图像(一个 784 字节的数组),使用相同的架构:输入(10,)和输出(784,)与 sigmoid。这并不完全等价于逆,因为在这里您首先进行线性变换,然后进行非线性变换。在逆过程中,您将首先执行(好吧,撤消)非线性,然后执行(撤消)线性。784x10 矩阵折叠太多信息的说法对我来说似乎有点奇怪,因为确实存在一个 10x784 矩阵可以再现足够多的信息

在此处输入图像描述

3个回答

数学探索

Θ+是的伪逆Θ.

回想一下,如果一个向量vR(Θ)(即在行空间中)然后v=Θ+Θv. 也就是说,只要我们选择一个在行空间中的向量Θ然后我们可以使用伪逆完全保真地重建它。因此,如果任何图像碰巧是行的线性组合Θ然后我们可以重建它。

更具体。f(x)有一个伪逆f+(x)定义为你有。如果我们限制我们的域,这样xC(ΘT)(转置的列空间)然后f+=fres1.

也就是说,在我们的域限制下,伪逆变成了真逆。

外推

这样看来,只要我们处于这样的域限制下,我们就可以为一般 NN 定义伪逆。不过,某些 NN 可能没有任何允许逆向的限制。也许,有一些方法可以规范参数,这样就可以了。带有 ReLU 的 NN 不会承认这样的逆向,因为 ReLU 会丢失关于负值的信息。泄漏的 Relu 可能会起作用。

进一步的调查

最后,这为进一步研究提供了一个区域。一些需要回答的问题可能是:

  • 优化参数是否可以在其行空间中包含非平凡的示例?
  • 如果是这样,在什么条件下这是可能的?
  • 这些示例是否以任何方式表示在行空间中?
  • 是否有某种方法可以对 NN 进行正则化,使其允许对某些所需限制进行逆运算?
  • 可逆性在什么条件下有用?

所以,如果我走相反的路,从我的 y 开始并预测一个 x,然后要求它的倒数 - 我得到了非常好的结果(实际上 - 100% 准确度)。

IE

model = Sequential([
    Dense(784, input_shape=(10,), activation='sigmoid'),
])
model.compile(loss=keras.losses.binary_crossentropy,
              optimizer=keras.optimizers.Adam(0.01),
              metrics=['binary_crossentropy'])
model.fit(y_train, x_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(y_test, x_test))
# train until accuracy > 0.9, then:
W, b = model.get_weights()
y = y_train
x = reverse.predict(y)
z = rev_sigmoid(x)
y_hat = rev_linear(z, W, b)
(y_hat.argmax(axis=1) == y.argmax(axis=1)).mean()  # 1.0

在玩了一些玩具示例之后,我认为另一种方式可能是不可能的,因为矩阵没有逆矩阵。例如,将这些(玩具)矩阵放在 WolframAlpha 中会告诉您行列式为 0,但在 numpy 中,行列式仅略大于 0,因此您设法计算出一个实际上不是逆的“逆”并得到不好的结果。

这也是有道理的。在相反的场景中,我们从 10 维开始,展开到 784,然后折叠回 10。但在“常规”场景中,我们从 784 开始,折叠到 10,然后再次展开到 784 - 并且(我猜) 太多的信息会丢失。

TL博士;我认为任何合理的神经网络的逆都不存在。

假设您正在使用32bitMNIST 示例中的浮点数。不同数字的数量32bitfloat 可以表示是有限的(比如x)

您可以放入神经网络的不同图像的数量 =x784. 但不同输出的总数仅为 x10(因为输出是一个长度向量10)。

因此,根据鸽巢原理,有多个输入对应于相同的输出。

平均还有x784/x10=x774单个输出向量的输入图像。

这意味着该函数是不可逆的,因为它不是一对一的(而且远非如此)。

有些人也在讨论伪逆。我对伪逆了解不多。尽管如此,为了使这些工作(我的意思是能够从给定的输出向量生成数字图像),他们应该能够区分x774图像进入

  1. 看起来像实数的图像和
  2. 其他的,这是一团乱七八糟的闪烁像素,恰好产生给定的输出。

无论算法如何解决这个问题,因此必须拥有该问题的领域知识,可能是通过神经网络权重继承的。

这似乎是神经网络尚未探索的领域。

希望这可以帮助:)