<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Python人工智能 | 十八.Keras搭建卷積神經網絡及CNN原理詳解

    VSole2022-08-17 12:34:41

    一.卷積神經網絡原理

    1.什么是CNN

    一般的神經網絡在理解圖片信息的時候還是有不足之處,這時卷積神經網絡就成為了計算機處理圖片的助推器。卷積神經網絡的英文是Convolutional Neural Network,簡稱CNN。它通常應用于圖像識別和語音識等領域,并能給出更優秀的結果,也可以應用于視頻分析、機器翻譯、自然語言處理、藥物發現等領域。著名的阿爾法狗讓計算機看懂圍棋就是基于卷積神經網絡的。

    神經網絡是由很多神經層組成,每一層神經層中存在很多神經元,這些神經元是識別事物的關鍵,當輸入是圖片時,其實就是一堆數字。

    首先,卷積是什么意思呢?卷積是指不在對每個像素做處理,而是對圖片區域進行處理,這種做法加強了圖片的連續性,看到的是一個圖形而不是一個點,也加深了神經網絡對圖片的理解。

    卷積神經網絡批量過濾器,持續不斷在圖片上滾動搜集信息,每一次搜索都是一小塊信息,整理這一小塊信息之后得到邊緣信息。比如第一次得出眼睛鼻子輪廓等,再經過一次過濾,將臉部信息總結出來,再將這些信息放到全神經網絡中進行訓練,反復掃描最終得出的分類結果。如下圖所示,貓的一張照片需要轉換為數學的形式,這里采用長寬高存儲,其中黑白照片的高度為1,彩色照片的高度為3(RGB)。

    過濾器搜集這些信息,將得到一個更小的圖片,再經過壓縮增高信息嵌入到普通神經層上,最終得到分類的結果,這個過程即是卷積。Convnets是一種在空間上共享參數的神經網絡,如下圖所示,它將一張RGB圖片進行壓縮增高,得到一個很長的結果。

    近幾年神經網絡飛速發展,其中一個很重要的原因就是CNN卷積神經網絡的提出,這也是計算機視覺處理的飛躍提升。關于TensorFlow中的CNN,Google公司也出了一個非常精彩的視頻教程,也推薦大家去學習。

    • Google官方卷積神經網絡介紹視頻 - 優達學城

    2.CNN原理

    本文主要講解如何去應用CNN,下面我們先簡單看看CNN是如何處理信息的。這里參考Google官方視頻介紹,強烈推薦大家學習。

    假設你有一張小貓咪的照片,如下圖所示,它可以被表示為一個博餅,它有寬度(width)和高度(height),并且由于天然存在紅綠藍三色,它還擁有RGB厚度(depth),此時你的輸入深度為3。

    假設我們現在拿出圖片的一小塊,運行一個具有K個輸出的小神經網絡,像圖中一樣把輸出表示為垂直的一小列。

    在不改變權重的情況下,通過小神經網絡滑動掃遍整個圖片,就像我們拿著刷子刷墻一樣水平垂直的滑動。

    此時,輸出端畫出了另一幅圖像,如下圖中紅色區域所示。它與之前的寬度和高度不同,更重要的是它跟之前的深度不同,而不是僅僅只有紅綠藍,現在你得到了K個顏色通道,這種操作稱為——卷積。

    如果你的塊大小是整張圖片,那它跟普通的神經網絡層沒有任何區別,正是由于我們使用了小塊,我們有很多小塊在空間中共享較少的權重。卷積不在對每個像素做處理,而是對圖片區域進行處理,這種做法加強了圖片的連續性,也加深了神經網絡對圖片的理解。

    一個卷積網絡是組成深度網絡的基礎,我們將使用數層卷積而不是數層的矩陣相乘。如下圖所示,讓它形成金字塔形狀,金字塔底是一個非常大而淺的圖片,僅包括紅綠藍,通過卷積操作逐漸擠壓空間的維度,同時不斷增加深度,使深度信息基本上可以表示出復雜的語義。同時,你可以在金字塔的頂端實現一個分類器,所有空間信息都被壓縮成一個標識,只有把圖片映射到不同類的信息保留,這就是CNN的總體思想。

    上圖的具體流程如下:

    • 首先,這是有一張彩色圖片,它包括RGB三原色分量,圖像的長和寬為256*256,三個層面分別對應紅(R)、綠(G)、藍(B)三個圖層,也可以看作像素點的厚度。
    • 其次,CNN將圖片的長度和寬度進行壓縮,變成12812816的方塊,壓縮的方法是把圖片的長度和寬度壓小,從而增高厚度。
    • 再次,繼續壓縮至646464,直至3232256,此時它變成了一個很厚的長條方塊,我們這里稱之為分類器Classifier。該分類器能夠將我們的分類結果進行預測,MNIST手寫體數據集預測結果是10個數字,比如[0,0,0,1,0,0,0,0,0,0]表示預測的結果是數字3,Classifier在這里就相當于這10個序列。
    • 最后,CNN通過不斷壓縮圖片的長度和寬度,增加厚度,最終會變成了一個很厚的分類器,從而進行分類預測。

    如果你想實現它,必須還要正確實現很多細節。此時,你已經接觸到了塊和深度的概念,塊(PATCH)有時也叫做核(KERNEL),如下圖所示,你堆棧的每個薄餅都被叫做特征圖(Feature Map),這里把三個特性映射到K個特征圖中,PATCH/KERNEL的功能是從圖片中抽離一小部分進行分析,每次抽離的小部分都會變成一個長度、一個寬度、K個厚度的數列。

    另一個你需要知道的概念是——步幅(STRIDE)。它是當你移動濾波器或抽離時平移的像素的數量,每一次跨多少步去抽離圖片中的像素點。

    如果步幅STRIDE等于1,表示每跨1個像素點抽離一次,得到的尺寸基本上和輸入相同。

    如果步幅STRIDE等于2,表示每次跨2個像素點抽離,意味著變為一半的尺寸。它收集到的信息就會被縮減,圖片的長度和寬度被壓縮了,壓縮合并成更小的一塊立方體。

    壓縮完之后再合并成一個立方體,它就是更小的一塊立方體,包含了圖片中的所有信息。

    抽離圖片信息的方式稱為PADDING(填充),一般分為兩種:

    • VALID PADDING: 抽出來這層比原先那層圖片寬和長裁剪了一點,抽取的內容全部是圖片內的。
    • SAME PADDING: 抽離出的那層與之前的圖片一樣的長和寬,抽取的內容部分再圖片外,圖片外的值用0來填充。

    研究發現,卷積過程會丟失一些信息,比如現在想跨2步去抽離原始圖片的重要信息,形成長寬更小的圖片,該過程中可能會丟失重要的圖片信息。為了解決這個問題,通過POOLING(持化)可以避免。其方法是:卷積時不再壓縮長寬,盡量保證更多信息,壓縮工作交給POOLING。經過圖片到卷積,持化處理卷積信息,再卷積再持化,將結果傳入兩層全連接神經層,最終通過分類器識別貓或狗。

    總結:整個CNN從下往上依次經歷“圖片->卷積->持化->卷積->持化->結果傳入兩層全連接神經層->分類器”的過程,最終實現一個CNN的分類處理。

    • IMAGE 圖片
    • CONVOLUTION 圖層
    • MAX POOLING 更好地保存原圖片的信息
    • CONVOLUTION 圖層
    • MAX POOLING 更好地保存原圖片的信息
    • FULLY CONNECTED 神經網絡隱藏層
    • FULLY CONNECTED 神經網絡隱藏層
    • CLASSIFIER 分類器

    寫到這里,CNN的基本原理講解完畢,希望大家對CNN有一個初步的理解。同時建議大家處理神經網絡時,先用一般的神經網絡去訓練它,如果得到的結果非常好,就沒必要去使用CNN,因為CNN結構比較復雜。

    二.Keras實現CNN

    接著我們講解如何在Keras代碼中編寫CNN。

    1.代碼實現

    第一步,打開Anaconda,然后選擇已經搭建好的“tensorflow”環境,運行Spyder。

    第二步,導入擴展包。

    import numpy as npfrom keras.datasets import mnistfrom keras.utils import np_utilsfrom keras.models import Sequentialfrom keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Flattenfrom keras.optimizers import Adam
    

    第三步,載入MNIST數據及預處理。

    • X_train.reshape(-1, 1, 28, 28) / 255
    • 將每個像素點進行標準化處理,從0-255轉換成0-1的范圍。
    • np_utils.to_categorical(y_train, nb_classes=10)
    • 調用up_utils將類標轉換成10個長度的值,如果數字是3,則會在對應的地方標記為1,其他地方標記為0,即{0,0,0,1,0,0,0,0,0,0}。

    由于MNIST數據集是Keras或TensorFlow的示例數據,所以我們只需要下面一行代碼,即可實現數據集的讀取工作。如果數據集不存在它會在線下載,如果數據集已經被下載,它會被直接調用。

    # 下載MNIST數據 # training X shape (60000, 28x28), Y shape (60000, )# test X shape (10000, 28x28), Y shape (10000, )(X_train, y_train), (X_test, y_test) = mnist.load_data()
    # 數據預處理# 參數-1表示樣例的個數 1表示灰度照片(3對應RGB彩色照片) 28*28表示像素長度和寬度X_train = X_train.reshape(-1, 1, 28, 28) / 255   # normalizeX_test = X_test.reshape(-1, 1, 28, 28) / 255     # normalize
    # 將類向量轉化為類矩陣  數字 5 轉換為 0 0 0 0 0 1 0 0 0 0 矩陣y_train = np_utils.to_categorical(y_train, num_classes=10)y_test = np_utils.to_categorical(y_test, num_classes=10)
    

    第四步,創建神經網絡第一層及池化層。

    小方塊的長度和寬度是5,in size為1是圖片的厚度,輸出的高度是32。conv1輸出的大小為28 * 28 * 32,因為padding采用“SAME”的形式,conv1輸出值為32,故厚度也為32,長度和寬度相同為28。而由于POOLING處理設置的strides步長為2,故其輸出大小也有變化,其結果為14 * 14 * 32。

    核心代碼如下。卷積層利用Convolution2D,池化層利用MaxPooling2D。

    • nb_filters表示濾波器,其值為32,每個濾波器掃描之后都會產生一個特征
    • nb_row表示寬度5
    • nb_col表示高度5
    • border_mode表示過濾,采用same方式(Padding method)
    • input_shape表示輸入形狀,1個高度,28個長度,28個寬度
    #---------------------------創建第一層神經網絡---------------------------# 創建CNNmodel = Sequential()
    # Conv layer 1 output shape (32, 28, 28)# 第一層利用Convolution2D卷積 model.add(Convolution2D(    filters = 32,                   # 32個濾波器     nb_row = 5,                     # 寬度     nb_col = 5,                     # 高度    border_mode = 'same',           # Padding method    input_shape = (1, 28, 28),      # 輸入形狀 channels height width))# 增加神經網絡激活函數model.add(Activation('relu'))
    # Pooling layer 1 (max pooling) output shape (32, 14, 14)# 池化層利用MaxPooling2Dmodel.add(MaxPooling2D(    pool_size = (2, 2),             # 向下取樣    strides = (2,2),                # 取樣跳2個    padding='same',                 # Padding method))
    

    為了防止跨度太大,丟失東西太多,這里添加了POOLING處理,strides值為2,減小跨度。最終得到結果的形狀都一樣,但它能保留更多的圖片信息。

    第五步,創建第二層神經網絡及取樣。

    conv2定義的patch為5*5,傳入大小為32,傳出大小為64,不斷將其變厚,類似于下圖所示。圖片最早的厚度為1(MNIST數據集是黑白圖片,如果是彩色則為3),接著第一層厚度變成32,第三層厚度增長為64。

    此時conv2的輸出結果為14 * 14 * 64,第二層POOLING處理會繼續縮小一半,pool2輸出結果為7 * 7 * 64,高度不變。

    # Conv layer 2 output shape (64, 14, 14)model.add(Convolution2D(64, 5, 5, border_mode='same'))model.add(Activation('relu'))
    # Pooling layer 2 (max pooling) output shape (64, 7, 7)model.add(MaxPooling2D(pool_size = (2, 2), border_mode='same'))
    

    第六步,構建全連接層。

    輸入值為conv2 layer的輸出值7 * 7 * 64,輸出值為1024,讓其變得更高更厚。接著第二個全連接層輸出結果為分類的10個類標。

    # Fully connected layer 1 input shape (64 * 7 * 7) = (3136), output shape (1024)model.add(Flatten())                  # 將三維層拉直model.add(Dense(1024))                # 全連接層model.add(Activation('relu'))         # 激勵函數
    # Fully connected layer 2 to shape (10) for 10 classesmodel.add(Dense(10))                  # 輸出10個單位 model.add(Activation('softmax'))      # 分類激勵函數
    

    這里簡單總結下神經網絡:

    • conv1 layer:經過卷積和POOLING處理,最終輸出14 * 14 * 32
    • conv2 layer:經過卷積和POOLING處理,最終輸出7 * 7 * 64
    • func1 layer:平常使用的神經網絡,輸入7 * 7 * 64,最終輸出1024
    • func2 layer:平常使用的神經網絡,輸入1024,最終輸出10,代表10個數字,即為prediction

    第七步,定義優化器并激活神經網絡,接著進行訓練預測,并輸出相應結果。

    # 優化器 optimizeradam = Adam(lr=1e-4)
    # We add metrics to get more results you want to see# 激活神經網絡model.compile(optimizer=adam,                      # 加速神經網絡              loss='categorical_crossentropy',     # 損失函數              metrics=['accuracy'])                # 計算誤差或準確率
    print('Training')model.fit(X_train, y_train, epochs=1, batch_size=64,)  # 訓練次數及每批訓練大小
    print('Testing')loss, accuracy = model.evaluate(X_test, y_test)
    print('\ntest loss: ', loss)print('\ntest accuracy: ', accuracy)
    

    2.完整代碼

    # -*- coding: utf-8 -*-"""Created on Wed Feb 19 19:47:37 2020@author: xiuzhang Eastmount CSDNWuhan Fighting!"""import numpy as npfrom keras.datasets import mnistfrom keras.utils import np_utilsfrom keras.models import Sequentialfrom keras.layers import Dense, Activation, Convolution2D, MaxPooling2D, Flattenfrom keras.optimizers import Adam
    #---------------------------載入數據及預處理---------------------------# 下載MNIST數據 # training X shape (60000, 28x28), Y shape (60000, )# test X shape (10000, 28x28), Y shape (10000, )(X_train, y_train), (X_test, y_test) = mnist.load_data()
    # 數據預處理# 參數-1表示樣例的個數 1表示灰度照片(3對應RGB彩色照片) 28*28表示像素長度和寬度X_train = X_train.reshape(-1, 1, 28, 28) / 255   # normalizeX_test = X_test.reshape(-1, 1, 28, 28) / 255     # normalize
    # 將類向量轉化為類矩陣  數字 5 轉換為 0 0 0 0 0 1 0 0 0 0 矩陣y_train = np_utils.to_categorical(y_train, num_classes=10)y_test = np_utils.to_categorical(y_test, num_classes=10)
    #---------------------------創建第一層神經網絡---------------------------# 創建CNNmodel = Sequential()
    # Conv layer 1 output shape (32, 28, 28)# 第一層利用Convolution2D卷積 model.add(Convolution2D(    filters = 32,                   # 32個濾波器     nb_row = 5,                     # 寬度     nb_col = 5,                     # 高度    border_mode = 'same',           # Padding method    input_shape = (1, 28, 28),      # 輸入形狀 channels height width))# 增加神經網絡激活函數model.add(Activation('relu'))
    # Pooling layer 1 (max pooling) output shape (32, 14, 14)# 池化層利用MaxPooling2Dmodel.add(MaxPooling2D(    pool_size = (2, 2),             # 向下取樣    strides = (2,2),                # 取樣跳2個    padding='same',                 # Padding method))
    #---------------------------創建第二層神經網絡---------------------------# Conv layer 2 output shape (64, 14, 14)model.add(Convolution2D(64, 5, 5, border_mode='same'))model.add(Activation('relu'))
    # Pooling layer 2 (max pooling) output shape (64, 7, 7)model.add(MaxPooling2D(pool_size = (2, 2), border_mode='same'))
    #-----------------------------創建全連接層------------------------------# Fully connected layer 1 input shape (64 * 7 * 7) = (3136), output shape (1024)model.add(Flatten())                  # 將三維層拉直model.add(Dense(1024))                # 全連接層model.add(Activation('relu'))         # 激勵函數
    # Fully connected layer 2 to shape (10) for 10 classesmodel.add(Dense(10))                  # 輸出10個單位 model.add(Activation('softmax'))      # 分類激勵函數
    #--------------------------------訓練和預測------------------------------# 優化器 optimizeradam = Adam(lr=1e-4)
    # We add metrics to get more results you want to see# 激活神經網絡model.compile(optimizer=adam,                      # 加速神經網絡              loss='categorical_crossentropy',     # 損失函數              metrics=['accuracy'])                # 計算誤差或準確率
    print('Training')model.fit(X_train, y_train, epochs=1, batch_size=64,)  # 訓練次數及每批訓練大小
    print('Testing')loss, accuracy = model.evaluate(X_test, y_test)
    print('\ntest loss: ', loss)print('\ntest accuracy: ', accuracy)
    

    3.運行結果

    訓練一個批次的結果如下圖所示,最終誤差loss為“0.2520788”,正確率為“0.92650”。

    訓練兩個批次的結果如下圖所示,最終誤差loss為“0.156024”,正確率為“0.95590”。

    訓練六個批次的結果如下圖所示,最終誤差loss為“0.07606”,正確率為“0.97500”。可以看到誤差不斷減小,正確率不斷提高,說明CNN在不斷學習。真正做神經網絡實驗時,我們會針對不同的參數和樣本、算法進行比較,也希望這篇文章對您有幫助。

    三.總結

    寫到這里,這篇文章就結束了。本文主要通過Keras實現了一個CNN分類學習的案例,并詳細介紹了卷積神經網絡原理知識。

    最后,希望這篇基礎性文章對您有所幫助,如果文章中存在錯誤或不足之處,還請海涵~作為人工智能的菜鳥,我希望自己能不斷進步并深入,后續將它應用于圖像識別、網絡安全、對抗樣本等領域,指導大家撰寫簡單的學術論文,一起加油!

    卷積keras
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    卷積神經網絡的英文是Convolutional Neural Network,簡稱CNN。近幾年神經網絡飛速發展,其中一個很重要的原因就是CNN卷積神經網絡的提出,這也是計算機視覺處理的飛躍提升。
    Python人工智能第9篇文章詳細介紹卷積神經網絡基礎知識
    從本專欄開始,作者正式研究Python深度學習、神經網絡及人工智能相關知識。一.RNN文本分類1.RNN循環神經網絡英文是Recurrent Neural Networks,簡稱RNN。假設有一組數據data0、data1、data2、data3,使用同一個神經網絡預測它們,得到對應的結果。RNN常用于自然語言處理、機器翻譯、語音識別、圖像識別等領域。本文將采用詞向量、TFIDF兩種方式進行實驗。
    搭建過程詳見這篇文章:二.TensorFlow環境搭建、學習路線及入門案例安裝如下圖所示:安裝成功之后,我們嘗試一個簡單的代碼。打開Anaconda,然后選擇已經搭建好的“tensorflow”環境,運行Spyder。
    Python人工智能第10篇介紹TF實現CNN圖像分類任務
    一.文本分類文本分類旨在對文本集按照一定的分類體系或標準進行自動分類標記,屬于一種基于分類體系的自動分類。牛亞峰老師將傳統的文本分類流程歸納如下圖所示。在傳統的文本分類中,基本上大部分機器學習方法都在文本分類領域有所應用。本文將采用詞向量、TFIDF兩種方式進行實驗。
    而從上圖中可以看到,yolo對于目標物體探測的精度會隨著網格密度的增高而增高,也不會存在像滑動窗口那樣因為步長過大而滑過了目標物體從而導致探測不到的情況。
    評價神經網絡的方法和評價機器學習的方法大同小異,常見的包括誤差、準確率、R2 score、F值等。
    與欺騙攻擊相對應,語音欺騙檢測是一種識別防御技術,國內外相關人員進行了最新的研究。目前,指紋、人臉和聲紋等常見的生物特征已經被大量應用。2017年在瑞典斯德哥爾摩舉行的 2017 挑戰賽 則重點關注語音回放欺騙攻擊。這次的挑戰賽吸引了 53 個注冊團隊,收到了 23 個提交結果。由于輸入 ASV 系統的語音的欺騙方法未知,傳統的語音欺騙檢測系統無法同時檢測 LA 和 PA 兩種攻擊。
    我們設計了基于ReRAM的數模混合CNN加速器ReHy,相比CPU/GPU可以在保證CNN訓練精度的同時將訓練時間縮短近50倍。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类