<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【深度學(xué)習(xí)】一文弄懂CNN及圖像識別(Python)

          共 8296字,需瀏覽 17分鐘

           ·

          2021-12-14 09:09

          一、卷積神經(jīng)網(wǎng)絡(luò)簡介

          卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks, CNN)是一類包含卷積計(jì)算的前饋神經(jīng)網(wǎng)絡(luò),是基于圖像任務(wù)的平移不變性(圖像識別的對象在不同位置有相同的含義)設(shè)計(jì)的,擅長應(yīng)用于圖像處理等任務(wù)。在圖像處理中,圖像數(shù)據(jù)具有非常高的維數(shù)(高維的RGB矩陣表示),因此訓(xùn)練一個(gè)標(biāo)準(zhǔn)的前饋網(wǎng)絡(luò)來識別圖像將需要成千上萬的輸入神經(jīng)元,除了顯而易見的高計(jì)算量,還可能導(dǎo)致許多與神經(jīng)網(wǎng)絡(luò)中的維數(shù)災(zāi)難相關(guān)的問題。

          對于高維圖像數(shù)據(jù),卷積神經(jīng)網(wǎng)絡(luò)利用了卷積和池化層,能夠高效提取圖像的重要“特征”,再通過后面的全連接層處理“壓縮的圖像信息”及輸出結(jié)果。對比標(biāo)準(zhǔn)的全連接網(wǎng)絡(luò),卷積神經(jīng)網(wǎng)絡(luò)的模型參數(shù)大大減少了。

          二、卷積神經(jīng)網(wǎng)絡(luò)的“卷積”?

          2.1 卷積運(yùn)算的原理

          在信號處理、圖像處理和其它工程/科學(xué)領(lǐng)域,卷積都是一種使用廣泛的技術(shù),卷積神經(jīng)網(wǎng)絡(luò)(CNN)這種模型架構(gòu)就得名于卷積計(jì)算。但是,深度學(xué)習(xí)領(lǐng)域的“卷積”本質(zhì)上是信號/圖像處理領(lǐng)域內(nèi)的互相關(guān)(cross-correlation),互相關(guān)與卷積實(shí)際上還是有些差異的。卷積是分析數(shù)學(xué)中一種重要的運(yùn)算。簡單定義f , g 是可積分的函數(shù),兩者的卷積運(yùn)算如下:

          其定義是兩個(gè)函數(shù)中一個(gè)函數(shù)(g)經(jīng)過反轉(zhuǎn)和位移后再相乘得到的積的積分。如下圖,函數(shù) g 是過濾器。它被反轉(zhuǎn)后再沿水平軸滑動(dòng)。在每一個(gè)位置,我們都計(jì)算 f 和反轉(zhuǎn)后的 g 之間相交區(qū)域的面積。這個(gè)相交區(qū)域的面積就是特定位置出的卷積值。

          互相關(guān)是兩個(gè)函數(shù)之間的滑動(dòng)點(diǎn)積或滑動(dòng)內(nèi)積。互相關(guān)中的過濾器不經(jīng)過反轉(zhuǎn),而是直接滑過函數(shù) f,f 與 g 之間的交叉區(qū)域即是互相關(guān)。

          下圖展示了卷積與互相關(guān)運(yùn)算過程,相交區(qū)域的面積變化的差異:

          在卷積神經(jīng)網(wǎng)絡(luò)中,卷積中的過濾器不經(jīng)過反轉(zhuǎn)。嚴(yán)格來說,這是離散形式的互相關(guān)運(yùn)算,本質(zhì)上是執(zhí)行逐元素乘法和求和。但兩者的效果是一致,因?yàn)檫^濾器的權(quán)重參數(shù)是在訓(xùn)練階段學(xué)習(xí)到的,經(jīng)過訓(xùn)練后,學(xué)習(xí)得到的過濾器看起來就會像是反轉(zhuǎn)后的函數(shù)。

          2.2 卷積運(yùn)算的作用

          CNN通過設(shè)計(jì)的卷積核(convolution filter,也稱為kernel)與圖片做卷積運(yùn)算(平移卷積核去逐步做乘積并求和)。

          如下示例設(shè)計(jì)一個(gè)(特定參數(shù))的3×3的卷積核:

          讓它去跟圖片做卷積,卷積的具體過程是:

            1. 用這個(gè)卷積核去覆蓋原始圖片;

            2. 覆蓋一塊跟卷積核一樣大的區(qū)域之后,對應(yīng)元素相乘,然后求和;

            3. 計(jì)算一個(gè)區(qū)域之后,就向其他區(qū)域挪動(dòng)(假設(shè)步長是1),繼續(xù)計(jì)算;

            4. 直到把原圖片的每一個(gè)角落都覆蓋到為止;

          可以發(fā)現(xiàn),通過特定的filter,讓它去跟圖片做卷積,就可以提取出圖片中的某些特征,比如邊界特征。

          進(jìn)一步的,我們可以借助龐大的數(shù)據(jù),足夠深的神經(jīng)網(wǎng)絡(luò),使用反向傳播算法讓機(jī)器去自動(dòng)學(xué)習(xí)這些卷積核參數(shù),不同參數(shù)卷積核提取特征也是不一樣的,就能夠提取出局部的、更深層次和更全局的特征以應(yīng)用于決策。

          卷積運(yùn)算的本質(zhì)性總結(jié):過濾器(g)對圖片(f)執(zhí)行逐步的乘法并求和,以提取特征的過程。卷積過程可視化可訪問:https://poloclub.github.io/cnn-explainer/ ? 或 ? https://github.com/vdumoulin/conv_arithmetic

          三、卷積神經(jīng)網(wǎng)絡(luò)

          卷積神經(jīng)網(wǎng)絡(luò)通常由3個(gè)部分構(gòu)成:卷積層,池化層,全連接層。簡單來說,卷積層負(fù)責(zé)提取圖像中的局部及全局特征;池化層用來大幅降低參數(shù)量級(降維);全連接層用于處理“壓縮的圖像信息”并輸出結(jié)果。

          3.1 卷積層(CONV)

          3.1.1 卷積層基本屬性

          卷積層主要功能是動(dòng)態(tài)地提取圖像特征,由濾波器filters和激活函數(shù)構(gòu)成。一般要設(shè)置的超參數(shù)包括filters的數(shù)量、大小、步長,激活函數(shù)類型,以及padding是“valid”還是“same”。

          • 卷積核大小(Kernel):直觀理解就是一個(gè)濾波矩陣,普遍使用的卷積核大小為3×3、5×5等。在達(dá)到相同感受野的情況下,卷積核越小,所需要的參數(shù)和計(jì)算量越小。卷積核大小必須大于1才有提升感受野的作用,而大小為偶數(shù)的卷積核即使對稱地加padding也不能保證輸入feature map尺寸和輸出feature map尺寸不變(假設(shè)n為輸入寬度,d為padding個(gè)數(shù),m為卷積核寬度,在步長為1的情況下,如果保持輸出的寬度仍為n,公式,n+2d-m+1=n,得出m=2d+1,需要是奇數(shù)),所以一般都用3作為卷積核大小。

          • 卷積核數(shù)目:主要還是根據(jù)實(shí)際情況調(diào)整, 一般都是取2的整數(shù)次方,數(shù)目越多計(jì)算量越大,相應(yīng)模型擬合能力越強(qiáng)。

          • 步長(Stride):卷積核遍歷特征圖時(shí)每步移動(dòng)的像素,如步長為1則每次移動(dòng)1個(gè)像素,步長為2則每次移動(dòng)2個(gè)像素(即跳過1個(gè)像素),以此類推。步長越小,提取的特征會更精細(xì)。

          • 填充(Padding):處理特征圖邊界的方式,一般有兩種,一種是“valid”,對邊界外完全不填充,只對輸入像素執(zhí)行卷積操作,這樣會使輸出特征圖像尺寸變得更小,且邊緣信息容易丟失;另一種是還是“same”,對邊界外進(jìn)行填充(一般填充為0),再執(zhí)行卷積操作,這樣可使輸出特征圖的尺寸與輸入特征圖的尺寸一致,邊緣信息也可以多次計(jì)算。

          • 通道(Channel):卷積層的通道數(shù)(層數(shù))。如彩色圖像一般都是RGB三個(gè)通道(channel)。

          • 激活函數(shù):主要還是根據(jù)實(shí)際驗(yàn)證,通常選擇Relu。

          另外的,卷積的類型除了標(biāo)準(zhǔn)卷積,還演變出了反卷積、可分離卷積、分組卷積等各種類型,可以自行驗(yàn)證。

          3.1.2 卷積層的特點(diǎn)

          通過卷積運(yùn)算的介紹,可以發(fā)現(xiàn)卷積層有兩個(gè)主要特點(diǎn):局部連接(稀疏連接)和權(quán)值共享。

          • 局部連接,就是卷積層的節(jié)點(diǎn)僅僅和其前一層的部分節(jié)點(diǎn)相連接,只用來學(xué)習(xí)局部區(qū)域特征。(局部連接感知結(jié)構(gòu)的理念來源于動(dòng)物視覺的皮層結(jié)構(gòu),其指的是動(dòng)物視覺的神經(jīng)元在感知外界物體的過程中起作用的只有一部分神經(jīng)元。)

          • 權(quán)值共享,同一卷積核會和輸入圖片的不同區(qū)域作卷積,來檢測相同的特征,卷積核上面的權(quán)重參數(shù)是空間共享的,使得參數(shù)量大大減少。

          由于局部連接(稀疏連接)和權(quán)值共享的特點(diǎn),使得CNN具有仿射的不變性(平移、縮放等線性變換)

          3.2 池化層(Pooling)

          池化層可對提取到的特征信息進(jìn)行降維,一方面使特征圖變小,簡化網(wǎng)絡(luò)計(jì)算復(fù)雜度;另一方面進(jìn)行特征壓縮,提取主要特征,增加平移不變性,減少過擬合風(fēng)險(xiǎn)。但其實(shí)池化更多程度上是一種計(jì)算性能的一個(gè)妥協(xié),強(qiáng)硬地壓縮特征的同時(shí)也損失了一部分信息,所以現(xiàn)在的網(wǎng)絡(luò)比較少用池化層或者使用優(yōu)化后的如SoftPool。

          池化層設(shè)定的超參數(shù),包括池化層的類型是Max還是Average(Average對背景保留更好,Max對紋理提取更好),窗口大小以及步長等。如下的MaxPooling,采用了一個(gè)2×2的窗口,并取步長stride=2,提取出各個(gè)窗口的max值特征(AveragePooling就是平均值):

          3.3 全連接層(FC)

          在經(jīng)過數(shù)次卷積和池化之后,我們最后會先將多維的圖像數(shù)據(jù)進(jìn)行壓縮“扁平化”, 也就是把 (height,width,channel) 的數(shù)據(jù)壓縮成長度為 height × width × channel 的一維數(shù)組,然后再與全連接層連接(這也就是傳統(tǒng)全連接網(wǎng)絡(luò)層,每一個(gè)單元都和前一層的每一個(gè)單元相連接,需要設(shè)定的超參數(shù)主要是神經(jīng)元的數(shù)量,以及激活函數(shù)類型),通過全連接層處理“壓縮的圖像信息”并輸出結(jié)果。

          3.4 ?示例:經(jīng)典CNN的構(gòu)建(Lenet-5)

          LeNet-5由Yann LeCun設(shè)計(jì)于 1998年,是最早的卷積神經(jīng)網(wǎng)絡(luò)之一。它是針對灰度圖進(jìn)行訓(xùn)練的,輸入圖像大小為32321,不包含輸入層的情況下共有7層。下面逐層介紹LeNet-5的結(jié)構(gòu):

          • 1、C1-卷積層

          第一層是卷積層,用于過濾噪音,提取關(guān)鍵特征。使用5 * 5大小的過濾器6個(gè),步長s = 1,padding = 0。

          • 2、S2-采樣層(平均池化層)

          第二層是平均池化層,利用了圖像局部相關(guān)性的原理,對圖像進(jìn)行子抽樣,可以減少數(shù)據(jù)處理量同時(shí)保留有用信息,降低網(wǎng)絡(luò)訓(xùn)練參數(shù)及模型的過擬合程度。使用2 * 2大小的過濾器,步長s = 2,padding = 0。池化層只有一組超參數(shù)pool_size 和 步長strides,沒有需要學(xué)習(xí)的模型參數(shù)

          • 3、C3-卷積層

          第三層使用5 * 5大小的過濾器16個(gè),步長s = 1,padding = 0。

          • 4、S4-下采樣層(平均池化層)

          第四層使用2 * 2大小的過濾器,步長s = 2,padding = 0。沒有需要學(xué)習(xí)的參數(shù)。

          • 5、C5-卷積層

          第五層是卷積層,有120個(gè)5 * 5 的單元,步長s = 1,padding = 0。

          • 6、F6-全連接層

          有84個(gè)單元。每個(gè)單元與F5層的全部120個(gè)單元之間進(jìn)行全連接。

          • 7、Output-輸出層

          Output層也是全連接層,采用RBF網(wǎng)絡(luò)的連接方式(現(xiàn)在主要由Softmax取代,如下示例代碼),共有10個(gè)節(jié)點(diǎn),分別代表數(shù)字0到9(因?yàn)長enet用于輸出識別數(shù)字的),如果節(jié)點(diǎn)i的輸出值為0,則網(wǎng)絡(luò)識別的結(jié)果是數(shù)字i。

          如下Keras復(fù)現(xiàn)Lenet-5:

          from?keras.models?import?Sequential
          from?keras?import?layers?

          le_model?=?keras.Sequential()
          le_model.add(layers.Conv2D(6,?kernel_size=(5,?5),?strides=(1,?1),?activation='tanh',?input_shape=(32,32,1),?padding="valid"))
          le_model.add(layers.AveragePooling2D(pool_size=(2,?2),?strides=(2,?2),?padding='valid'))
          le_model.add(layers.Conv2D(16,?kernel_size=(5,?5),?strides=(1,?1),?activation='tanh',?padding='valid'))
          le_model.add(layers.AveragePooling2D(pool_size=(2,?2),?strides=(2,?2),?padding='valid'))
          le_model.add(layers.Conv2D(120,?kernel_size=(5,?5),?strides=(1,?1),?activation='tanh',?padding='valid'))
          le_model.add(layers.Flatten())
          le_model.add(layers.Dense(84,?activation='tanh'))
          le_model.add(layers.Dense(10,?activation='softmax'))

          四、CNN圖像分類-keras?

          以keras實(shí)現(xiàn)經(jīng)典的CIFAR10圖像數(shù)據(jù)集的分類為例,代碼:https://github.com/aialgorithm/Blog

          • 訓(xùn)練集輸入數(shù)據(jù)的樣式為:(50000, 32, 32, 3)對應(yīng) (樣本數(shù), 圖像高度, 寬度, RGB彩色圖像通道為3)
          from?keras.datasets?import?cifar10
          from?keras.preprocessing.image?import?ImageDataGenerator
          from?keras.models?import?Sequential
          from?keras.layers?import?Dense,?Dropout,?Activation,?Flatten
          from?keras.layers?import?Conv2D,?MaxPooling2D
          import?keras
          import?os

          #?數(shù)據(jù),切分為訓(xùn)練和測試集
          (x_train,?y_train),?(x_test,?y_test)?=?cifar10.load_data()
          print('x_train?shape:',?x_train.shape)
          print(x_train.shape[0],?'train?samples')
          print(x_test.shape[0],?'test?samples')
          • 展示數(shù)據(jù)集,共有10類圖像:
          #?展示數(shù)據(jù)集
          import?matplotlib.pyplot?as?plt
          class_names?=?['airplane',?'automobile',?'bird',?'cat',?'deer',
          ???????????????'dog',?'frog',?'horse',?'ship',?'truck']

          plt.figure(figsize=(10,10))
          for?i?in?range(25):
          ????plt.subplot(5,5,i+1)
          ????plt.xticks([])
          ????plt.yticks([])
          ????plt.grid(False)
          ????plt.imshow(x_train[i])
          ????#?The?CIFAR?labels?happen?to?be?arrays,?
          ????#?which?is?why?you?need?the?extra?index
          ????plt.xlabel(class_names[y_train[i][0]])
          plt.show()
          • 數(shù)據(jù)及標(biāo)簽預(yù)處理:
          #?將標(biāo)簽向量轉(zhuǎn)換為二值矩陣。
          num_classes?=?10??#圖像數(shù)據(jù)有10個(gè)實(shí)際標(biāo)簽類別
          y_train?=?keras.utils.to_categorical(y_train,?num_classes)
          y_test?=?keras.utils.to_categorical(y_test,?num_classes)

          print(y_train.shape,?'ytrain')

          #?圖像數(shù)據(jù)歸一化
          x_train?=?x_train.astype('float32')
          x_test?=?x_test.astype('float32')
          x_train?/=?255
          x_test?/=?255
          • 構(gòu)造卷積神經(jīng)網(wǎng)絡(luò): 輸入層->多組卷積及池化層->全連接網(wǎng)絡(luò)->softmax多分類輸出層。(如下圖部分網(wǎng)絡(luò)結(jié)構(gòu))
          #?構(gòu)造卷積神經(jīng)網(wǎng)絡(luò)
          model?=?Sequential()

          #?圖像輸入形狀(32,?32,?3)?對應(yīng)(image_height,?image_width,?color_channels)?
          model.add(Conv2D(32,?(3,?3),?padding='same',
          ?????????????????input_shape=(32,?32,?3)))
          model.add(Activation('relu'))
          model.add(Conv2D(32,?(3,?3)))
          model.add(Activation('relu'))
          model.add(MaxPooling2D(pool_size=(2,?2)))
          model.add(Dropout(0.25))

          #?卷積、池化層輸出都是一個(gè)三維的(height,?width,?channels)
          #?越深的層中,寬度和高度都會收縮
          model.add(Conv2D(64,?(3,?3),?padding='same'))
          model.add(Activation('relu'))
          model.add(Conv2D(64,?(3,?3)))
          model.add(Activation('relu'))
          model.add(MaxPooling2D(pool_size=(2,?2)))
          model.add(Dropout(0.25))

          #??3?維展平為?1?維?,輸入全連接層
          model.add(Flatten())
          model.add(Dense(512))
          model.add(Activation('relu'))
          model.add(Dropout(0.5))
          model.add(Dense(num_classes))???#?CIFAR數(shù)據(jù)有?10?個(gè)輸出類,以softmax輸出多分類
          model.add(Activation('softmax'))?
          • 模型編譯:設(shè)定RMSprop 優(yōu)化算法;設(shè)定分類損失函數(shù).
          #?初始化?RMSprop?優(yōu)化器
          opt?=?keras.optimizers.rmsprop(lr=0.001,?decay=1e-6)

          #?模型編譯:設(shè)定RMSprop 優(yōu)化算法;設(shè)定分類損失函數(shù);
          model.compile(loss='categorical_crossentropy',
          ??????????????optimizer=opt,
          ??????????????metrics=['accuracy'])

          • 模型訓(xùn)練: 簡單驗(yàn)證5個(gè)epochs
          batch_size?=?64
          epochs?=?5??

          history?=?model.fit(x_train,?y_train,
          ??????????????batch_size=batch_size,
          ??????????????epochs=epochs,
          ??????????????validation_data=(x_test,?y_test),
          ??????????????shuffle=True)
          • 模型評估:測試集accuracy: 0.716,可見訓(xùn)練/測試集整體的準(zhǔn)確率都不太高(欠擬合),可以增加epoch數(shù)、模型調(diào)優(yōu)驗(yàn)證效果。

          附 卷積神經(jīng)網(wǎng)絡(luò)優(yōu)化方法(tricks):

          參數(shù)優(yōu)化:可以用隨機(jī)搜索、貝葉斯優(yōu)化。推薦分布式超參數(shù)調(diào)試框架Keras Tuner包括了常用的優(yōu)化方法。

          數(shù)據(jù)層面:數(shù)據(jù)增強(qiáng)廣泛用于圖像任務(wù),效果提升大。常用有圖像樣本變換、mixup等。更多優(yōu)化方法具體可見:https://arxiv.org/abs/1812.01187

          #?保存模型和權(quán)重
          num_predictions?=?20
          save_dir?=?os.path.join(os.getcwd(),?'saved_models')
          model_name?=?'keras_cifar10_trained_model.h5'

          if?not?os.path.isdir(save_dir):
          ????os.makedirs(save_dir)
          model_path?=?os.path.join(save_dir,?model_name)
          model.save(model_path)
          print('Saved?trained?model?at?%s?'?%?model_path)

          #?評估訓(xùn)練模型
          scores?=?model.evaluate(x_test,?y_test,?verbose=1)
          print('Test?loss:',?scores[0])
          print('Test?accuracy:',?scores[1])

          plt.plot(history.history['accuracy'],?label='accuracy')
          plt.plot(history.history['val_accuracy'],?label?=?'val_accuracy')
          plt.xlabel('Epoch')
          plt.ylabel('Accuracy')
          plt.ylim([0.5,?1])
          plt.legend(loc='lower?right')
          plt.show()
          - END -

          文章首發(fā)公眾號“算法進(jìn)階”,文末閱讀原文可訪問文章相關(guān)代碼


          往期精彩回顧




          站qq群955171419,加入微信群請掃碼:
          瀏覽 51
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人片无码免费 | 亚洲国产中文字幕 | 一级特黄特色的免费大片 | 日日夜夜久久视频久久视频 | 九九九无码 |