介紹
你正在處理影象資料嗎?我們可以使用計算機視覺演算法來做很多事情:
物件檢測
影象分割
影象翻譯
物件跟蹤(實時),還有更多……
這讓我思考——如果一個影象中有多個物件類別,我們該怎麼辦?製作一個影象分類模型是一個很好的開始,但我想擴充套件我的視野以承擔一個更具挑戰性的任務—構建一個多標籤影象分類模型!
製作一個影象分類模型
https://www.analyticsvidhya.com/blog/2019/01/build-image-classification-model-10-minutes/?utm_source=blog&utm_medium=multi-label-image-classification
我不想使用簡單玩具資料集來構建我的模型—這太普通了。然後,它打動了我—包含各種各樣的人的電影/電視劇海報。我可以僅通過看海報就能來構建我自己的多標籤影象分類模型來預測不同的流派嗎?
答案很簡單——是的!在本文中,我解釋了多標籤影象分類背後的思想。我們將使用電影海報構建我們自己的模型。你將會對我們的模型產生的令人印象深刻的結果感到驚訝。如果你是《復仇者聯盟》或《權力的遊戲》的粉絲,那麼在實現部分會有一個很棒的驚喜(無劇透的)給你。
激動嗎?很好,我們開始吧!
目錄
1. 什麼是多標籤影象分類?
2. 多標籤影象分類與多類影象分類有何不同?
3. 瞭解多標籤影象分類模型體系結構;
4. 構建多標籤影象分類模型的步驟;
5. 案例研究:用Python解決多標籤影象分類問題;
6.接下來的步驟和你的實驗;
7.尾記。
1. 什麼是多標籤影象分類?
讓我們通過一個直觀的例子來理解多標籤影象分類的概念。 看看下面的圖片:
圖1中的物件是一輛汽車。這是顯而易見的。然而,在圖2中沒有汽車,只有一組建築物。你能看出我們要怎麼做嗎?我們將影象分為兩類,即,有車還是沒車。
當我們只有兩類影象可以分類時,這就稱為二值影象分類問題。
讓我們再看一個圖片:
在這個圖片中,你識別出了多少個物體?有太多了——房子、帶噴泉的池塘、樹木、岩石等等。所以,當我們可以將一個影象分類為多個類(如上圖所示)時,就稱為多標籤影象分類問題。
現在,這裡有一個問題——我們大多數人對多標籤和多類影象分類感到困惑。當我第一次遇到這些術語時,我也被迷惑了。現在我對這兩個主題有了更好的理解,讓我來為你們澄清一下區別。
2. 多標籤影象分類與多類影象分類有何不同?
假設給我們一些動物的圖片,讓我們把它們分成相應的類別。為了便於理解,我們假設一個給定的影象可以分為4類(貓、狗、兔子和鸚鵡)。現在,可能有兩種情況:
每個影象只包含一個物件(上述4個類別中的任何一個),因此,它只能被歸入4個類別中的一個。
影象可能包含多個物件(來自上述4個類別),因此該影象將屬於多個類別。
讓我們通過例子來了解每種情況,從第一個場景開始:
這裡,我們的每個影象都只包含一個物件。敏銳的你會注意到在這個集合中有4種不同型別的物件(動物)。
這裡的每張圖片只能被分類為貓、狗、鸚鵡或兔子。沒有任何一個影象屬於多個類別的情況。
當影象可分類的類別超過兩種時
一個影象不屬於一個以上的類別
如果滿足上述兩個條件,則稱為多類影象分類問題。
現在,讓我們思考第二種情況 —— 看看下面的影象:
第一張圖片(左上角)包含一隻狗和一隻貓
第二幅圖(右上角)包括一隻狗、一隻貓和一隻鸚鵡
第三幅圖(左下角)包含一隻兔子和一隻鸚鵡,以及
最後一張圖片(右下角)包含一隻狗和一隻鸚鵡
這些都是給定的影象的標籤。這裡的每個影象都屬於一個以上的類,因此它是一個多標籤影象分類問題。
這兩種情況應該有助於你理解多類和多標籤影象分類之間的區別。如果你需要進一步的說明,請在本文下面的評論部分與我聯絡。
在進入下一節之前,我建議你通讀這篇文章——在10分鐘內構建你的第一個影象分類模型!它將幫助你瞭解如何解決一個多類影象分類問題。
在10分鐘內構建你的第一個影象分類模型:
https://www.analyticsvidhya.com/blog/2019/01/build-image-classification-model-10-minutes/?utm_source=blog&utm_medium=multi-label-image-classification
3. 構建多標籤影象分類模型的步驟
現在我們已經對多標籤影象分類有了一個直觀的認識,讓我們深入討論解決這個問題應該遵循的步驟。
第一步是以結構化格式獲取資料。這既適用於影象二分類,也適用於多類影象分類。
你應該有一個資料夾,其中包含您想要訓練模型的所有影象。現在,為了訓練這個模型,我們還需要影象的真實標籤。因此,你還應該有一個.csv檔案,其中包含所有訓練影象的名稱及其對應的真實標籤。
我們將在本文後面學習如何建立這個.csv檔案。現在,只要記住資料應該是一種特定的格式。資料準備好後,我們可以將進一步的步驟劃分如下:
載入和預處理資料
首先,載入所有影象,然後根據專案的需求對它們進行預處理。為了檢查我們的模型將如何對不可見的資料(測試資料)執行,我們建立了一個驗證集。我們在訓練集上訓練我們的模型並使用驗證集對其進行驗證(標準的機器學習方法)。
定義模型的結構
下一步是定義模型的結構。這包括決定隱藏層的數量、每層神經元的數量、啟用函式等等。
訓練模型
是時候在訓練集上訓練我們的模型了!我們輸入訓練影象及其對應的真標籤對模型進行訓練。我們還在這裡傳入驗證影象,以幫助我們驗證模型在不可見資料上的效能。
作出預測
最後,我們使用訓練過的模型對新影象進行預測。
4. 瞭解多標籤影象分類模型結構
現在,多標籤影象分類任務的預處理步驟將類似於多類問題的預處理步驟。關鍵的區別在於我們定義模型結構的步驟。
對於多類影象分類模型,我們在輸出層使用softmax啟用函式。對於每個影象,我們想要最大化單個類的概率。當一個類的概率增大時,另一個類的概率就減小。所以,我們可以說每個類的概率都依賴於其他類。
但是在多標籤影象分類的情況下,單個影象可以有多個標籤。我們希望概率彼此獨立。使用softmax啟用函式並不合適。相反,我們可以使用sigmoid啟用函式。這將獨立地預測每個類的概率。它將在內部建立n個模型(這裡的n是總類數),每個類一個模型,並預測每個類的概率。
利用sigmoid啟用函式將多標籤問題轉化為n-二分類問題。因此對於每幅影象,我們將得到概率來確定影象是否屬於第一類,以此類推。由於我們已經將其轉換為一個n-二分類問題,我們將使用binary_cross-sentropy損失。我們的目標是儘量減少這種損失,以提高模型的效能。
這是我們在定義用於解決多標籤影象分類問題的模型結構時必須做的主要更改。訓練部分將類似於一個多類問題。我們將傳入訓練影象及其對應的真實標籤,以及驗證集來驗證模型的效能。
最後,我們將獲取一張新的影象,並使用訓練過的模型來預測該影象的標籤。還跟得上嗎?
5. 案例研究:用Python解決多標籤影象分類問題
祝賀你來到這一步!你的獎勵——用Python解決一個可怕的多標籤影象分類問題。是時候啟動你最喜歡的Python IDE了!
讓我們明確問題陳述。我們的目標是通過電影的海報影象來預測電影的型別。你能猜到為什麼這是一個多標籤影象分類問題嗎?在你往下看之前想一下。
一部電影可以屬於多種型別,對吧?它不僅僅屬於一個類別,如動作片或喜劇片。電影可以是兩種或多種型別的結合。因此,它是多標籤影象分類。
我們將使用的資料集包含多個多型別電影的海報影象。我對資料集做了一些更改,並將其轉換為結構化格式,即一個包含影象的資料夾和一個儲存真正標籤的.csv檔案。你可以從這裡下載結構化資料集。下面是一些來自我們資料集的海報:
這裡
https://drive.google.com/file/d/1dNa_lBUh4CNoBnKdf9ddoruWJgABY1br/view
如果你願意,可以在這裡下載原始資料集和基準真值。
這裡
https://www.cs.ccu.edu.tw/~wtchu/projects/MoviePoster/index.html
讓我們開始程式設計!
首先,匯入所有需要的Python庫:
1. import keras
2. from keras.models import Sequential
3. from keras.layers import Dense, Dropout, Flatten
4. from keras.layers import Conv2D, MaxPooling2D
5. from keras.utils import to_categorical
6. from keras.preprocessing import image
7. import numpy as np
8. import pandas as pd
9. import matplotlib.pyplot as plt
10. from sklearn.model_selection import train_test_split
11. from tqdm import tqdm
12. %matplotlib inline
現在,讀取.csv檔案並檢視前五行的內容:
1. train = pd.read_csv('multi_label_train.csv') # reading the csv file
2. train.head() # printing first five rows of the file
這個檔案中有27列。 讓我們輸出這些列的名字看看:
1. train.columns
Genre列包含每個影象的列表,其中明確了每個影象對應的電影的型別。因此,從.csv檔案的頭部開始,第一個影象的型別是喜劇和戲劇。
剩下的25列是獨熱碼列。因此,如果一部電影屬於動作型別,它的值將為1,否則為0。每個影象可以屬於25種不同的型別。
我們將構建一個返回給定電影海報型別的模型。但在此之前,你還記得構建影象分類模型的第一步嗎?
沒錯——就是正確的載入和預處理資料。所以,讓我們看看所有的訓練圖片:
1. train_image = []
2. for i in tqdm(range(train.shape[0])):
3. img = image.load_img('Multi_Label_dataset/Images/'+train['Id'][i]+'.jpg',target_size=(400,400,3))
4. img = image.img_to_array(img)
5. img = img/255
6. train_image.append(img)
7. X = np.array(train_image)
快速瀏覽一下陣列的形狀:
1. X.shape
這裡共有7254個海報影象,所有影象都已轉換為(400,300,3)的形狀。 讓我們繪製並視覺化其中一個影象:
1. plt.imshow(X[2])
這是電影《交易場所》的海報。讓我們輸出這部電影的型別:
1. train['Genre'][2]
這部電影僅有一個型別——喜劇。我們的模型所需的下一步是所有影象的真實標籤。你能猜出這7254個影象真實標籤的形狀是什麼嗎?
讓我們來看看。 我們知道總共有25種可能的型別。對於每個影象,我們將有25個目標,即電影是否屬於該型別。 因此,所有這25個目標的值都為0或1。
我們將從訓練檔案中刪除Id和Genre列,並將剩餘的列轉換為將成為我們影象目標的陣列:
1. y = np.array(train.drop(['Id', 'Genre'],axis=1))
2. y.shape
輸出陣列的形狀是(7254,25),正如我們預想的那樣。 現在,讓我們建立一個驗證集,它將幫助我們檢查模型在不可見的資料上的效能。 我們將隨機分離10%的影象作為我們的驗證集:
1. X_train, X_test, y_train, y_test =
2. train_test_split(X, y, random_state=42, test_size=0.1)
下一步是定義模型結構。輸出層將有25個神經元(等於型別的數量),我們將使用sigmoid作為啟用函式。
我將使用某一結構(如下所示)來解決這個問題。 你也可以通過更改隱藏層數,啟用函式和其他超引數來修改此架構。
1. model = Sequential()
2. model.add(Conv2D(filters=16, kernel_size=(5, 5), activation="relu", input_shape=(400,400,3)))
3. model.add(MaxPooling2D(pool_size=(2, 2)))
4. model.add(Dropout(0.25))
5. model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))
6. model.add(MaxPooling2D(pool_size=(2, 2)))
7. model.add(Dropout(0.25))
8. model.add(Conv2D(filters=64, kernel_size=(5, 5), activation="relu"))
9. model.add(MaxPooling2D(pool_size=(2, 2)))
10. model.add(Dropout(0.25))
11. model.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu'))
12. model.add(MaxPooling2D(pool_size=(2, 2)))
13. model.add(Dropout(0.25))
14. model.add(Flatten())
15. model.add(Dense(128, activation='relu'))
16. model.add(Dropout(0.5))
17. model.add(Dense(64, activation='relu'))
18. model.add(Dropout(0.5))
19. model.add(Dense(25, activation='sigmoid'))
讓我們顯示我們的模型總結:
1. model.summary()
有相當多的引數要學習! 現在,編譯模型。 我將使用binary_crossentropy作為損失函式,使用ADAM作為優化器(同樣,你也可以使用其他優化器):
1. model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
最後,我們最有趣的部分——訓練模型。我們將訓練模型10個迴圈,並傳入我們之前建立的驗證資料,以驗證模型的效能:
1. model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test), batch_size=64)
我們可以看到訓練損失已降至0.24,驗證損失也降低了。 下一步是什麼? 是時候做預測了!
所有《權力的遊戲(GoT)》和《復仇者聯盟(Avengers)》的粉絲——這是給你們的禮物。 讓我獲取GoT和Avengers的海報,並將它們提供給我們的模型。 在繼續之前下載GOT和Avengers的海報。
GOT
https://drive.google.com/file/d/1cfIE-42H4_UM-JERoctseLUpKwmd40YE/view
Avengers
https://drive.google.com/file/d/1buNOcfo0Im2HmFH778dUwxven8Zzebtu/view
在進行預測之前,我們需要使用前面看到的相同步驟預處理這些影象。
1. img = image.load_img('GOT.jpg',target_size=(400,400,3))
2. img = image.img_to_array(img)
3. img = img/255
現在,我們將使用我們訓練好的模型預測這些海報的型別。該模型將告訴我們每種型別的概率,我們將從中獲得前3個預測結果。
1. classes = np.array(train.columns[2:])
2. proba = model.predict(img.reshape(1,400,400,3))
3. top_3 = np.argsort(proba[0])[:-4:-1]
4. for i in range(3):
5. print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
6. plt.imshow(img)
真棒!我們的模型為《權力的遊戲》預測了戲劇,驚悚和動作型別。在我看來,這個分類很好。讓我們在《復仇者聯盟》海報上試試我們的模型。影象預處理:
1. img = image.load_img('avengers.jpeg',target_size=(400,400,3))
2. img = image.img_to_array(img)
3. img = img/255
然後做預測:
1. classes = np.array(train.columns[2:])
2. proba = model.predict(img.reshape(1,400,400,3))
3. top_3 = np.argsort(proba[0])[:-4:-1]
4. for i in range(3):
5. print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
6. plt.imshow(img)
我們的模型給出的型別是戲劇、動作和驚悚。同樣,這些都是非常準確的結果。這個模型能在好萊塢電影分類上表現的一樣優秀嗎?讓我們來看看。我們將使用這張Golmal 3的海報。
你知道在這個階段該做什麼——載入和預處理的影象:
1. img = image.load_img('golmal.jpeg',target_size=(400,400,3))
2. img = image.img_to_array(img)
3. img = img/255
然後為這個海報預測電影型別:
1. classes = np.array(train.columns[2:])
2. proba = model.predict(img.reshape(1,400,400,3))
3. top_3 = np.argsort(proba[0])[:-4:-1]
4. for i in range(3):
5. print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
6. plt.imshow(img)
《Golmaal 3》是一部喜劇,我們的模型預測它為最受歡迎的型別。其他預測型別是劇情片和浪漫片——相對準確的評估。我們可以看到該模型能夠僅通過海報預測電影型別。
6. 接下來的步驟和你自己的實驗
這就是如何解決多標籤影象分類問題。儘管我們只有大約7000張圖片來訓練模型,但我們的模型表現得非常好。
你可以嘗試收集更多的訓練海報。我的建議是使所有的流派類別有相對平等的分佈的資料集。為什麼?
如果某一型別在大多數訓練影象中重複出現,那麼我們的模型可能會與該型別過度匹配。對於每一張新圖片,該模型都可能預測出相同的型別。為了克服這個問題,你應該嘗試均衡的流派類別分佈。
這些是你可以嘗試改進模型效能的一些關鍵點。你還能想到別的嗎?告訴我!
7. 尾記
除了流派型別預測外,多標籤影象分類還有多種應用。例如,你可以使用此技術自動標記影象。假設你想預測影象中服裝的型別和顏色。你可以建立一個多標籤影象分類模型,這將幫助你預測同時兩者!
希望本文能幫助你理解多標籤影象分類的概念。如果你有任何反饋或建議,請在下面的評論部分與我們分享。實驗快樂!
原文連結:
https://www.analyticsvidhya.com/blog/2019/04/build-first-multi-label-image-classification-model-python/
原文標題:
Build your First Multi-Label Image Classification Model in Python