Python-OpenCV深度學習入門示例詳解
0. 前言
深度學習已經(jīng)成為機器學習中最受歡迎和發(fā)展最快的領(lǐng)域。自 2012 年深度學習性能超越機器學習等傳統(tǒng)方法以來,深度學習架構(gòu)開始快速應(yīng)用于包括計算機視覺在內(nèi)的眾多領(lǐng)域。深度學習的常見應(yīng)用包括語音識別、圖像識別、自然語言處理、推薦系統(tǒng)等等。大多數(shù)現(xiàn)代深度學習架構(gòu)都基于人工神經(jīng)網(wǎng)絡(luò),深度學習中的“深”是指架構(gòu)的層數(shù)。在本文中,首先介紹傳統(tǒng)機器學習方法與深度學習間的差異,然后將介紹圖像分類和對象檢測中常見的深度學習架構(gòu),最后,將介紹深度學習 Python 庫 Keras,并通過實戰(zhàn)來推開深度學習的大門。
1. 計算機視覺中的深度學習簡介
深度學習推動了計算機視覺領(lǐng)域的深刻變革,我們首先解釋深度學習中的關(guān)鍵概念,以便更好的了解深度學習的廣袤世界。
1.1 深度學習的特點
深度學習在許多計算機視覺任務(wù)中的性能超越了傳統(tǒng)的機器學習方法,但在選擇何種方法完成特定的計算任務(wù)時,應(yīng)該明確深度學習與傳統(tǒng)的機器學習方法之間的區(qū)別,以選擇合適的方法:
- 傳統(tǒng)的機器學習算法大多可以在低端機器上運行,而深度學習算法需要較高的算力才能正確訓練,通常這些計算可以使用 GPU 進行優(yōu)化并行計算
- 當對特征工程缺乏領(lǐng)域理解時,深度學習技術(shù)將是首選方法,這是由于在深度學習中,尋找相關(guān)特征的任務(wù)是算法的一部分,它通過減少問題的特征工程來實現(xiàn)自動化。特征工程是將領(lǐng)域知識應(yīng)用于創(chuàng)建特征檢測器和提取器的過程,目的是降低數(shù)據(jù)的復雜性,使傳統(tǒng)的機器學習方法能夠正確學習。因此,傳統(tǒng)機器學習算法的性能取決于識別和提取特征的準確程度,而深度學習技術(shù)試圖從數(shù)據(jù)中自動提取高級特征。
- 傳統(tǒng)機器學習和深度學習都能夠處理海量數(shù)據(jù)集。但兩種方法之間的主要區(qū)別在于隨著數(shù)據(jù)規(guī)模的增加其性能的變化程度。例如,在處理小數(shù)據(jù)集時,深度學習算法難以在數(shù)據(jù)中找到映射關(guān)系,因此可能表現(xiàn)不佳,因為深度學習通常需要大量數(shù)據(jù)來調(diào)整其內(nèi)部參數(shù)。根據(jù)經(jīng)驗法,如果數(shù)據(jù)集很大,深度學習會優(yōu)于其他技術(shù),而當數(shù)據(jù)集很小時,傳統(tǒng)的機器學習算法更可取。
可以使用下圖來總結(jié)機器學習與深度學習的主要區(qū)別:
由上圖可知,機器學習與深度學習的關(guān)鍵選擇要點如下:
- 計算資源(深度學習<——高算力計算機;機器學習<——低算力計算機)
- 特征工程(深度學習<——特征提取和目標任務(wù)在同一步驟中;機器學習<——特征提取和目標任務(wù)在不同步驟中)
- 數(shù)據(jù)集大?。ㄉ疃葘W習<——大型或超大型數(shù)據(jù)集;機器學習<——小型或中型數(shù)據(jù)集)
1.2 深度學習大爆發(fā)
深度學習的概念可以追溯至 1986 年,但直到 2012 年深度學習性能超越傳統(tǒng)機器學習時,才出現(xiàn)了深度學習的大爆發(fā)。 ImageNet 是一個大型視覺數(shù)據(jù)庫,包含超過 1400 萬張帶有標簽的高分辨率圖像,包含 20,000 多個類別。因此,2012 年 AlexNet 架構(gòu)在解決 ImageNet 大規(guī)模視覺識別挑戰(zhàn)賽 (ILSVRC) 上的突破性進展通常被認為是深度學習大爆發(fā)的開始。
2. 用于圖像分類的深度學習簡介
繼 AlexNet 在 ILSVRC 比賽中取得成功之后,更多深度學習架構(gòu)開始被應(yīng)用于 ImageNet 挑戰(zhàn)賽中,下圖顯示了在 ImageNet 挑戰(zhàn)賽中的最相關(guān)深度學習模型的準確率和模型的參數(shù)量:
接下來,對深度學習模型架構(gòu)進行介紹,以了解它們的發(fā)展脈絡(luò)及其關(guān)鍵點:
AlexNet
:AlexNet 是 LSVRC-2012 的獲勝者,是一種簡單但功能強大的網(wǎng)絡(luò)架構(gòu),其通過堆疊卷積層和池化層,最后頂部使用全連接層。
VGG
:VGGNet 由 Visual Geometry Group (VGG) 提出,在 LSVRC-2014 中排名第二,與 AlexNet 相比其在整個網(wǎng)絡(luò)中僅使用 3 x 3 卷積核,而不是使用大尺寸卷積核(例如 7 x 7 和 11 x 11),主要貢獻在于它表明網(wǎng)絡(luò)的深度是在卷積神經(jīng)網(wǎng)絡(luò)中實現(xiàn)更好的識別或分類準確率的關(guān)鍵。它的主要缺點是訓練速度非常慢,并且其網(wǎng)絡(luò)架構(gòu)權(quán)重參數(shù)量非常大(可以從上圖看出)。
GoogLeNet/Inception V1
:GoogLeNet (也稱 Inception V1) 是 LSVRC-2014 的獲勝者,其 top-5 錯誤率僅為 6.67%,非常接近人類水平的表現(xiàn)。這種架構(gòu)比 VGGNet 更深,但由于其使用 9 個并行的 Inception 模塊,Inception 模塊基于幾個非常小的卷積,極大的減少了參數(shù)數(shù)量。
ResNet
:ResNets 是 LSVRC-2015 的獲勝者,是迄今為止最深的網(wǎng)絡(luò),其包含 153 個卷積層 top-5 分類錯誤率僅為 4.9% (使深度學習模型準確率首次高于人類)。該架構(gòu)使用跳躍連接,可實現(xiàn)增量學習修改。
Inception V3
:Inception V2 在 Inception 模塊中引入了批歸一化,Inception V3 架構(gòu)包含了分解思想,其目標是在不降低網(wǎng)絡(luò)效率的情況下減少參數(shù)的數(shù)量。
Inception V4
:Inception V4 具有比 Inception-V3 更統(tǒng)一的簡化架構(gòu)和更多的 Inception 模塊,在 LSVRC 上達到了 80.2% 的 top-1 準確率和 95.2% 的 top-5 準確率。
3. 用于目標檢測的深度學習簡介
目標檢測是深度學習中的一個熱門話題,其用于識別和定位圖像中的多個對象。目標檢測算法通常使用以下三個數(shù)據(jù)集進行基準測試:1) PASCAL Visual Object (PASCAL VOC) 數(shù)據(jù)集,包含 20 個類別的 10,000 張圖像,數(shù)據(jù)集中包含目標的邊界框;2) ImageNet 在 2013 年發(fā)布了一個目標檢測數(shù)據(jù)集,它由大約 500,000 張圖像和 200 個類別組成;3) Common Objects in Context (COCO) 是一個大規(guī)模的對象檢測、分割數(shù)據(jù)集,其包括 328,000 張圖像以及 250 萬個標記目標。為了評估目標檢測算法,通常使用平均精度均值 (mean Average Precision, mAP),用于目標檢測深度學習算法:
R-CNN:Region-based Convolutional Network (R-CNN) 是最早使用卷積神經(jīng)網(wǎng)絡(luò)進行目標檢測的算法之一,與基于 HOG 特征的系統(tǒng)相比,卷積神經(jīng)網(wǎng)絡(luò)可以帶來更高的對象檢測性能。該算法可以分解為以下三個步驟:
- 創(chuàng)建一組候選區(qū)域
- 對每個候選區(qū)域通過基于 AlexNet 的模型執(zhí)行前向傳遞以提取特征向量
- 潛在對象通過 SVM 分類器預測類別,利用線性回歸器預測邊界框的坐標
Fast R-CNN:Fast Region-based Convolutional Network (Fast R-CNN) 是對 R-CNN的改進,以有效地對目標提議進行分類。此外,F(xiàn)ast R-CNN 采用多項創(chuàng)新來提高訓練和測試速度,同時提高檢測精度。
Faster R-CNN:Faster R-CNN 是對 Fast R-CNN 的改進,它引入了候選區(qū)域網(wǎng)絡(luò) (region proposal network, RPN),與檢測網(wǎng)絡(luò)共享圖像的卷積特征。
R-FCN:Region-based Fully Convolutional Network (R-FCN) 是一個只有卷積層的框架,以實現(xiàn)準確高效的目標檢測。
YOLO: You only look once (YOLO) 可以在一個步驟中同時預測邊界框和類別概率。與其他深度學習檢測器相比,YOLO 產(chǎn)生更多的定位誤差,但其產(chǎn)生假陽性的概率較小。
SSD:Single Shot MultiBox Detector (SSD) 同樣通過單一端到端卷積神經(jīng)網(wǎng)絡(luò)架構(gòu)同時預測邊界框和類別概率。
YOLO V2: YOLO V2 是 YOLO 的改進版本,專注于提高準確性,同時是一個實時快速檢測器。
NASNet: NASNet 的作者介紹了神經(jīng)網(wǎng)絡(luò)搜索,通過使用循環(huán)神經(jīng)網(wǎng)絡(luò)來組成神經(jīng)網(wǎng)絡(luò)架構(gòu),NASNet 學習模型模型架構(gòu)的同時提高準確性。
Mask R-CNN:Mask Region-based Convolutional Network (Mask R-CNN) 是 Faster R-CNN 模型的改進,它為邊界框檢測添加了一個并行分支,目的是預測目標掩碼。目標掩碼是它在圖像中按像素進行的分割,允許進行目標實例分割。
YOLO V3:YOLO V3 是以 YOLO V1 和 YOLO V2 為基礎(chǔ)調(diào)整了網(wǎng)絡(luò)結(jié)構(gòu);利用多尺度特征進行對象檢測。
YOLO V4:YOLO-V4 算法是在原有 YOLO 目標檢測架構(gòu)的基礎(chǔ)上,采用了 CNN 領(lǐng)域中優(yōu)秀的優(yōu)化策略,從數(shù)據(jù)處理、主干網(wǎng)絡(luò)、網(wǎng)絡(luò)訓練、激活函數(shù)、損失函數(shù)等各個方面都有著不同程度的優(yōu)化。
4. 深度學習框架 keras 介紹與使用
在本節(jié)中,我們將通過兩個簡單示例來一窺深度學習的神秘面紗。在第一個示例中,構(gòu)造輸入數(shù)據(jù)來解決線性回歸問題;在第二個示例中,使用 MNIST 數(shù)據(jù)集對手寫數(shù)字進行分類。
4.1 keras 庫簡介與安裝
Keras 是用 Python 編寫的開源高級神經(jīng)網(wǎng)絡(luò) API,它能夠在 TensorFlow、或 Theano 之上運行,其最大的特點是能夠?qū)崿F(xiàn)快速實驗,因此本文利用它來進行深度學習實戰(zhàn)。
要安裝 Keras,首先進行安裝:
pip install keras
4.2 使用 keras 實現(xiàn)線性回歸模型
首先創(chuàng)建用于訓練/測試算法的數(shù)據(jù),如下所示:
# 產(chǎn)生一百個隨機數(shù)據(jù)點作為訓練數(shù)據(jù) Number = 100 x = np.linspace(0, Number, Number) y = 3 * np.linspace(0, Number, Number) + np.random.uniform(-12, 12, Number)
接下來創(chuàng)建模型:
def create_model(): # 創(chuàng)建 Sequential 模型 model = Sequential() # 使用具有線性激活函數(shù)的全連接層 model.add(Dense(input_dim=1, units=1, activation='linear', kernel_initializer='uniform')) # 使用均方差(mse)作為損失函數(shù),Adam作為優(yōu)化器編譯模型 model.compile(loss='mse', optimizer=Adam(lr=0.1)) return model
使用 Keras 時,最簡單的模型類型是 Sequential 模型,可以將其視為網(wǎng)絡(luò)層的線性堆棧,對于更復雜的架構(gòu),可以使用 Keras 函數(shù)式 API,以創(chuàng)建任意網(wǎng)絡(luò)架構(gòu)。
作為簡單示例,此處使用 Sequential 模型,然后利用 model.add() 方法堆疊層來構(gòu)建模型。在此示例中,使用了具有線性激活函數(shù)的單個全連接層。定義模型之后,需要使用損失函數(shù)與優(yōu)化器編譯模型,示例中使用均方差 (mean squared error, MSE) 作為損失函數(shù),使用 Adam 作為優(yōu)化器并設(shè)置學習率為 0.1。
編譯模型完成后,就可以使用 model.fit() 方法使用訓練數(shù)據(jù)的訓練模型:
linear_reg_model.fit(x, y, epochs=100, validation_split=0.2, verbose=2)
訓練后,就可以獲得可學習參數(shù) w 和 b,這些值將用于接下來的:
def get_weights(model): w = model.get_weights()[0][0][0] b = model.get_weights()[1][0] return w, b w_final, b_final = get_weights(linear_reg_model)
接下來,我們可以用以下方式進行預測:
predictions = w_final * x + b_final
還可以保存模型:
linear_reg_model.save_weights("my_model.h5")
最后可以將訓練數(shù)據(jù)集和訓練完成后線性模型進行可視化:
plt.subplot(1, 2, 1) plt.plot(x, y, 'ro', label='Original data') plt.xlabel('x') plt.ylabel('y') plt.title("Training Data") plt.subplot(1, 2, 2) plt.plot(x, y, 'ro', label='Original data') plt.plot(x, predictions, label='Fitted line') plt.xlabel('x') plt.ylabel('y') plt.title('Linear Regression Result', fontsize=10) plt.legend() plt.show()
如上圖所示,可以看到左側(cè)圖像顯示的是訓練數(shù)據(jù),右側(cè)圖像顯示了線性回歸模型對應(yīng)的擬合線。
如果我們已經(jīng)擁有訓練完成的模型權(quán)重文件,就可以直接加載預先訓練的模型來進行預測:
# 加載模型 linear_reg_model.load_weights('my_model.h5') # 構(gòu)建測試數(shù)據(jù)集 M = 3 new_x = np.linspace(Number + 1, Number + 10, M) # 使用模型進行預測 new_predictions = linear_reg_model.predict(new_x)
程序的運行結(jié)果如下圖所示:
4.3 使用 keras 進行手寫數(shù)字識別
接下來,我們使用 Keras 識別手寫數(shù)字,與第一個示例相同,首先需要構(gòu)建模型:
def create_model(): model = Sequential() model.add(Dense(units=128, activation='relu', input_shape=(784,))) model.add(Dense(units=128, activation='relu')) model.add(Dense(units=64, activation='relu')) model.add(Dense(units=10, activation='softmax')) # 使用分類交叉熵(categorical_crossentropy)作為損失函數(shù)和隨機梯度下降作為優(yōu)化器編譯模型 model.compile(optimizer=SGD(0.001), loss='categorical_crossentropy', metrics=['acc']) return model
使用 categorical_crossentropy 損失函數(shù)編譯模型,該損失函數(shù)非常適合比較兩個概率分布,使用隨機梯度下降 (stochastic gradient descent, SGD) 作為優(yōu)化器。
接下來加載 MNIST 數(shù)據(jù)集:
(train_x, train_y), (test_x, test_y) = mnist.load_data()
此外,由于我們使用的是全連接層,因此必須對加載的數(shù)據(jù)進行整形以輸入網(wǎng)絡(luò):
train_x = train_x.reshape(60000, 784) test_x = test_x.reshape(10000, 784) train_y = keras.utils.to_categorical(train_y, 10) test_y = keras.utils.to_categorical(test_y, 10)
創(chuàng)建模型完成后,就可以訓練模型,并保存創(chuàng)建的模型,也可以評估模型在測試數(shù)據(jù)集上的表現(xiàn):
# 模型創(chuàng)建 model = create_model() # 模型訓練 model.fit(train_x, train_y, batch_size=32, epochs=10, verbose=1) # 模型保存 model.save("mnist-model.h5") # 評估模型在測試數(shù)據(jù)集上的表現(xiàn) accuracy = model.evaluate(x=test_x, y=test_y, batch_size=32) # 打印準確率 print("Accuracy: ", accuracy[1])
接下來,可以使用訓練完成的模型來預測圖像中的手寫數(shù)字:
def load_digit(image_name): gray = cv2.imread(image_name, cv2.IMREAD_GRAYSCALE) gray = cv2.resize(gray, (28, 28)) gray = gray.reshape((1, 784)) return gray # 加載圖片 test_digit_0 = load_digit("digit_0.png") test_digit_1 = load_digit("digit_1.png") test_digit_2 = load_digit("digit_2.png") test_digit_3 = load_digit("digit_3.png") imgs = np.array([test_digit_0, test_digit_1, test_digit_2, test_digit_3]) imgs = imgs.reshape(4, 784) # 預測加載圖像 prediction_class = model.predict_classes(imgs) # 打印預測結(jié)果 print("Class: ", prediction_class)
加載的四張圖像如下圖所示:
使用經(jīng)過訓練的模型來預測這些圖像,得到的輸出如下:
Class: [0 1 2 3]
小結(jié)
在本節(jié)中,使用流行的庫深度學習庫 Keras 對深度學習進行了介紹。我們首先概述了用于圖像分類和目標檢測的深度學習架構(gòu)。然后,我們介紹了 Keras,并通過示例訓練了簡單線性回歸模型,介紹了如何利用 Keras 訓練全連接網(wǎng)絡(luò)識別手寫數(shù)字。
到此這篇關(guān)于Python-OpenCV深度學習入門示例詳解的文章就介紹到這了,更多相關(guān)Python OpenCV深度學習內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何使用Python和正則表達式處理XML表單數(shù)據(jù)
在日常的Web開發(fā)中,處理表單數(shù)據(jù)是一個常見的任務(wù),而XML是一種常用的數(shù)據(jù)格式,用于在不同的系統(tǒng)之間傳遞和存儲數(shù)據(jù),本文通過闡述一個技術(shù)問題并給出解答的方式,介紹如何使用Python和正則表達式處理XML表單數(shù)據(jù),需要的朋友可以參考下2023-09-09解決Tensorflow使用pip安裝后沒有model目錄的問題
今天小編就為大家分享一篇解決Tensorflow使用pip安裝后沒有model目錄的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06Python實現(xiàn)視頻轉(zhuǎn)換為字符畫詳解
這篇文章主要介紹了如何通過Python實現(xiàn)讀取視頻并將其轉(zhuǎn)換為字符畫的示例代碼,文中講解詳細,對我們的學習和工作有一點的價值,感興趣的小伙伴可以了解一下2021-12-12Python無法用requests獲取網(wǎng)頁源碼的解決方法
爬蟲獲取信息,很多時候是需要從網(wǎng)頁源碼中獲取鏈接信息的,下面這篇文章主要給大家介紹了關(guān)于Python無法用requests獲取網(wǎng)頁源碼的解決方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07python自動化測試selenium定位frame及iframe示例
這篇文章主要為大家介紹了python自動化測試selenium定位frame及iframe示例的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11