基于神经网络的输出获取可能的输入

5
我开始学习神经网络,刚制作了一个通过反向传播训练识别手写数字的程序,准确率相当不错。现在我想看看网络认为完美数字的样子(也就是获取一个像素数组,可以产生所需数字但不在数据集中)。我的研究没有发现相关信息,但在另一个网站上发布后,有人建议我尝试反向传播到输入层。由于我数学基础不强,所以请问如何实现这一方法(或任何其他达成目标的方法)?

对于数学背景/可行性的考虑,请在 stats 上提问。回答这个问题需要对统计学有相当深入的理解。可能不太适合在stackoverflow上提问。 - cel
你的“识别”是指你训练了一个10类分类模型吗? - lmjohns3
1个回答

3
您可以通过反转模型并将输出层的权重投影到输入层的像素上进行可视化,来获取多类分类神经网络(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 的逆矩阵的第四列(从 0 开始),得到一个 784 元素的列向量,重新排列成一个 28 x 28 的图像,并查看它。这是最佳输入,因为输出层激活与输入和该类别的权重向量的点积成正比,因此与类别 4 的权重向量相同的输入向量将在输出层最大程度地激活该类别。
如果将更多层和非线性加入模型,那么事情会变得更加复杂,但是一般的方法仍然相同。你需要一些方法来计算给定模型的目标输出z*时的最佳输入x*,但你只知道从输入到目标的(可能复杂的)正向映射z = f(x)。你可以将其视为一个优化问题:你正在尝试计算x* = f^-1(z*),并且你知道fz*。如果你对f的了解允许你计算闭合形式的符号反演,那么你只需将z*插入即可获得x*。如果你不能这样做,你可以始终使用迭代优化过程来计算给定x0的逐步改进近似值x1x2、...、xn。以下是使用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"图像基本上就是这个过程的核心 -- 优化过程试图确定输入像素,以复制复杂网络中特定隐藏层的状态。由于存在卷积等复杂因素,这种情况更加复杂,但是思想是类似的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接