Py学习  »  机器学习算法

手动计算深度学习模型中的参数数量

AI研习社 • 4 年前 • 460 次点击  

本文为 AI 研习社编译的技术博客,原标题 :

Counting No. of Parameters in Deep Learning Models by Hand

作者 | Raimi Karim

翻译 | Snowdrop99         

校对 | 斯蒂芬·二狗子        审核 | 酱番梨       整理 | 立鱼王

原文链接:

https://towardsdatascience.com/counting-no-of-parameters-in-deep-learning-models-by-hand-8f1716241889

注:本文的相关链接请访问文末【阅读原文】



摄影:Andrik Langfield,来自Unsplash

为什么我们需要再次计算一个深度学习模型中的参数数量?我们没有那样去做。然而,当我们需要减少一个模型中的文件大小甚至是减少模型推理的时间时,我们知道模型量化前后的参数数量是派得上用场的。(请点击原文查阅深度学习的高效的方法和硬件的视频。)

计算深度学习模型中可训练参数的数量被认为是微不足道的,因为你的代码已经可以为你完成这些任务。但是我依然想在这里留下我的笔记以供我们偶尔参考。以下是我们将要运行的模型:

  1. 前馈神经网络 (FFNN)

  2. 循环神经网络(RNN)

  3. 卷积神经网络(CNN)

与此同时,我会用Keras的API创建一个模型,以便简单的原型设计和代码的整洁,因此我们在此快速import导入相关的对象:

from keras.layers import Input, Dense, SimpleRNN, LSTM, GRU, Conv2D
from keras.layers import Bidirectional
from keras.models import Model

建立模型后,使用model.count_params()来查看有多少参数是可训练的。


   1. FFNNs

  • i, 输入大小

  • h, 隐藏层的大小

  • o, 输出大小

对于一个隐藏层,

参数数量

=层间的连接+每层的偏差

=(i×h+h×o)+(h+o)

例1.1:输入大小为3,隐藏层大小为5,输出大小为2


图1.1:输入大小为3,隐藏层大小为5,输出大小为2的FFNN。图形反映了实际的单元数量。

  • i = 3

  • h = 5

  • o = 2

参数数量

=层间的连接+每层的偏差

=(3×5+5×2)+(5+2)

=32

 input = Input((None, 3))
 dense = Dense(5)(input)
output = Dense(2)(dense)
 model = Model(input, output)

例1.2:输入大小为50,隐藏层大小[100,1,100],输出大小为50

图1.2:3层隐藏层的FFNN。图形没有反映出实际的单元数量。

  • i = 50

  • h = 100, 1, 100

  • o = 50

参数数量

=层间的连接+每层的偏差

=(50×100+100×1+1×100+100×50)+(100+1+100+50)

=10,451

input = Input((None, 50))
dense = Dense(100)(input)
dense = Dense(1)(dense)
dense = Dense(100)(dense)
output = Dense(50)(dense)
model = Model(input, output)


   2. RNNs

  • g, 一个单元中的FFNNs的数量(RNN有1个,GRU有3个,LSTM有4个)

  • h, 隐藏单元的大小

  • i,输入的维度/大小 

因为每一个FFNN有h(h+i)+h个参数,则我们有

参数数量=g×[h(h+i)+h]

例2.1:LSTM有两个隐藏单元,输入维度为3.

图2.1:一个LSTM单元。

  • g = 4 (LSTM有4个FFNN)

  • h = 2

  • i = 3

参数数量 
= g × [h(h+i) + h]
= 4 × [2(2+3) + 2] 
= 48




    
input = Input((None, 3))
lstm = LSTM(2)(input)
model = Model(input, lstm)

例2.2:堆叠双向GRU有5个隐藏单元,输入大小为8(其输出是级联的)+LSTM有50个隐藏单元。


图2.2:一个堆叠RNN包含有BiGRU和LSTM层。该图形没有反映出实际的单元数。

双向GRU有5个隐藏层,输入大小为10,

  • g = 3 ( GRU有3个FFNN)

  • h = 5

  • i = 8

第一层的参数数量

= 2 × g × [h(h+i)  + h] (由于双向性,则第一项是2)

= 2 × 3 × [5(5+8) + 5]
= 420

LSTM有50个隐藏单元

  • g = 4 (LSTM有4个FFNN)

  • h = 50

  • i = 5+5 (双向GRU级联的输出;GRU的输出大小为5;隐藏单元数同为5)

第二层的参数数量
= g × [h(h+i)  + h]
= 4 × [50(50+10) + 50]
= 12,200

总的参数数量= 420 + 12,200 = 12,620

input = Input((None, 8))
layer1 = Bidirectional(GRU(5, return_sequences=True))(input)
layer2 = LSTM(50)(layer1)
model = Model(input, layer2)

merge_mode默认是串联的。


   CNNs

对于一层,

  • i, 输入映射的数量(或通道)no. of input maps (or channels)

  • f, 滤波器大小(仅仅是长度)filter size (just the length)

  • o, 输出映射的数量(或通道。这也由使用了多少滤波器来定义)

一个滤波器被应用于每一个输入映射。

参数数量
= weights + biases

= [ i × ( f × f ) × o] + o

例3.1:1×1滤波器的灰度图,输出3个通道


图3.1:使用2×2滤波器对灰度图像进行卷积以输出3个通道。 这里有15个参数--12个权重和3个偏差。

  • i = 1 (灰度图只有一个通道)

  • f = 2

  • o = 3

参数数量
= [ i × ( f × f ) × o] + o

= [1 × (2 × 2) × 3] + 3

= 15

input = Input((None, None, 1))
conv2d = Conv2D(kernel_size=2, filters=3)(input)
model = Model(input, conv2d)

例3.2:RGB图像有2×2滤波器,输出一个通道

每一个输入特征映射都有一个滤波器。产生的卷积按元素添加,并且向每个元素添加偏差项。 这给出了具有一个特征映射的输出。


 图3.2 :使用2×2滤波器对RGB图像进行卷积以输出一个通道 。这里有13个参数--12个权重和一个偏差。  

  • i = 3 (RGB图像有3个通道)

  • f = 2

  • o = 1

参数数量
= [i  × ( f × f ) × o] + o
= [3 × (2×2) × 1] + 1
= 13

input = Input((None, None, 3))
conv2d = Conv2D(kernel_size=2, filters=1)(input)
model = Model(input, conv2d)

例3.3:一张图像有2个通道,2×2滤波器和3通道的输出

每一个输入特征映射有3个滤波器(紫色,黄色,青色)。产生的卷积按元素添加,并且向每个元素添加偏差项。 这给出了具有3个特征映射的输出。


图3.1:对一个2通道的2×2滤波器的图像进行卷积以输出3个通道。这里有27个参数--24个权重和3个偏差。

  • i = 2

  • f = 2

  • o = 3

参数数量
= [i × ( f × f ) × o] + o
= [2 × (2×2) × 3] + 3
= 27

input = Input((None, None, 2))
conv2d = Conv2D(kernel_size=2, filters=3)(input)
model = Model(input, conv2d)

目前为止就这样了! 如果您有任何反馈,请在下面留言!

想要继续查看该篇文章相关链接和参考文献?

点击底部【阅读原文】即可访问:

https://ai.yanxishe.com/page/TextTranslation/1602

点击阅读原文,查看本文更多内容↙

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/31198
 
460 次点击