# 计算模型参数,查看模型结构,我们要查看有多少参数,需要先安装包
pip install torchsummary
import torch
import torch.nn as nn
from torchsummary import summary # 导入 summary 函数,用于计算模型参数和查看模型结构
# 创建神经网络模型类
class Model(nn.Module):
# 初始化模型的构造函数
def __init__(self):
super().__init__() # 调用父类 nn.Module 的初始化方法
# 定义第一个全连接层(线性层),3个输入特征,3个输出特征
self.linear1 = nn.Linear(3, 3)
# 使用 Xavier 正态分布初始化第一个全连接层的权重
nn.init.xavier_normal_(self.linear1.weight)
# 定义第二个全连接层,输入 3 个特征,输出 2 个特征
self.linear2 = nn.Linear(3, 2)
# 使用 Kaiming 正态分布初始化第二个全连接层的权重,适合 ReLU 激活函数
nn.init.kaiming_normal_(self.linear2.weight)
# 定义输出层,输入 2 个特征,输出 2 个特征
self.out = nn.Linear(2, 2)
# 定义前向传播过程 (forward 函数会自动执行,类似于模型的"推理"过程)
def forward(self, x):
# 第一个全连接层运算
x = self.linear1(x)
# 使用 Sigmoid 激活函数
x = torch.sigmoid(x)
# 第二个全连接层运算
x = self.linear2(x)
# 使用 ReLU 激活函数
x = torch.relu(x)
# 输出层运算
x = self.out(x)
# 使用 Softmax 激活函数,将输出转化为概率分布
# dim=-1 表示在最后一个维度(通常是输出的类别维度)上做 softmax 归一化
x = torch.softmax(x, dim=-1)
return x
if __name__ == '__main__':
# 实例化神经网络模型
my_model = Model()
# 随机生成一个形状为 (5, 3) 的输入数据,表示 5 个样本,每个样本有 3 个特征
my_data = torch.randn(5, 3)
print("mydata shape", my_data.shape)
# 通过模型进行前向传播,输出模型的预测结果
output = my_model(my_data)
print("output shape", output.shape)
# 计算并显示模型的参数总量以及模型结构
summary(my_model, input_size=(3,), batch_size=5)
# 查看模型中所有的参数,包括权重和偏置项(bias)
print("-----查看模型参数w 和 b -----")
for name, parameter in my_model.named_parameters():
print(name, parameter)
mydata shape torch.Size([5, 3])
output shape torch.Size([5, 2])
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Linear-1 [5, 3] 12
Linear-2 [5, 2] 8
Linear-3 [5, 2] 6
================================================================
Total params: 26
Trainable params: 26
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------
-----查看模型参数w 和 b -----
linear1.weight Parameter containing:
tensor([[ 0.4777, -0.2076, 0.4900],
[-0.1776, 0.4441, 0.6924],
[-0.5449, 1.6153, 0.0243]], requires_grad=True)
linear1.bias Parameter containing:
tensor([0.4524, 0.2902, 0.4897], requires_grad=True)
linear2.weight Parameter containing:
tensor([[-0.0510, -1.2731, -0.7253],
[-0.6112, 0.1189, -0.4903]], requires_grad=True)
linear2.bias Parameter containing:
tensor([0.5391, 0.2552], requires_grad=True)
out.weight Parameter containing:
tensor([[-0.3271, -0.3483],
[-0.0619, -0.0680]], requires_grad=True)
out.bias Parameter containing:
tensor([-0.5508, 0.5895], requires_grad=True)
代码输出结果解读
这个代码的输出展示了两部分内容:
-
数据维度和模型输出维度:
-
mydata shape torch.Size([5, 3])
-
output shape torch.Size([5, 2])
-
-
模型的结构、参数数量和每一层的权重与偏置:
-
模型的层结构、每一层的输出形状,以及每一层的参数数量。
-
每层的权重(
weight
)和偏置(bias
)的具体数值。
-
让我们详细分析每一部分的输出。
1. 输入数据和输出数据的形状
mydata shape torch.Size([5, 3])
这部分的输出说明:
-
输入数据的形状为
(5, 3)
,表示有 5 个样本,每个样本有 3 个特征。这与模型定义时的输入层nn.Linear(3, 3)
是一致的,输入层期望接收 3 个特征。
output shape torch.Size([5, 2])
这部分的输出说明:
-
模型输出的形状为
(5, 2)
,表示 5 个样本的输出,每个样本的输出有 2 个值。由于模型的输出层定义为nn.Linear(2, 2)
,它接收 2 个输入特征并输出 2 个值,符合预期。
2. 模型结构和参数
模型结构和参数信息是通过 summary()
函数生成的,它列出了每一层的名称、输出形状和参数数量。
详细输出解释:
---------------------------------------------------------------- Layer (type) Output Shape Param # ================================================================ Linear-1 [5, 3] 12 Linear-2 [5, 2] 8 Linear-3 [5, 2] 6 ================================================================ Total params: 26 Trainable params: 26 Non-trainable params: 0 ----------------------------------------------------------------
线性层 1(Linear-1
):
-
层的类型:
Linear
,这是一个全连接层,定义为nn.Linear(3, 3)
。 -
输出形状:
[5, 3]
,表示输入了 5 个样本,每个样本有 3 个特征,经过该层的输出仍然是 5 个样本,每个样本有 3 个特征。 -
参数数量:12,其中 9 个是权重参数(
3 x 3
的权重矩阵),另外 3 个是偏置项。
线性层 2(Linear-2
):
-
层的类型:
Linear
,定义为nn.Linear(3, 2)
,将 3 个输入特征映射到 2 个输出特征。 -
输出形状:
[5, 2]
,表示输入了 5 个样本,每个样本有 2 个输出特征。 -
参数数量:8,其中 6 个是权重参数(
3 x 2
的权重矩阵),另外 2 个是偏置项。
输出层(Linear-3
):
-
层的类型:
Linear
,定义为nn.Linear(2, 2)
,接收 2 个输入特征,输出 2 个特征。 -
输出形状:
[5, 2]
,表示 5 个样本,每个样本的输出为 2 个特征。 -
参数数量:6,其中 4 个是权重参数(
2 x 2
的权重矩阵),另外 2 个是偏置项。
参数统计:
-
总参数数量:26,模型中所有可训练参数(包括权重和偏置)的总数量。
-
可训练参数:26,模型中所有参与训练的参数。这里所有的参数都是可训练的(
requires_grad=True
),没有非可训练的参数。 -
非可训练参数:0,说明模型中没有被设置为不可训练的参数。
3. 查看每一层的权重和偏置
这一部分输出列出了每一层的具体参数(权重和偏置)的值。
linear1.weight
:
tensor([[ 0.4777, -0.2076, 0.4900], [-0.1776, 0.4441, 0.6924], [-0.5449, 1.6153, 0.0243]], requires_grad=True)
这是 linear1
层的权重矩阵,形状是 (3, 3)
。由于 linear1
是 nn.Linear(3, 3)
,它的权重矩阵也是 3 行 3 列。权重参数是使用 Xavier 初始化(nn.init.xavier_normal_
)初始化的。
linear1.bias
:
tensor([0.4524, 0.2902, 0.4897], requires_grad=True)
这是 linear1
层的偏置项,形状是 (3,)
,因为每个输出特征对应一个偏置值。
linear2.weight
:
tensor([[-0.0510, -1.2731, -0.7253], [-0.6112, 0.1189, -0.4903]], requires_grad=True)
这是 linear2
层的权重矩阵,形状是 (2, 3)
,因为 linear2
是 nn.Linear(3, 2)
,需要 3 个输入特征映射到 2 个输出特征。权重是使用 Kaiming 初始化(nn.init.kaiming_normal_
)初始化的。
linear2.bias
:
tensor([0.5391, 0.2552], requires_grad=True)
这是 linear2
层的偏置项,形状是 (2,)
,因为每个输出特征对应一个偏置值。
out.weight
:
tensor([[-0.3271, -0.3483], [-0.0619, -0.0680]], requires_grad=True)
这是输出层 out
的权重矩阵,形状是 (2, 2)
,因为 out
是 nn.Linear(2, 2)
,接收 2 个输入特征并输出 2 个特征。
out.bias
:
tensor([-0.5508, 0.5895], requires_grad=True)
这是输出层 out
的偏置项,形状是 (2,)
。
总结
-
这段代码展示了一个简单的神经网络模型,包含 3 个全连接层(线性层),每层的输入输出特征数量逐步缩小。
-
我们通过
summary()
查看了模型的整体结构,展示了每一层的输出形状和参数数量,总共有 26 个参数。 -
每一层的权重和偏置参数值被输出,展示了它们是如何被初始化的(通过 Xavier 和 Kaiming 初始化)。
-
该模型的前向传播通过激活函数(
sigmoid
和ReLU
)以及 softmax 将输出转化为概率分布。