torch.nn.Linear#
PyTorch的 nn.Linear() 是用于设置网络中的全连接层的,需要注意在二维图像处理的任务中,全连接层的输入与输出一般都设置为二维张量,形状通常为[batch_size, size]
,不同于卷积层要求输入输出是四维张量。其用法与形参说明如下:
torch.nn.Linear(in_features, # 输入的神经元个数,也可以说是前一层网络神经元的个数
out_features, # 输出神经元个数,也可以说是该网络层神经元的个数
bias=True, # 网络层是否有偏置,默认存在
device=None,
dtype=None)
对传入数据应用线性变换: \(y=xA^{T}+b\)
Linear其实就是对输入\(X_{n\times i}\)执行了一个线性变换,既:
\(Y_{n\times o}=X_{n\times i}W_{i\times o}+b\)
其中\(W\)是模型要学习的参数,\(W\)的维度为\(W_{i\times o}\),\(b\)是\(o\)维的向量偏置,\(n\)为输入向量的行数(例如,你想一次输入10个样本,即batch_size
为10,则\(n=10\)),\(i\)为输入神经元的个数(例如你的样本特征数为5,则\(i=5\)),\(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([-0.9083], grad_fn=<ViewBackward0>)
我们的输入为[1,2]
,输出了[-0.9083]
。可以查看模型参数验证一下上述的式子:
# 当我们不设置权重和偏执的时候,可以使用下面方式查看系统自动生成的参数
for param in model.parameters():
print(param)
Parameter containing:
tensor([[ 0.4266, -0.4878]], requires_grad=True)
Parameter containing:
tensor([-0.3593], requires_grad=True)
可以看到,模型有3个参数,分别为两个权重和一个偏置。计算可得:
\(y=[1,2]∗[0.4266, -0.4878]^T-0.3593=-0.9083\)
# 通过系统给出的值进行计算
cc= torch.Tensor([1, 2])
bb=torch.Tensor([[0.4266],[-0.4878]]) #转置后的值
dd=torch.matmul(cc,bb)-0.3593
print(dd)
tensor([-0.9083])
# 设置权重和偏置
weight = torch.tensor([[0.5, 0.3]]) # 2x1的权重矩阵
bias = torch.tensor([0.1]) # 偏置向量
model.weight.data = weight
model.bias.data = bias
input = torch.Tensor([1, 2]) # 给一个样本,该样本有2个特征(这两个特征的值分别为1和2)
output = model(input)
output
tensor([1.2000], grad_fn=<ViewBackward0>)
通过给固定的两个权重和一个偏执。计算可得:
\(y=[1,2]∗[0.5, 0.3]^T+0.1=1.2000\)
# 进行验证
ee=torch.matmul(torch.Tensor([1, 2]),torch.Tensor([[0.5],[0.3]]))+0.1
print(ee)
tensor([1.2000])
实战#
假设我们的一次输入三个样本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_{3x5}\) 为:
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_{5x10}\):
model = nn.Linear(in_features=5, out_features=10, bias=True)
经过线性层,其实就是做了一件事,即:
\(Y_{3X10}=X_{3x5}W_{5x10}+b\)
具体表示则为:
\(\begin{align} \left[\begin{array}{lllll} 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{array}\right] & = \left[\begin{array}{lllll} 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{array}\right]\left[\begin{array}{lllll} 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{array}\right]+b \end{align}\)
_=model(X)
__=model(X).size()
print(_)
print(__)
tensor([[-0.0862, -0.4761, -0.2895, -0.0469, -0.2535, -0.0178, -0.2911, -0.3080,
-0.1375, -0.0317],
[-0.0313, -0.7474, -0.1868, -0.0754, -0.1681, 0.0614, -0.2868, -0.3378,
0.0286, 0.0399],
[ 0.0236, -1.0187, -0.0840, -0.1038, -0.0827, 0.1406, -0.2825, -0.3676,
0.1947, 0.1115]], grad_fn=<AddmmBackward0>)
torch.Size([3, 10])