機器學習:如何計算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。


分享到:


相關文章: