如何使用 PyTorch 将参数(网络的权重)应用于输入向量?
How to apply the parameters (weights of a network) to a vector of inputs using PyTorch?
我有一个简单的“神经网络”,它接受两个输入并计算一个线性组合并输出一个标量。在一个方程的情况下,即在 1D 中,我们将有:weight1*inputA + weight2*inputB = output
。现在,我对多维输入感兴趣,即 inputA
是一个向量。所以我希望我的网络将 weight1
应用于向量,例如:weight1 * [input1, input2] + weight2 * [input3, input4]
。在此设置中,我希望输出也为向量:[out1, out2]
,其中 out1 = weight1*inputA + weight2*inputB
。但是,我不想更改网络的输入和输出维度。与一维情况一样,我会将网络初始化为 net = LinearNet(2,1)
,因为我们采用两个输入,inputA
和 inputB
,并得到一个输出。我明白输入和输出本身是多维的,但这不应该打扰我的网络。
以下是一分钟。工作示例:
import numpy as np
import torch
from torch import nn
def f(x,a,b,c,d):
x_next = np.zeros((2,))
x_next[0] = x[0]*(a-b*x[1])
x_next[1] = -x[1]*(c-d*x[0])
return x_next #returns [2,:]
a = 1
b = 0.5
c = 1
d = 0.5
x01 = 1 #init cond. varA
x02 = 2 #init cond. varB
params = [a,b,c,d,x01,x02]
# ==================
h = 0.001
T = 10
K = int(T/h)
# forward euler approx.
x_traj_FE = np.zeros((2,K))
a, b, c, d, x_traj_FE[0,0], x_traj_FE[1,0] = params
for k in range(K-1):
x_traj_FE[:,k+1] = x_traj_FE[:,k] + h*f(x_traj_FE[:,k],a,b,c,d)
# ==================
class LinearNet(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearNet, self).__init__()
self.layer1 = nn.Linear(input_dim, output_dim, bias=False)
#no activation function
def forward(self, x):
x = self.layer1(x)
#no activation
return x
torch.manual_seed(789)
net = LinearNet(2,1)
x_traj = np.zeros((2,K))
a, b, c, d, x_traj[0,0], x_traj[1,0] = params
for k in range(K-1):
print(net.layer1.weight)
input1 = x_traj[:,k]
input2 = f(x_traj[:,k],a,b,c,d)
inputs = torch.Tensor(np.array([input1, input2]))
print('input: '+str(inputs))
print('shape: '+str(inputs.shape))
print('output: '+str(net(inputs)))
break
如果我们运行这个,我们将收到以下输出:
Parameter containing:
tensor([[0.3871, 0.5595]], requires_grad=True)
input: tensor([[ 1., 2.],
[ 0., -1.]])
shape: torch.Size([2, 2])
output: tensor([[ 1.5060],
[-0.5595]], grad_fn=<MmBackward0>)
最终,我想计算耦合方程 f
的前向欧拉步,其中 input1
是系统 f
中每个方程的初始条件,并且input2
是在上一步评估的系统。如果我们手动执行,一步可以计算为(给定上面网络的权重):
weights = [0.3871, 0.5595]
x_traj = np.zeros((2,K))
a, b, c, d, x_traj[0,0], x_traj[1,0] = params
for k in range(K-1):
x_traj[:,k+1] = weights[0]*x_traj[:,k] + weights[1]*f(x_traj[:,k],a,b,c,d)
break
x_traj
输出为:
array([[1. , 0.3871, 0. , ..., 0. , 0. , 0. ],
[2. , 0.2147, 0. , ..., 0. , 0. , 0. ]])
正如我们所见,网络的输出与人工计算不同。我看不到网络如何计算这个标量向量乘法,因此,我无法理解如何检索与手动计算相同的输出。
当您执行 inputs = torch.Tensor(np.array([input1, input2]))
时,您正在创建一个张量,其中第一个 行 是 input1
,第二个 行 是 input2
。当您手动相乘时,您的第一个 列 等于之前的 input1
,input2
也是如此。为了获得与第一种情况相同的结果,您可以将循环中的语句更改为(但是我不知道在您的用例中两者中哪一个在逻辑上是正确的):
inp = torch.stack([x_traj[:,k], f(x_traj[:,k],a,b,c,d)],dim=0) # This gives the same matrix as `inputs` in the first case
x_traj[:,k+1] = weights[0]*inp[:,0] + weights[1]*inp[:,1] # This is equivalent to calling the network in the first case
我有一个简单的“神经网络”,它接受两个输入并计算一个线性组合并输出一个标量。在一个方程的情况下,即在 1D 中,我们将有:weight1*inputA + weight2*inputB = output
。现在,我对多维输入感兴趣,即 inputA
是一个向量。所以我希望我的网络将 weight1
应用于向量,例如:weight1 * [input1, input2] + weight2 * [input3, input4]
。在此设置中,我希望输出也为向量:[out1, out2]
,其中 out1 = weight1*inputA + weight2*inputB
。但是,我不想更改网络的输入和输出维度。与一维情况一样,我会将网络初始化为 net = LinearNet(2,1)
,因为我们采用两个输入,inputA
和 inputB
,并得到一个输出。我明白输入和输出本身是多维的,但这不应该打扰我的网络。
以下是一分钟。工作示例:
import numpy as np
import torch
from torch import nn
def f(x,a,b,c,d):
x_next = np.zeros((2,))
x_next[0] = x[0]*(a-b*x[1])
x_next[1] = -x[1]*(c-d*x[0])
return x_next #returns [2,:]
a = 1
b = 0.5
c = 1
d = 0.5
x01 = 1 #init cond. varA
x02 = 2 #init cond. varB
params = [a,b,c,d,x01,x02]
# ==================
h = 0.001
T = 10
K = int(T/h)
# forward euler approx.
x_traj_FE = np.zeros((2,K))
a, b, c, d, x_traj_FE[0,0], x_traj_FE[1,0] = params
for k in range(K-1):
x_traj_FE[:,k+1] = x_traj_FE[:,k] + h*f(x_traj_FE[:,k],a,b,c,d)
# ==================
class LinearNet(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearNet, self).__init__()
self.layer1 = nn.Linear(input_dim, output_dim, bias=False)
#no activation function
def forward(self, x):
x = self.layer1(x)
#no activation
return x
torch.manual_seed(789)
net = LinearNet(2,1)
x_traj = np.zeros((2,K))
a, b, c, d, x_traj[0,0], x_traj[1,0] = params
for k in range(K-1):
print(net.layer1.weight)
input1 = x_traj[:,k]
input2 = f(x_traj[:,k],a,b,c,d)
inputs = torch.Tensor(np.array([input1, input2]))
print('input: '+str(inputs))
print('shape: '+str(inputs.shape))
print('output: '+str(net(inputs)))
break
如果我们运行这个,我们将收到以下输出:
Parameter containing:
tensor([[0.3871, 0.5595]], requires_grad=True)
input: tensor([[ 1., 2.],
[ 0., -1.]])
shape: torch.Size([2, 2])
output: tensor([[ 1.5060],
[-0.5595]], grad_fn=<MmBackward0>)
最终,我想计算耦合方程 f
的前向欧拉步,其中 input1
是系统 f
中每个方程的初始条件,并且input2
是在上一步评估的系统。如果我们手动执行,一步可以计算为(给定上面网络的权重):
weights = [0.3871, 0.5595]
x_traj = np.zeros((2,K))
a, b, c, d, x_traj[0,0], x_traj[1,0] = params
for k in range(K-1):
x_traj[:,k+1] = weights[0]*x_traj[:,k] + weights[1]*f(x_traj[:,k],a,b,c,d)
break
x_traj
输出为:
array([[1. , 0.3871, 0. , ..., 0. , 0. , 0. ],
[2. , 0.2147, 0. , ..., 0. , 0. , 0. ]])
正如我们所见,网络的输出与人工计算不同。我看不到网络如何计算这个标量向量乘法,因此,我无法理解如何检索与手动计算相同的输出。
当您执行 inputs = torch.Tensor(np.array([input1, input2]))
时,您正在创建一个张量,其中第一个 行 是 input1
,第二个 行 是 input2
。当您手动相乘时,您的第一个 列 等于之前的 input1
,input2
也是如此。为了获得与第一种情况相同的结果,您可以将循环中的语句更改为(但是我不知道在您的用例中两者中哪一个在逻辑上是正确的):
inp = torch.stack([x_traj[:,k], f(x_traj[:,k],a,b,c,d)],dim=0) # This gives the same matrix as `inputs` in the first case
x_traj[:,k+1] = weights[0]*inp[:,0] + weights[1]*inp[:,1] # This is equivalent to calling the network in the first case