如何计算神经网络的参数量以及创建多隐藏层网络(总参数量接近) |
您所在的位置:网站首页 › inq的计算公式 › 如何计算神经网络的参数量以及创建多隐藏层网络(总参数量接近) |
计算神经网络的参数量 对于全连接层来说,其单层的参数量为 (输入维度 + 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 |