Numpy 理解nn.Linear在PyTorch中正向传播的用法
本研究的目的是建立一个简化的前向传播模型,该模型再现PyTorch中的代码结构,但不使用任何PyTorch库。其思想是在模拟代码结构的同时进行矩阵乘法,包括pyTorch中的类定义 用于正向传播的PyTorch代码Numpy 理解nn.Linear在PyTorch中正向传播的用法,numpy,pytorch,Numpy,Pytorch,本研究的目的是建立一个简化的前向传播模型,该模型再现PyTorch中的代码结构,但不使用任何PyTorch库。其思想是在模拟代码结构的同时进行矩阵乘法,包括pyTorch中的类定义 用于正向传播的PyTorch代码 from torch import nn #DEFINE THE REQUIRED CLASS class Network(nn.Module): def __init__(self): super().__init__()
from torch import nn
#DEFINE THE REQUIRED CLASS
class Network(nn.Module):
def __init__(self):
super().__init__()
# Inputs to hidden layer linear transformation
self.hidden = nn.Linear(784, 256)
# Output layer, 10 units - one for each digit
self.output = nn.Linear(256, 10)
# Define sigmoid activation and softmax output
self.sigmoid = nn.Sigmoid()
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
# Pass the input tensor through each of our operations
x = self.hidden(x)
x = self.sigmoid(x)
x = self.output(x)
x = self.softmax(x)
return x
#use
model = Network()
...
ps = model.forward(some_tensor)
这是我的复制机代码:
class my_mul:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.layer = LAYER(self.dim1, self.dim2)
def forward(self, X):
X = self.layer.doit( X)
return X
class LAYER:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
def __call__(self, Z):
self.matrix2 = Z
def doit(self, X):
self.matrix1 = np.random.rand(self.dim1, self.dim2)
print('matrix 1 in class LAYER ',self.matrix1)
X = np.matmul(self.matrix1, self.matrix2)
import numpy as np
#
np.random.seed(0)
# initialize matrix2 which emulates the tensor being passed down to the forward
# propagation step within a deep network training
matrix2 = np.random.rand(2,2)
print('matrix2 ',matrix2)
#
# use the __call__ method of LAYER to pass matrix2 to LL
LL = LAYER(2,2)
LL(matrix2)
MM = my_mul(2,2)
P = MM.forward(matrix2)
print('the product of the 2 matrices is ', P)
上述“复制器代码”失败如下。问题是数据传递不正确,我不知道如何使它工作
matrix2 [[0.5488135 0.71518937]
[0.60276338 0.54488318]]
matrix 1 in class LAYER [[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
Traceback (most recent call last):
File "all_s.py", line 30, in <module>
P = MM.forward(matrix2)
File "all_s.py", line 7, in forward
X = self.layer.doit( X)
File "all_s.py", line 19, in doit
X = np.matmul(self.matrix1, self.matrix2)
AttributeError: 'LAYER' object has no attribute 'matrix2'
matrix2[[0.5488135 0.71518937]
[0.60276338 0.54488318]]
类层中的矩阵1[[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
回溯(最近一次呼叫最后一次):
文件“all_.py”,第30行,在
P=前向毫米(X 2)
文件“all_.py”,第7行,向前
X=self.layer.doit(X)
文件“all_.py”,第19行,在doit中
X=np.matmul(self.matrix1,self.matrix2)
AttributeError:“LAYER”对象没有属性“matrix2”
问题是,当您在初始化的模型上调用前向函数时,self.matrix2
尚未定义,因为错误提示:
AttributeError:“LAYER”对象没有属性“matrix2”
需要说明的是:MM()
相当于调用MM.\uu调用\uuu()
。您没有调用它,因此出现了错误
我不知道为什么您会在转发
和调用
中都有一个实现。在PyTorch中,高级API调用是通过\uuuuu-call\uuuuu
进行的,这正是您所期望的。而且,\uuuu call\uuu
将调用forward
,并触发模块上已注册的挂钩
快速修复方法是在初始化中定义矩阵(线性层的底层组件)(即在\uuuuuu init\uuuu
内部)。然后,当调用时,执行输入和该矩阵之间的矩阵乘法
class LAYER:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.matrix1 = np.random.rand(self.dim1, self.dim2)
def __call__(self, Z):
return self.doit(Z)
def doit(self, X):
return np.matmul(X, self.matrix1)
不过,类似这样的情况会更清楚:
class Model:
def __init__(self, h, w):
self.layer = Linear(h, w)
def __call__(self, x):
return self.forward(x)
def forward(self, x):
x = self.layer(x)
return x
class Linear:
def __init__(self, h, w):
self.weights = np.random.rand(h, w)
def __call__(self, x):
return self.forward(x)
def forward(self, x):
return np.matmul(x, self.weights)
x = np.random.rand(2, 2)
model = Model(2, 2)
model(x)
现在,您可以在
模型
类中使用其他层。并向后传递线性
问题是,当您在初始化的模型上调用向前函数时,self.matrix2
尚未定义,因为错误提示:
AttributeError:“LAYER”对象没有属性“matrix2”
需要说明的是:MM()
相当于调用MM.\uu调用\uuu()
。您没有调用它,因此出现了错误
我不知道为什么您会在转发
和调用
中都有一个实现。在PyTorch中,高级API调用是通过\uuuuu-call\uuuuu
进行的,这正是您所期望的。而且,\uuuu call\uuu
将调用forward
,并触发模块上已注册的挂钩
快速修复方法是在初始化中定义矩阵(线性层的底层组件)(即在\uuuuuu init\uuuu
内部)。然后,当调用时,执行输入和该矩阵之间的矩阵乘法
class LAYER:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.matrix1 = np.random.rand(self.dim1, self.dim2)
def __call__(self, Z):
return self.doit(Z)
def doit(self, X):
return np.matmul(X, self.matrix1)
不过,类似这样的情况会更清楚:
class Model:
def __init__(self, h, w):
self.layer = Linear(h, w)
def __call__(self, x):
return self.forward(x)
def forward(self, x):
x = self.layer(x)
return x
class Linear:
def __init__(self, h, w):
self.weights = np.random.rand(h, w)
def __call__(self, x):
return self.forward(x)
def forward(self, x):
return np.matmul(x, self.weights)
x = np.random.rand(2, 2)
model = Model(2, 2)
model(x)
现在,您可以在
模型
类中使用其他层。并向后传递线性
我使用了Ivan提供的指南:
class my_mul:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.layer = LAYER(self.dim1, self.dim2)
def forward(self, X):
X = self.layer.doit( X)
return X
class LAYER:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.matrix1 = np.random.rand(self.dim1, self.dim2)
print('matrix 1 in class LAYER ',self.matrix1)
def __call__(self, Z):
Y = self.doit(Z)
return Y
def doit(self, X):
X = np.matmul(self.matrix1, X)
return X
import numpy as np
#
np.random.seed(0)
# initialize matrix2 which emulates the tensor being passed down to the forward
# propagation step within a deep network training
matrix2 = np.random.rand(2,2)
print('matrix2 ',matrix2)
MM = my_mul(2,2)
P = MM.forward(matrix2)
print('the product of the 2 matrices is ', P)
解释
F:\x\finance-2019\AI\udacity\ML_introduction\pytorch\Linear>python all_s.py
matrix2 [[0.5488135 0.71518937]
[0.60276338 0.54488318]]
matrix 1 in class LAYER [[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
the product of the 2 matrices is [[0.62182879 0.65493025]
[0.77768188 0.79886983]]
该行:
MM = my_mul(2,2)
P = MM.forward(matrix2)
创建类my_mul的对象MM,并调用my_mul的init方法:
以MM为单位的对象由类层创建,该类层通过自己的init方法使用提供的高度和宽度维度初始化matrix1
该行:
MM = my_mul(2,2)
P = MM.forward(matrix2)
调用my_mul的forward方法,该方法将matrix2传递给LAYER的doit方法,该方法执行matmul操作并返回矩阵乘积
结果
F:\x\finance-2019\AI\udacity\ML_introduction\pytorch\Linear>python all_s.py
matrix2 [[0.5488135 0.71518937]
[0.60276338 0.54488318]]
matrix 1 in class LAYER [[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
the product of the 2 matrices is [[0.62182879 0.65493025]
[0.77768188 0.79886983]]
结果已通过手动计算验证,并且是正确的。我使用了Ivan提供的指南:
class my_mul:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.layer = LAYER(self.dim1, self.dim2)
def forward(self, X):
X = self.layer.doit( X)
return X
class LAYER:
def __init__(self, h, w):
self.dim1 = h
self.dim2 = w
self.matrix1 = np.random.rand(self.dim1, self.dim2)
print('matrix 1 in class LAYER ',self.matrix1)
def __call__(self, Z):
Y = self.doit(Z)
return Y
def doit(self, X):
X = np.matmul(self.matrix1, X)
return X
import numpy as np
#
np.random.seed(0)
# initialize matrix2 which emulates the tensor being passed down to the forward
# propagation step within a deep network training
matrix2 = np.random.rand(2,2)
print('matrix2 ',matrix2)
MM = my_mul(2,2)
P = MM.forward(matrix2)
print('the product of the 2 matrices is ', P)
解释
F:\x\finance-2019\AI\udacity\ML_introduction\pytorch\Linear>python all_s.py
matrix2 [[0.5488135 0.71518937]
[0.60276338 0.54488318]]
matrix 1 in class LAYER [[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
the product of the 2 matrices is [[0.62182879 0.65493025]
[0.77768188 0.79886983]]
该行:
MM = my_mul(2,2)
P = MM.forward(matrix2)
创建类my_mul的对象MM,并调用my_mul的init方法:
以MM为单位的对象由类层创建,该类层通过自己的init方法使用提供的高度和宽度维度初始化matrix1
该行:
MM = my_mul(2,2)
P = MM.forward(matrix2)
调用my_mul的forward方法,该方法将matrix2传递给LAYER的doit方法,该方法执行matmul操作并返回矩阵乘积
结果
F:\x\finance-2019\AI\udacity\ML_introduction\pytorch\Linear>python all_s.py
matrix2 [[0.5488135 0.71518937]
[0.60276338 0.54488318]]
matrix 1 in class LAYER [[0.4236548 0.64589411]
[0.43758721 0.891773 ]]
the product of the 2 matrices is [[0.62182879 0.65493025]
[0.77768188 0.79886983]]
通过人工计算,验证了计算结果的正确性