• <td id="ui4cm"></td>
  • <bdo id="ui4cm"><legend id="ui4cm"></legend></bdo>
  • 當前位置:首頁 > 安卓源碼 > 技術博客 >

    使用Keras和CNN進行自定義AI人臉識別

    時間:2020-08-09 22:05 來源:互聯網 作者:源碼搜藏 瀏覽: 收藏 挑錯 推薦 打印

    在這里,我們將討論CNN,然后設計一個并使用Keras在Python中實現它。 下載源8.4 KB 介紹 如果您看過《 少數派報告》 電影,您可能還記得湯姆克魯斯(Tom Cruise)走進一家Gap商店的場景。 視網膜掃描儀讀取他的眼睛,并為他播放定制的廣告。 好吧,這是2020
    在這里,我們將討論CNN,然后設計一個并使用Keras在Python中實現它。

    介紹

    如果您看過《少數派報告》電影,您可能還記得湯姆·克魯斯(Tom Cruise)走進一家Gap商店的場景。視網膜掃描儀讀取他的眼睛,并為他播放定制的廣告。好吧,這是2020年。我們不需要視網膜掃描儀,因為我們擁有人工智能(AI)和機器學習(ML)!

    在本系列中,我們將向您展示如何使用深度學習進行面部識別,然后基于被識別的面部,使用神經網絡語音合成(TTS)引擎播放自定義廣告。歡迎您在CodeProject上瀏覽此處的代碼,或下載.zip文件以在自己的計算機上瀏覽代碼。

    我們假定您熟悉AI / ML的基本概念,并且可以找到使用Python的方法。

    在本文中,我們將討論CNN,然后設計一個并使用Keras在Python中實現它。

    什么是CNN?

    CNN是一種神經網絡(NN),通常用于圖像分類任務(例如人臉識別)以及輸入具有網格狀拓撲的任何其他問題。在CNN中,并非每個節點都連接到下一層的所有節點。換句話說,它們不是完全連接的NN。這有助于防止完全連接的NN中出現過擬合問題,更不用說由NN中過多的連接導致的超慢收斂。

    CNN的概念依賴于稱為卷積的數學運算,這在數字信號處理領域非常普遍。卷積被定義為兩個函數(第三個函數)的乘積,表示前兩個函數之間的重疊量。在CNN區域,通過在圖像中滑動濾鏡(即內核)來實現卷積。

    在人臉識別中,卷積操作使我們能夠檢測圖像中的不同特征。不同的濾鏡可以檢測垂直和水平邊緣,紋理,曲線和其他圖像特征。這就是為什么任何CNN中的第一層都是卷積層的原因。

    CNN中另一個常見的層是池化層。池化用于減小圖像表示的大小,這意味著減少了參數數量,并最終減少了計算量。最常見的池化類型是“ max”,它使用滑動窗口(類似于卷積操作中的窗口)在每個位置從匹配的單元格組中獲取最大值。最后,它根據收獲的最大值構建圖像的新表示形式。

    最常見的CNN架構通常從卷積層開始,然后是激活層,然后是池化層,最后以傳統的全連接網絡(例如多層NN)結束。這種類型的將一層一層接一層的模型稱為順序模型。為什么最后要建立全連接網絡?要學習變換圖像中特征的非線性組合(在卷積和合并之后)。

    設計CNN

    這是我們將在CNN中實現的架構:

    • 輸入層– NumPy數組(img_width,img_height,1);“ 1”,因為我們正在處理灰度圖像;對于RGB圖像,應該是(img_width,img_height,3)
    • Conv2D層– 32個濾鏡,濾鏡大小為3
    • 激活層–必須使用非線性函數進行學習,在這種情況下,該函數為ReLU
    • Conv2D層– 32個濾鏡,濾鏡大小為3,步幅為3
    • 使用ReLU功能的激活層
    • MaxPooling2D層–應用(2,2)合并窗口
    • 25%的DropOut層–通過從前一層中隨機刪除一些值(將它們設置為0)來防止過度擬合;又名稀釋技術
    • Conv2D層– 64個濾鏡,濾鏡大小為3
    • 使用ReLU功能的激活層
    • Conv2D層– 64個濾鏡,濾鏡大小為3,步幅為3
    • 使用ReLU功能的激活層
    • MaxPooling2D層–應用(2,2)合并窗口
    • DropOut層,占25%
    • 展平層–轉換要在下一層使用的數據
    • 致密層–代表完全連接的傳統NN
    • 使用ReLU功能的激活層
    • DropOut層,占25%
    • 密集層,節點數與問題中的類數匹配–耶魯數據集為15
    • 使用ReLU功能的激活層

    上面的架構很常見;層參數已通過實驗進行了微調。

    實施CNN

    現在,讓我們在代碼中實現我們的CNN架構-我們選擇的一組圖層。為了創建易于擴展的解決方案,我們將ML模型與一組抽象方法結合使用:

    class MLModel(metaclass=abc.ABCMeta):
    
        def __init__(self, dataSet=None):
            if dataSet is not None:
                self.objects = dataSet.objects
                self.labels = dataSet.labels
                self.obj_validation = dataSet.obj_validation
                self.labels_validation = dataSet.labels_validation
                self.number_labels = dataSet.number_labels
                self.n_classes = dataSet.n_classes
            self.init_model()
    
        @abstractmethod
        def init_model(self):
            pass
    
        @abstractmethod
        def train(self):
            pass
    
        @abstractmethod
        def predict(self, object):
            pass
    
        @abstractmethod
        def evaluate(self):
            score = self.get_model().evaluate(self.obj_validation, self.labels_validation, verbose=0)
            print("%s: %.2f%%" % (self.get_model().metrics_names[1], score[1] * 100))
    
        @abstractmethod
        def get_model(self):
            pass

    在我們的例子中,dataset是本系列上一篇文章中FaceDataSet描述的類的實例。在類,從中繼承和實現其所有的抽象方法,是一個將包含我們的CNN架構。這里是:ConvolutionalModelMLModel

    class ConvolutionalModel(MLModel):
    
        def __init__(self, dataSet=None):
            if dataSet is None:
                raise Exception("DataSet is required in this model")
            self.shape = numpy.array([constant.IMG_WIDTH, constant.IMG_HEIGHT, 1])
            super().__init__(dataSet)
            self.cnn.compile(loss=constant.LOSS_FUNCTION,
                             optimizer=Common.get_sgd_optimizer(),
                             metrics=[constant.METRIC_ACCURACY])
    
        def init_model(self):
            self.cnn = Sequential()
    
            self.cnn.add(Convolution2D(32, 3, padding=constant.PADDING_SAME, input_shape=self.shape))
            self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
            self.cnn.add(Convolution2D(32, 3, 3))
            self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
            self.cnn.add(MaxPooling2D(pool_size=(2, 2)))
            self.cnn.add(Dropout(constant.DROP_OUT_O_25))
    
            self.cnn.add(Convolution2D(64, 3, padding=constant.PADDING_SAME))
            self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
            self.cnn.add(Convolution2D(64, 3, 3))
            self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
            self.cnn.add(MaxPooling2D(pool_size=(2, 2)))
            self.cnn.add(Dropout(constant.DROP_OUT_O_25))
    
            self.cnn.add(Flatten())
            self.cnn.add(Dense(constant.NUMBER_FULLY_CONNECTED))
            self.cnn.add(Activation(constant.RELU_ACTIVATION_FUNCTION))
            self.cnn.add(Dropout(constant.DROP_OUT_0_50))
            self.cnn.add(Dense(self.n_classes))
            self.cnn.add(Activation(constant.SOFTMAX_ACTIVATION_FUNCTION))
            self.cnn.summary()
    
        def train(self, n_epochs=20, batch=32):
            self.cnn.fit(self.objects, self.labels,
                           batch_size=batch,
                           epochs=n_epochs, shuffle=True)
    
        def get_model(self):
            return self.cnn
    
        def predict(self, image):
            image = Common.to_float(image)
            result = self.cnn.predict(image)
            print(result)
    
        def evaluate(self):
           super(ConvolutionalModel, self).evaluate()

    在構造函數中,我們設置self.shape變量,該變量定義輸入層的形狀。在我們的情況下,對于耶魯數據集,圖像高度為320像素,寬度為243像素,self.shape =(320,243,1)。

    然后super(),我們調用從父構造函數獲取所有與數據集相關的變量集,并調用init_model()初始化模型的方法。

    最后,我們調用該compile方法,該方法配置用于訓練的模型并設置要在loss參數中使用的目標函數。在訓練過程中,目標功能得到了優化(最小化或最大化)。該accuracy參數定義在訓練中評估模型的度量。該optimizer參數定義權重的計算方式。最常見的優化器是“梯度下降”。

    我們的CNN模型定義為順序的,并根據體系結構要求添加了所有層。該train()方法使用表示層排列fit的sequential類的方法來訓練CNN。此方法接收訓練CNN的數據作為輸入,該數據的正確分類以及一些可選參數,例如要運行的時期數。

    訓練CNN

    現在,代碼已經準備就緒,可以開始訓練我們的CNN了。讓我們實例化ConvolutionalModel該類,在耶魯大學數據集上進行訓練,然后調用評估方法。

    cnn = ConvolutionalModel(dataSet)
    cnn.train(n_epochs=50)
    cnn.evaluate()

    在進行了50個時期的訓練后,我們在測試圖像上的準確性達到了近85%。

     

    這意味著我們的CNN現在將以85%的概率識別出數據集中15個主題中的每個主題。簡短的練習還不錯吧?

    現在,我們已經訓練了CNN,如果我們想預測新的傳入數據(意味著來自圖像的新面孔),則可以使用之前詳細介紹的ConvolutionalModel類中的predict(image)方法來進行。如何運作?該呼叫看起來像下一個呼叫,它應符合某些假設。

    cnn.predict(np.expand_dims(image, axis=0))

    首先,輸入圖像必須具有與先前訓練的CNN輸入層相同的尺寸或形狀。其次,在predict()我們歸一化數據的方法中,它應該是相同類型的輸入,即像素值矩陣,因此不需要提供歸一化的圖像像素矩陣。第三,我們可能需要為輸入的面部圖像添加一個維度,因為在經過訓練的CNN中,我們考慮了數據集中樣本數量的第4個維度。這可以使用expand_dims()numpy方法來實現。第四,假定將提供面部圖像,在較大圖片的情況下,先前文章中提供的面部檢測方法可證明是有用的。

     

    最后,該predict()方法的輸出可以在上圖中看到。此方法將輸出臉部屬于每個可能類別或個人的概率(對于訓練后的數據集為15)。在這種情況下,我們可以看到類別4的可能性最高,這正是輸入的面部圖像所指的類別或人物。


    使用Keras和CNN進行自定義AI人臉識別 轉載http://www.robbiejoe.com/appboke/48992.html

    技術博客閱讀排行

    最新文章

    亚洲AV无码一区东京热
  • <td id="ui4cm"></td>
  • <bdo id="ui4cm"><legend id="ui4cm"></legend></bdo>