机器学习:如何计算CNN中的参数数量?

机器学习:如何计算CNN中的参数数量?

每位机器学习工程师/软件开发人员/对机器学习感兴趣的学生都曾参与过卷积神经网络,也被称为CNN。我们有一个普遍的理论,即如何训练网络来对图像进行分类。但是机器学习/神经网络的新手们完全不了解CNN究竟是如何学习参数的。

我们知道,在每个Conv Layer中,网络都试图了解基本模式。例如:在第一层,网络试图学习模式和边缘。在第二层,它试图了解形状/颜色和其他东西。称为特征层/全连接层的最后一层尝试对图像进行分类。

在我们了解参数之前,我们需要知道卷积网络中的一些基本概念,这对修改/重用源代码非常有帮助。

CNN网络中有各种各样的层。

输入层:所有输入图层都是读取图像。所以,这里没有参数学习。

卷积层:考虑采用“ l ”个特征映射作为输入并具有“ k ”个特征映射作为输出的卷积层。过滤器大小是“ n * m ” 。

机器学习:如何计算CNN中的参数数量?

在这里输入有l=32的特征映射作为输入,k=64特征映射作为输出,过滤器大小是n=3和m=3。重要的是要理解,我们不是简单地有一个3*3的过滤器,但是实际上,我们有3*3*32的过滤器,因为我们的输入有32个维度。作为第一个conv层的输出,我们学习了64个不同的3*3*32的过滤器,它们的总重量是“n*m*k*l”。然后有一个术语叫做对每个特征映射的偏差。所以,参数的总数是“(n*m*l+1)*k”。

池化层:没有可以在池中学习的参数。这一层只是用来减少图像尺寸大小。

全连接层:在此层中,所有输入单元对每个输出单元具有可分离的权重。对于“ n ”个输入和“ m ”个输出,权重的数量是“ n * m ”。此外,该层对于每个输出节点都有偏差,所以“ (n + 1)* m ”参数。

输出层:当“ n ”是输入的数量并且“ m ”是输出的数量时,该层是全连接层,因此是“ (n + 1)m ”参数。

CNN层最后的困难是第一个全连接层,我们不知道全连接层的维度,因为它是一个卷积层。要计算它,我们必须从输入图像的大小开始计算每个卷积层的大小。

在简单情况下,输出CNN层的大小计算为“ input_size-(filter_size-1) ”。例如,如果输入图像尺寸是(50,50)并且过滤器是(3,3),则(50-(3-1))= 48。但是,卷积网络的输入图像的大小不应小于输入,所以padding完成。

要计算padding,请输入input_size + 2 * padding_size-(filter_size-1)。对于以上情况,(50+(2 * 1) - (3-1)= 52-2 = 50)给出相同的输入大小。

如果我们想要在卷积期间显式地下采样图像,我们可以定义一个步幅。

最后,计算网络学习的参数数量(n * m * k + 1)* f

让我们使用Python代码看一下:

import keras

from keras.models import Model

from keras.layers import Input, concatenate, Conv2D, MaxPooling2D, Conv2DTranspose, Dropout

from keras.optimizers import Adam

from keras.callbacks import ModelCheckpoint

from keras.utils import plot_model

from keras import backend as K

K.set_image_data_format('channels_last')

img_row = 96

img_col = 96

smooth = 1

def create_conv_layer(f,stride,activationfn,padding,prevlayer,dropout):

conv = Conv2D(f,stride,activation=activationfn,padding=padding)(prevlayer)

conv = Dropout(dropout)(conv)

conv = Conv2D(f,stride,activation=activationfn,padding=padding)(conv)

return conv

def maxpooling_fn(prevlayer):

return MaxPooling2D(pool_size=(2,2))(prevlayer)

def concatenate_fn(f,kernal,stride,padding,src,dest):

return concatenate([Conv2DTranspose(f,kernal,strides=stride,padding=padding)(src),dest],axis=3)

def dice_coef(y_true,y_pred):

y_true_f = K.flatten(y_true)

y_pred_f = K.flatten(y_pred)

intersection = K.sum(y_true_f * y_pred_f)

return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)

def dice_coef_loss(y_true,y_pred):

return -dice_coef(y_true,y_pred)

def getnetwork():

inputs = Input((img_row,img_col,1))

conv1 = create_conv_layer(32,(3,3),'relu','same',inputs,0.2)

pool1 = maxpooling_fn(conv1)

conv2 = create_conv_layer(64,(3,3),'relu','same',pool1,0.2)

pool2 = maxpooling_fn(conv2)

conv3 = create_conv_layer(128,(3,3),'relu','same',pool2,0.3)

pool3 = maxpooling_fn(conv3)

conv4 = create_conv_layer(256,(3,3),'relu','same',pool3,0.3)

pool4 = maxpooling_fn(conv4)

conv5 = create_conv_layer(512,(3,3),'relu','same',pool4,0.3)

pool5 = maxpooling_fn(conv5)

up6 = concatenate_fn(256,(2,2),(2,2),'same',conv5,conv4)

conv6 = create_conv_layer(256,(3,3),'relu','same',up6,0.3)

up7 = concatenate_fn(128,(2,2),(2,2),'same',conv6,conv3)

conv7 = create_conv_layer(128,(3,3),'relu','same',up7,0.3)

up8 = concatenate_fn(64,(2,2),(2,2),'same',conv7,conv2)

conv8 = create_conv_layer(64,(3,3),'relu','same',up8,0.3)

up9 = concatenate_fn(32,(2,2),(2,2),'same',conv8,conv1)

conv9 = create_conv_layer(32,(3,3),'relu','same',up9,0.3)

conv10 = Conv2D(1,(1,1),activation='sigmoid')(conv9)

model = Model(inputs=[inputs],outputs=[conv10])

model.compile(optimizer=Adam(lr=0.00001),loss=dice_coef_loss,metrics=[dice_coef])

return model

model = getnetwork()

print(model.summary())

plot_model(model, to_file='model.png')

机器学习:如何计算CNN中的参数数量?

卷积网络模型体系结构

input_1(输入层)具有shape(None,96,96,1),参数为0.在整个程序中stride=1,kernel_size=2*2,padding=same。

Convolutional_1 : ((kernel_size)*stride+1)*filters) = 3*3*1+1*32 = 320参数。在第一层中,卷积层有32个过滤器。

Dropout_1:Dropout层什么都不做。它只是删除低于上述权重的节点。

Convolutional_2 :由于卷积_1已经学习了32个过滤器。因此,该层中可训练参数的数量为3 * 3 * 32 + 1 * 32 = 9248。

Max_pooling_2d:该图层用于减少输入图像的大小。这里使用的kernal_size =(2,2)。所以输入图像96减少到一半48。

Convolutional_3 : 3 * 3 * 32 + 1 * 64 = 18496

最后,所有的参数总结在一起。

总训练参数= 7,759,521可训练参数= 7,759,251不可训练参数= 0。

相关推荐