Pytorch nn.Linear的基本用法
文章目录
nn.Linear的基本定义
nn.Linear定义一个神经网络的线性层,方法签名如下:
torch.nn.Linear(in_features, # 输入的神经元个数
out_features, # 输出神经元个数
bias=True # 是否包含偏置
)
Linear其实就是对输入
X
n
×
i
X_{n times i}
Xn×i 执行了一个线性变换,即:
Y
n
×
o
=
X
n
×
i
W
i
×
o
+
b
Y_{n times o} = X_{n times i}W_{itimes o} + b
Yn×o=Xn×iWi×o+b
其中
W
W
W是模型要学习的参数,
W
W
W 的维度为
W
i
×
o
W_{i times o}
Wi×o ,
b
b
b 是o维的向量偏置,
n
n
n 为输入向量的行数(例如,你想一次输入10个样本,即batch_size为10,则
n
=
10
n=10
n=10 ),
i
i
i 为输入神经元的个数(例如你的样本特征数为5,则
i
=
5
i=5
i=5 ),
o
o
o 为输出神经元的个数。
使用演示:
from torch import nn
import torch
model = nn.Linear(2, 1) # 输入特征数为2,输出特征数为1
input = torch.Tensor([1, 2]) # 给一个样本,该样本有2个特征(这两个特征的值分别为1和2)
output = model(input)
output
tensor([-1.4166], grad_fn=<AddBackward0>)
我们的输入为[1,2]
,输出了[-1.4166]
。可以查看模型参数验证一下上述的式子:
# 查看模型参数
for param in model.parameters():
print(param)
Parameter containing:
tensor([[ 0.1098, -0.5404]], requires_grad=True)
Parameter containing:
tensor([-0.4456], requires_grad=True)
可以看到,模型有3个参数,分别为两个权重和一个偏执。计算可得:
y
=
[
1
,
2
]
∗
[
0.1098
,
−
0.5404
]
T
−
0.4456
=
−
1.4166
y = [1, 2] * [0.1098, -0.5404]^T - 0.4456 = -1.4166
y=[1,2]∗[0.1098,−0.5404]T−0.4456=−1.4166
实战
假设我们的一次输入三个样本A,B,C(即batch_size为3),每个样本的特征数量为5:
A: [0.1,0.2,0.3,0.3,0.3]
B: [0.4,0.5,0.6,0.6,0.6]
C: [0.7,0.8,0.9,0.9,0.9]
则我们的输入向量
X
3
×
5
X_{3times 5}
X3×5 为:
X = torch.Tensor([
[0.1,0.2,0.3,0.3,0.3],
[0.4,0.5,0.6,0.6,0.6],
[0.7,0.8,0.9,0.9,0.9],
])
X
tensor([[0.1000, 0.2000, 0.3000, 0.3000, 0.3000],
[0.4000, 0.5000, 0.6000, 0.6000, 0.6000],
[0.7000, 0.8000, 0.9000, 0.9000, 0.9000]])
定义线性层,我们的输入特征为5,所以in_feature=5
,我们想让下一层的神经元个数为10,所以out_feature=10
,则模型参数为:
W
5
×
10
W_{5times 10}
W5×10
model = nn.Linear(in_features=5, out_features=10, bias=True)
经过线性层,其实就是做了一件事,即:
Y
3
×
10
=
X
3
×
5
W
5
×
10
+
b
Y_{3times 10}=X_{3times 5}W_{5times 10} + b
Y3×10=X3×5W5×10+b
具体表示则为:
[
Y
00
Y
01
⋯
Y
08
Y
09
Y
10
Y
11
⋯
Y
18
Y
19
Y
20
Y
21
⋯
Y
28
Y
29
]
=
[
X
00
X
01
X
02
X
03
X
04
X
10
X
11
X
12
X
13
X
14
X
20
X
21
X
22
X
23
X
24
]
[
W
00
W
01
⋯
W
08
W
09
W
10
W
11
⋯
W
18
W
19
W
20
W
21
⋯
W
28
W
29
W
30
W
31
⋯
W
38
W
39
W
40
W
41
⋯
W
48
W
49
]
+
b
begin{bmatrix} Y_{00} & Y_{01} & cdots & Y_{08} & Y_{09} \ Y_{10} & Y_{11} & cdots & Y_{18} & Y_{19} \ Y_{20} & Y_{21} & cdots & Y_{28} & Y_{29} \ end{bmatrix}=begin{bmatrix} X_{00} & X_{01} & X_{02} & X_{03} & X_{04} \ X_{10} & X_{11} & X_{12} & X_{13} & X_{14} \ X_{20} & X_{21} & X_{22} & X_{23} & X_{24} \ end{bmatrix}begin{bmatrix} W_{00} & W_{01} & cdots & W_{08} & W_{09} \ W_{10} & W_{11} & cdots & W_{18} & W_{19} \ W_{20} & W_{21} & cdots & W_{28} & W_{29} \ W_{30} & W_{31} & cdots & W_{38} & W_{39} \ W_{40} & W_{41} & cdots & W_{48} & W_{49} \ end{bmatrix} + b
⎣
⎡Y00Y10Y20Y01Y11Y21⋯⋯⋯Y08Y18Y28Y09Y19Y29⎦
⎤=⎣
⎡X00X10X20X01X11X21X02X12X22X03X13X23X04X14X24⎦
⎤⎣
⎡W00W10W20W30W40W01W11W21W31W41⋯⋯⋯⋯⋯W08W18W28W38W48W09W19W29W39W49⎦
⎤+b
其中
X
i
⋅
X_{icdot}
Xi⋅就表示第
i
i
i个样本,
W
⋅
j
W_{cdot j}
W⋅j 表示所有输入神经元到第
j
j
j个输出神经元的权重。
注意:这里图有点问题,应该是
W
00
,
W
01
,
W
02
,
.
.
.
,
W
07
,
W
08
,
W
09
W_{00}, W_{01}, W_{02}, ..., W_{07}, W_{08}, W_{09}
W00,W01,W02,...,W07,W08,W09
因为有三个样本,所以相当于依次进行了三次
Y
1
×
10
=
X
1
×
5
W
5
×
10
Y_{1times 10} = X_{1times 5}W_{5times 10}
Y1×10=X1×5W5×10,然后再将三个
Y
1
×
10
Y_{1times 10}
Y1×10 叠在一起
经过线性层后,我们最终的到了
3
×
10
3 times 10
3×10维的矩阵,即 输入3个样本,每个样本维度为5,输出为3个样本,将每个样本扩展成了10维
model(X).size()
torch.Size([3, 10])
参考资料
nn.Linear官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Linear.html