Python 你能反转Pytork神经网络并激活输出的输入吗?
我们能否激活神经网络的输出,以了解神经元如何连接到输入特征 如果我从PyTorch教程中选取一个基本NN示例。下面是一个Python 你能反转Pytork神经网络并激活输出的输入吗?,python,neural-network,pytorch,Python,Neural Network,Pytorch,我们能否激活神经网络的输出,以了解神经元如何连接到输入特征 如果我从PyTorch教程中选取一个基本NN示例。下面是一个f(x,y)训练示例 导入火炬 N、 D_in,H,D_out=64100010010 x=火炬。随机数(N,D_in) y=火炬。randn(N,D_out) 型号=torch.nn.Sequential( 火炬nn线性(D_in,H), torch.nn.ReLU(), 火炬nn线性(H,D_out), ) 损失=火炬.nn.mse损失(减少='sum') 学习率=1e-4
f(x,y)
训练示例
导入火炬
N、 D_in,H,D_out=64100010010
x=火炬。随机数(N,D_in)
y=火炬。randn(N,D_out)
型号=torch.nn.Sequential(
火炬nn线性(D_in,H),
torch.nn.ReLU(),
火炬nn线性(H,D_out),
)
损失=火炬.nn.mse损失(减少='sum')
学习率=1e-4
对于范围(500)内的t:
y_pred=模型(x)
损失=损失\u fn(y\u pred,y)
模型0_梯度()
loss.backward()
使用手电筒。无梯度()
对于model.parameters()中的参数:
参数-=学习率*参数梯度
在我完成网络训练后,通过x
输入预测y
。是否可以反转经过训练的NN,以便它现在可以从y
输入预测x
我不希望y
与训练y
输出的原始输入匹配。因此,我希望看到模型激活了哪些功能以匹配x
和y
如果可能的话,我如何在不破坏所有权重和连接的情况下重新排列
顺序模型?如果我理解正确,这里有两个问题:
是否有可能确定输入中哪些特征激活了神经元
如果是,是否可以使用此信息从p(x | y)
生成样本
关于1
,确定神经元是否对输入特征x_i
敏感的基本方法是计算该神经元的输出w.r.tx_i
的梯度。高梯度将指示对特定输入元素的敏感性。关于这个主题有丰富的文献,例如,您可以查看引导反向传播或(后者是关于使用convnet进行分类的,但它确实包含有用的想法)
至于2
,我认为你“扭转问题”的方法不正确。问题在于您的网络是有区别的,它的输出可以被看作是argmax_y p(y | x)
。请注意,这是一个逐点估计,而不是分布的完整建模。然而,您感兴趣的反问题似乎是从
p(x|y)=constant*p(y|x)p(x).
你不知道如何从p(y | x)
中取样,你也不知道p(x)
。即使您使用一种方法来发现神经元和特定输入特征之间的相关性,您也只能发现哪些特征对网络预测更重要,但这取决于y
的性质,这可能是不够的。考虑一个玩具实例,您的输入<代码> x>代码>是按照<代码> R^ 2 中的某个分布分布的2D点,其中输出<代码> y>代码>是二进制的,使得在R^ 2 < /代码>中的任何<代码>(a,b)被归类为<代码> 1 < /代码>如果<代码> A1。然后,判别网络可以学习垂直线x=1
作为其决策边界。检查神经元和输入特征之间的相关性将表明,只有第一个坐标在预测中有用,但该信息不足以从输入的完整2d分布中进行采样
我想那可能就是你想要的 这是可能的,但仅限于非常特殊的情况。对于前馈网络(顺序
),每个层都需要可逆;这意味着以下参数将分别应用于每个层。与一层相关的变换是y=激活(W*x+b)
,其中W
是权重矩阵,b
是偏差向量。为了解决x
问题,我们需要执行以下步骤:
反向激活
;但并非所有的激活函数都有相反的结果。例如,ReLU
函数在(-inf,0)
上没有反转。另一方面,如果我们使用tanh
,我们可以使用它的逆函数,即0.5*log((1+x)/(1-x))
为x
求解W*x=逆激活(y)-b
;要存在唯一的解决方案,W
必须具有类似的行和列秩,det(W)
必须为非零。我们可以通过选择特定的网络结构来控制前者,而后者则取决于训练过程
因此,要使神经网络可逆,它必须有一个非常特殊的结构:所有层必须有相同数量的输入和输出神经元(即平方权矩阵),并且激活函数都必须是可逆的
代码:使用PyTorch,我们必须手动对网络进行反演,包括求解线性方程组以及求逆激活函数。考虑下面的一层神经网络的例子(因为每个步骤单独应用到1层以上的步骤是微不足道的):
通过创建两个以相反顺序共享其层的独立顺序网络,这是完全可能的。尽管这只是颠倒了层的顺序,而不是计算步骤的顺序(因为每个层都执行激活(W*x+b)
)。但要使其有意义,您需要能够反转激活
功能,在您的示例中,使用ReLu
,这是不可能的,因为它在(.inf,inf)
上没有反转。所以你需要更准确地说出“反向神经网络”的真正含义。你在寻找吗?@Shai这很酷,但我只是想在我学习的这个阶段反向神经网络。
import torch
N = 10 # number of samples
n = 3 # number of neurons per layer
x = torch.randn(N, n)
model = torch.nn.Sequential(
torch.nn.Linear(n, n), torch.nn.Tanh()
)
y = model(x)
z = y # use 'z' for the reverse result, start with the model's output 'y'.
for step in list(model.children())[::-1]:
if isinstance(step, torch.nn.Linear):
z = z - step.bias[None, ...]
z = z[..., None] # 'torch.solve' requires N column vectors (i.e. shape (N, n, 1)).
z = torch.solve(z, step.weight)[0]
z = torch.squeeze(z) # remove the extra dimension that we've added for 'torch.solve'.
elif isinstance(step, torch.nn.Tanh):
z = 0.5 * torch.log((1 + z) / (1 - z))
print('Agreement between x and z: ', torch.dist(x, z))