如何计算神经网络的参数量以及创建多隐藏层网络(总参数量接近)

您所在的位置:网站首页 inq的计算公式 如何计算神经网络的参数量以及创建多隐藏层网络(总参数量接近)

如何计算神经网络的参数量以及创建多隐藏层网络(总参数量接近)

2023-03-27 05:42| 来源: 网络整理| 查看: 265

计算神经网络的参数量

对于全连接层来说,其单层的参数量为 (输入维度 + 1) * 该层神经元个数。这是因为全连接层的每个神经元都需要一个 权重向量 和一个 偏置值 来计算其输出,权重向量 的长度就是 输入维度,偏置值 是一个标量。

若当前 network 有 hidden_layers 层 hidden layer,其中每层 hidden_layer 有 hidden_dim 维,则有:

Total\_params = (input\_dim + 1) * hidden\_dim + (hidden\_dim + 1) * hidden\_dim * (hidden\_layers - 1) + (hidden\_dim + 1) * output\_dim

对于一个神经网络来说,其总参数量就是所有全连接层的参数量之和。例如,如果我们有一个神经网络,它有一个输入层(输入维度为 4),一个隐藏层(隐藏层神经元个数为 5),和一个输出层(输出维度为 3),那么它的总参数量就是:

输入层到隐藏层的全连接层: (4 + 1) * 5 = 25

隐藏层到输出层的全连接层: (5 + 1) * 3 = 18

总参数量: 25 + 18 = 43

图源自《动手学深度学习》

创建多隐藏层的网络

那么该如何创建多隐藏层的网络,顺便打印参数量呢? 这里举个例子说明:

import torch.nn as nn input_dim = 8 hidden_dim = 16 hidden_layers = 2 output_dim = 8 # 为了简洁,舍去了 Relu() network = nn.Sequential( nn.Linear(input_dim, hidden_dim), # 在函数的调用中,一个 * 表示将一个序列展开为单独的位置参数,这一行代码是列表推导,最终的表现是重复生成多个 hidden layer *[nn.Linear(hidden_dim, hidden_dim) for _ in range(hidden_layers-1)], nn.Linear(hidden_dim, output_dim) ) # 打印总参数量 total_params = ( (input_dim+1) * hidden_dim + (hidden_dim + 1) * hidden_dim * (hidden_layers - 1) + (hidden_dim + 1) * output_dim ) print(f'Total params: {total_params}') >> Total params: 552

当然,实际上你可以直接使用 pytorch 中的函数进行打印

total_params = sum(param.numel() for param in network.parameters()) print(f'Total params: {total_params}') >> Total params: 552

进一步的,如果你想查看各层分别的参数量,你可以使用以下代码

for name, param in network.named_parameters(): print(name, param.numel()) >> 0.weight 128 >> 0.bias 16 >> 1.weight 256 >> 1.bias 16 >> 2.weight 128 >> 2.bias 8

其中 weight 对应的是权重,bias是偏差。

构建总参数量接近的神经网络这个视频片段能够让你更好的了解 Deep Network 和 Shallow network 的差异:Why Deep Learning?

已知神经网络的总参数量由下式给出: Total\_params = (input\_dim + 1) * hidden\_dim + (hidden\_dim + 1) * hidden\_dim * (hidden\_layers - 1) + (hidden\_dim + 1) * output\_dim

为了符号简便,做以下简写: i = input\_dim\\o = output\_dim\\l = hidden\_layers\\d = hidden\_dim

有: Total\_params = (i + 1) * d + (d + 1) * d * (l - 1) + (d + 1) * o

进一步的,将其化成一元二次方程的形式,其中 d 为自变量: Total\_params = (l - 1) * d^2 + (i + o + l) * d + o

假设 i, o, l, d 均为已知量,现在需要求:在输入输出维度不变的情况下,当 dest\_hidden\_layers 给定时,隐藏层的维数等于多少才能让两个网络的总参数量接近?( dest 代指我们要计算的目标网络)

同样的,做以下简写: l_d = dest\_hidden\_layers\\ d_d = dest\_hidden\_dim

则有:

dest\_Total\_params = (l_d - 1) * d_d^2 + (i + o + l_d) * d_d + o

令 dest\_Total\_params = Total\_params :

(l_d - 1) * d_d^2 + (i + o + l_d) * d_d + o = (l - 1) * d^2 + (i + o + l) * d + o\\ \Rightarrow(l_d - 1) * d_d^2 + (i + o + l_d) * d_d - (l - 1) * d^2 - (i + o + l) * d = 0

这实际上是一个一元二次方程,其中 d_d 为自变量,其余均已知,可当作常数看待。令 a = l_d - 1,\\ b = i + o + l_d,\\ c = - (l - 1) * d^2 - (i + o + l) * d

则上式可化成 a * d_d^2 + b *d_d + c = 0 由一元二次方程的求根公式 y = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} 有 d_d = \frac{-(i+o+l_d) \pm \sqrt{(i+o+l_d)^2 - 4(l_d-l)(-((l - 1) * d^2 - (i + o + l) * d))}}{2(l_d-l)}

你可以通过调用下方代码中的 get_dest_dim() 获取目标网络隐藏层应该设置的维度。

def get_dest_dim(input_dim, output_dim, hidden_layers, dest_hidden_layers, hidden_dim): '''获取目标网络隐藏层的维度(总参数量接近于原网络)''' # 计算一元二次方程的系数 a,b,c a = dest_hidden_layers - 1 # a = l_d - 1 b = input_dim + output_dim + dest_hidden_layers # b = i + o + l_d c = - (hidden_layers - 1) * (hidden_dim ** 2) - (input_dim + output_dim + hidden_layers) * hidden_dim # c = - (l - 1) * (d ** 2) - (i + o + l) * d # 计算分子中的平方根部分,即 b^2-4ac sqrt_part = (b ** 2) - 4 * a * c # 计算两个解,一个是加号,一个是减号,即(-b±√(b^2-4ac))/(2a) d_d_plus = (-b + sqrt_part**(0.5)) / (2 * a) d_d_minus = (-b - sqrt_part**(0.5)) / (2 * a) # 返回两个解的元组 return (d_d_plus, d_d_minus) # 设置你想要的目标网络隐藏层数量 dest_hidden_layers = 2 # 获取对应的维数 dest_hidden_dim, _ = get_dest_dim(input_dim, output_dim, hidden_layers, dest_hidden_layers, hidden_dim) print(f"若将隐藏层网络层数改为: {dest_hidden_layers},则维数应当改为: {round(dest_hidden_dim)}",)

参考链接: 1. 图源自《动手学深度学习》 2. HW02 的 Sample code



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3