我开始学习神经网络,我刚刚制作了一个程序,可以学习如何以相当高的准确度识别手写数字(通过反向传播进行训练)。现在我希望能够看到网络认为完美数字是什么样的(本质上是获取一个像素数组,它产生所需的数字,但不是来自数据集)。我的研究结果是空的,但我在另一个网站上发布了文章,并建议我考虑反向传播到输入。我没有太多的数学背景,所以有人可以为我指出如何实现该目标(或实现我的目标的任何其他方法)的正确方向吗?
最佳答案
通过反转模型并可视化输出层的权重(投影到像素处的像素),您可以了解多类分类器神经网络 (NN) 中每个类的“理想”输入。输入层。
假设您有一个简单的线性分类器 NN,它有 784 个输入(MNIST 数字图像中的像素数)和 10 个输出(数字类别的数量)——没有隐藏层。给定输入图像 x(784 元素列向量)时,输出层的激活 z 由下式给出:z = f(x) = Wx + b 其中 W
是 10 x 784 权重矩阵,b
是 10 元素偏置向量。
您可以进行一些代数计算并轻松反转该模型,以计算给定 z
的 x
:x = f^-1(z) = W^- 1(z - b)。现在假设您想查看
4
类的最佳输入。该类的目标输出为 z = [0 0 0 0 1 0 0 0 0 0]^T
;如果我们暂时忽略偏差,那么您只需要计算 W
的逆的第 4 列(从 0 开始),一个 784 元素的列向量,将其重新排列回 28 x 28 图像,然后查看它。这是最佳输入,因为输出层激活与输入和该类的权重向量的点积成正比,因此与类 4
的权重向量相同的输入向量将最大程度地激活输出层的那个类。
如果向模型添加更多层和非线性,事情会变得更加复杂,但一般方法保持不变。您需要某种方法来计算模型的目标输出 z*
的最佳输入 x*
,但您只知道(可能很复杂)前向映射 z = f(x)
从输入到目标。您可以将此视为优化问题:您正在尝试计算 x* = f^-1(z*)
并且您知道 f
和 z*
。如果您对 f
的了解允许您以封闭形式计算符号逆,那么您只需插入 z*
即可得到 x*
。如果您做不到这一点,您始终可以使用迭代优化过程来连续计算更好的近似值 x1
、x2
、...、xn
给出 x0
的起始猜测。下面是使用 scipy.optimize
执行此操作的一些 Python 伪代码:
import numpy as np
import scipy.optimize
# our forward model, paired layers of already-trained
# weights and biases.
weights = [np.array(...) ...]
biases = [np.array(...) ...]
def f(x):
for W, b in zip(weights, biases):
# relu activation.
x = np.clip(np.dot(W, x) + b, 0, np.inf)
return x
# set our sights on class #4.
zstar = np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0])
# the loss we want to optimize: minimize difference
# between zstar and f(x).
def loss(x):
return abs(f(x) - zstar).sum()
x0 = np.zeros(784)
result = scipy.optimize.minimize(loss, x0)
顺便说一下,这个过程基本上是最近的"Inceptionism" images from Google的核心。 ——优化过程试图确定复制复杂网络中特定隐藏层状态的输入像素。在这种情况下,由于卷积等原因,它更加复杂,但想法是相似的。
关于python - 根据神经网络中给定的输出获取可能的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32000620/