快速構建深度學習影像資料集,微軟Bing和Google哪個更好用?
譯者 | Serene
編輯 | 明明
出品 | AI 科技大本營(公眾號ID:rgznai100)
【AI 科技大本營導讀】在本文中,作者將利用微軟的 Bing Image Search API 來建立深度學習影像資料集。Bing Image Search API 是微軟 Cognitive Services 的一個組成部分,主要是幫助使用者在視覺、語言、文字等手機應用和軟體中應用AI。相比較,利用 Google Images 來構建自己的資料集是一個乏味且需要手動的過程,主要原因是因為多年前,谷歌關停了自己的影像搜尋 API ,然而,我們需要的是一個通過查詢能夠自動下載影像的方案。
▌建立 Cognitive Services 帳戶
在本節中,我將會向你演示如何申請一個免費的Bing Image Search API賬戶。點開連結Bing Image Search API (https://azure.microsoft.com/en-us/try/cognitive-services/?api=bing-image-search-api),開始我們的註冊流程:
圖1:微軟 Bing Image Search API 註冊入口
從上圖的截圖中我們可以看到,這個試用版囊括了 Bing 中所有搜尋 API ,每月都有 3000 筆交易實現,已經能夠滿足使用者需求,這對於建立第一個深度學習影像資料集來說已將完全夠用了。
若要註冊 Bing Image Search API,請點選 “Get API Key” 按鍵。可以通過微軟賬號、Facebook 賬號、領英賬號甚至是 GitHub 賬號來註冊(方便起見我是用了GitHib賬號進行註冊的)。當完成註冊以後,就會看到如下圖中我的瀏覽器展示的頁面內容。
圖2:Microsoft Bing API 端點以及我需要使用該API時的金鑰
此時可以看到我的頁面中 Bing 搜尋終結點列表,包括兩個 API 金鑰。(請牢記的 API 金鑰,在下一節中就會用到它)
▌使用 Python 來構建你的深度學習資料集
在註冊完 Bing Image Search API 賬戶之後,現在我們已經做完了建立深度學習資料集的前期準備。
閱讀文件
在繼續下面的操作之前,我建議在瀏覽器中開啟下面兩個Bing影像搜尋API文件頁面:
Bing 影像搜尋 API – Python QuickStart(https://docs.microsoft.com/en-us/azure/cognitive-services/bing-image-search/quickstarts/python)
Bing 影像搜尋 API – Paging Webpages(https://docs.microsoft.com/en-us/azure/cognitive-services/bing-web-search/paging-webpages)
如果對 API 的工作原理或是當提出請求之後如何使用 API 依然存有疑問,可以參考上述兩個文件。
安裝 request 包
如果你的電腦系統中沒有安裝 request ,你可以通過如下方式來安裝:
$pip install requests
安裝Request包之後你會發現,向 HTTP 傳送請求會變得非常容易,而且能保證我們在向 Python 發出請求時不會遇到各種棘手的困難。除此之外請注意,如果你在虛擬環境中使用 Python ,那麼你需要在終端裡使用 workon 來訪問虛擬環境,再去安裝 request。
$ workon your_env_name
$ pip install requests
編寫你自己的Python影像下載程式碼
讓我們繼續向下走,開啟程式設計之旅。開啟一個新的指令碼檔案,將其命名 search_bing_api.py,為並在指令碼中輸入下述程式碼:
# import the necessary packages
from requests import exceptions
import argparse
import requests
import cv2
import os
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-q", "--query", required=True,
help="search query to search Bing Image API for")
ap.add_argument("-o", "--output", required=True,
help="path to output directory of images")
args = vars(ap.parse_args())
匯入此指令碼中所需的軟體包。你需要在虛擬環境中提前安裝好 OpenCV 和 requests 。下面這個連結(https://www.pyimagesearch.com/opencv-tutorials-resources-guides/)給出了在系統中安裝 OpenCV 的相關教程。
接下來,我們來講解一下兩個命令列引數:
“query”:指的是你想要搜尋的影像關鍵字或特徵,比如說“神奇寶貝”、”聖誕老人”或者是“侏羅紀公園”之類的。
“output”:影像的輸出目錄路徑。我個人偏向於把影像分成獨立的類子目錄,因此在呼叫函式時,一定要指定你想下載的影像儲存進入的正確資料夾(如下面 “下載影像進行培訓深度神經網路” 部分所示)。
在這個指令碼中你不需要去修改命令列的任何引數,這些引數是程式執行時的輸入量。如果你不明白怎麼正確使用命令列引數,請參考我以前的部落格文章 my recent blog post(https://www.pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/)。
接下來配置一些全域性變數:
# set your Microsoft Cognitive Services API key along with (1) the
# maximum number of results for a given search and (2) the group size
# for results (maximum of 50 per request)
API_KEY = "YOUR_API_KEY_GOES_HERE"
MAX_RESULTS = 250
GROUP_SIZE = 50
# set the endpoint API URL
URL = "https://api.cognitive.microsoft.com/bing/v7.0/images/search"
在使用上述程式碼的時候,讀者必須更改 API_KEY 的值。請登入到 Microsoft Cognitive Services 並選擇要使用的服務來獲取 API 金鑰(如上所示,需要單擊“獲取 API 金鑰”按鈕),然後只需將 API 金鑰貼上到該變數的引號內即可。
當然在實際程式設計的時候也可以更改 MAX_RESULTS和GROUP_SIZE 這兩個引數的值。我在示例中只要求資料庫中有 250 張圖片,一共 5 次搜尋,每次搜尋返回最多 50 張圖片(可以通過改變 MMAX_RESULTS 引數來更改這個數量),同時我要求 Bing API 在每次執行搜尋和下載圖片命令時,都要返回單次下載下來的圖片數量值。
你也可以把 GROUP_SIZE 的引數看作是 per page 的返回值的數量。因此如果我們一共需要 250 張圖片,就需要把 “pages” 引數調成 5,“per page” 的值賦成 50。
注意:
1、所下載的圖片一定要與搜尋的關鍵詞有關係;
2、操作過程需要在 Bing AI 的免費服務範圍之內(否則就需要為所要求的服務付費)。
現在一起來看一看,在準備階段我們會碰到的所有可能的異常。這些異常可能會在獲取映像時出現。我先列出可能遇到的異常:
# when attempting to download images from the web both the Python
# programming language and the requests library have a number of
# exceptions that can be thrown so let's build a list of them now
# so we can filter on them
EXCEPTIONS = set([IOError, FileNotFoundError,
exceptions.RequestException, exceptions.HTTPError,
exceptions.ConnectionError, exceptions.Timeout])
在處理網路請求時,我們可能會丟擲一些異常,我們將嘗試找到他們並加以妥善解決。
接下來讓我們初始化搜尋引數並進行搜尋:
# store the search term in a convenience variable then set the
# headers and search parameters
term = args["query"]
headers = {"Ocp-Apim-Subscription-Key" : API_KEY}
params = {"q": term, "offset": 0, "count": GROUP_SIZE}
# make the search
print("[INFO] searching Bing API for '{}'".format(term))
search = requests.get(URL, headers=headers, params=params)
search.raise_for_status()
# grab the results from the search, including the total number of
# estimated results returned by the Bing API
results = search.json()
estNumResults = min(results["totalEstimatedMatches"], MAX_RESULTS)
print("[INFO] {} total results for '{}'".format(estNumResults,
term))
# initialize the total number of images downloaded thus far
total = 0
對搜素變數引數進行了初始化。在執行該操作時若有任何問題請參閱相關 API documentation(https://docs.microsoft.com/en-us/rest/api/cognitiveservices/bing-images-api-v7-reference)。
接下來我們執行搜尋命令,並以 JSON 格式獲取結果。我們執行了計算命令並輸出下一個終端的預計下載圖片數量。將總數進行初始化,因為之後要記錄下載圖片的總數量。
接下來執行程式,得到 GROUP_SIZE 的迴圈結果:
# loop over the estimated number of results in `GROUP_SIZE` groups
for offset in range(0, estNumResults, GROUP_SIZE):
# update the search parameters using the current offset, then
# make the request to fetch the results
print("[INFO] making request for group {}-{} of {}...".format(
offset, offset + GROUP_SIZE, estNumResults))
params["offset"] = offset
search = requests.get(URL, headers=headers, params=params)
search.raise_for_status()
results = search.json()
print("[INFO] saving images for group {}-{} of {}...".format(
offset, offset + GROUP_SIZE, estNumResults))
執行迴圈,通過迴圈得到 GROUP_SIZE 批處理結果的估計量(這是 API 允許的)。
當呼叫 requests.get 來獲取 JSON blob時,當前偏移量會作為引數被傳遞。
現在嘗試儲存當前批次中的影像:
# loop over the results
for v in results["value"]:
# try to download the image
try:
# make a request to download the image
print("[INFO] fetching: {}".format(v["contentUrl"]))
r = requests.get(v["contentUrl"], timeout=30)
# build the path to the output image
ext = v["contentUrl"][v["contentUrl"].rfind("."):]
p = os.path.sep.join([args["output"], "{}{}".format(
str(total).zfill(8), ext)])
# write the image to disk
f = open(p, "wb")
f.write(r.content)
f.close()
# catch any errors that would not unable us to download the
# image
except Exception as e:
# check to see if our exception is in our list of
# exceptions to check for
if type(e) in EXCEPTIONS:
print("[INFO] skipping: {}".format(v["contentUrl"]))
continue
接下來我們將迴圈播放當前這一批影像,並嘗試將每個影像下載到我們的輸出路徑資料夾中。
建立一個 try-catch 塊,以便我們捕捉到我們之前在指令碼中定義的可能的異常情況。如果遇到異常,我們將跳過該特定影像並繼續下載後面的圖片。
在 try 程式碼塊內部我們通過 URL獲取影像,併為它建立一個路徑+檔名。
然後我們嘗試開啟影像,並將檔案寫入磁碟。需要注意的是,我們在 “wb” 中建立了一個由 b 表示的二進位制檔案物件,然後訪問二進位制資料 viar.content。
接下來,我們看看 OpenCV 能否實際載入影像。如果能實現該操作,則說明:1、影像檔案已成功下載,2、影像路徑有效:
# try to load the image from disk
image = cv2.imread(p)
# if the image is `None` then we could not properly load the
# image from disk (so it should be ignored)
if image is None:
print("[INFO] deleting: {}".format(p))
os.remove(p)
continue
# update the counter
total += 1
只要影像資料不是無,我們就需要更新計數器(每次加1)並迴圈回到頂部。
否則,我們需要呼叫 os.remove 刪除無效映像,然後繼續回到初始迴圈,同時不更新計數器。 if 語句可能由於下載檔案時出現網路錯誤,未安裝正確的影像 I / O 庫等原因被觸發。如果想要了解更多關於 OpenCV 和 Python 中的 NoneType 錯誤的資訊,請參閱此處網頁refer to this blog post(https://www.pyimagesearch.com/2016/12/26/opencv-resolving-nonetype-errors/)。
▌下載影像訓練深度學習神經網路系統
既然已經寫好了程式碼,現在就讓我們使用 Bing’s Image Search API 來下載深度學習資料集的影像。(需要使用本文的 “Download” 部分下載程式碼和示例目錄結構。)
現在建立一個資料集目錄:
$mkdirdataset
把下載的所以影像都儲存在資料集裡,執行以下命令來建立子目錄並搜尋 “charmander” (小火龍):
$ mkdir dataset/charmander
$ python search_bing_api.py --query "charmander" --output dataset/charmander
[INFO] searching Bing API for 'charmander'
[INFO] 250 total results for 'charmander'
[INFO] making request for group 0-50 of 250...
[INFO] saving images for group 0-50 of 250...
[INFO] fetching: http://fc06.deviantart.net/fs70/i/2012/355/8/2/0004_c___charmander_by_gaghiel1987-d5oqbts.png
[INFO] fetching: http://th03.deviantart.net/fs71/PRE/f/2010/067/5/d/Charmander_by_Woodsman819.jpg
[INFO] fetching: http://fc05.deviantart.net/fs70/f/2011/120/8/6/pokemon___charmander_by_lilnutta10-d2vr4ov.jpg
...
[INFO] making request for group 50-100 of 250...
[INFO] saving images for group 50-100 of 250...
...
[INFO] fetching: http://38.media.tumblr.com/f0fdd67a86bc3eee31a5fd16a44c07af/tumblr_nbhf2vTtSH1qc9mvbo1_500.gif
[INFO] deleting: dataset/charmander/00000174.gif
...
正如我在這篇文章開頭提到的,我們需要為搭建自己的 Pokedex 下載一些 Pokemon 的影像。
在上面的程式碼中,我正在下載一個受非常歡迎的寵物精靈—— 小火龍 Charmander 的影像。250 張圖片中,大部分都會成功下載;但是如上圖的輸出所示,有一些 OpenCV 無法開啟的檔案將被刪除。
同樣的,我們用上面的程式碼來下載皮卡丘的影像:
$ mkdir dataset/pikachu
$ python search_bing_api.py --query "pikachu" --output dataset/pikachu
[INFO] searching Bing API for 'pikachu'
[INFO] 250 total results for 'pikachu'
[INFO] making request for group 0-50 of 250...
[INFO] saving images for group 0-50 of 250...
[INFO] fetching: http://www.mcmbuzz.com/wp-content/uploads/2014/07/025Pikachu_OS_anime_4.png
[INFO] fetching: http://images4.fanpop.com/image/photos/23300000/Pikachu-pikachu-23385603-814-982.jpg
[INFO] fetching: http://images6.fanpop.com/image/photos/33000000/pikachu-pikachu-33005706-895-1000.png
...
還有傑尼龜(Squirtle) 的影像庫:
$ mkdir dataset/squirtle
$ python search_bing_api.py --query "squirtle" --output dataset/squirtle
[INFO] searching Bing API for 'squirtle'
[INFO] 250 total results for 'squirtle'
[INFO] making request for group 0-50 of 250...
[INFO] saving images for group 0-50 of 250...
[INFO] fetching: http://fc03.deviantart.net/fs71/i/2013/082/1/3/007_squirtle_by_pklucario-d5z1gj5.png
[INFO] fetching: http://fc03.deviantart.net/fs70/i/2012/035/b/2/squirtle_by_maii1234-d4oo1aq.jpg
[INFO] fetching: http://3.bp.blogspot.com/-yeK-y_dHCCQ/TWBkDZKi6vI/AAAAAAAAABU/_TVDXBrxrkg/s1600/Leo%2527s+Squirtle.jpg
...
同樣的,我們來處理妙蛙種子 (Bulbasaur) 的影像:
$ mkdir dataset/bulbasaur
$ python search_bing_api.py --query "bulbasaur" --output dataset/bulbasaur
[INFO] searching Bing API for 'bulbasaur'
[INFO] 250 total results for 'bulbasaur'
[INFO] making request for group 0-50 of 250...
[INFO] saving images for group 0-50 of 250...
[INFO] fetching: http://fc06.deviantart.net/fs51/f/2009/261/3/e/Bulbasaur_by_elfaceitoso.png
[INFO] skipping: http://fc06.deviantart.net/fs51/f/2009/261/3/e/Bulbasaur_by_elfaceitoso.png
[INFO] fetching: http://4.bp.blogspot.com/-b-dLFLsHtm4/Tq9265UAmjI/AAAAAAAAHls/CrkUUFrj6_c/s1600/001Bulbasaur+pokemon+firered+leafgreen.png
[INFO] skipping: http://4.bp.blogspot.com/-b-dLFLsHtm4/Tq9265UAmjI/AAAAAAAAHls/CrkUUFrj6_c/s1600/001Bulbasaur+pokemon+firered+leafgreen.png
[INFO] fetching: http://fc09.deviantart.net/fs71/i/2012/088/9/6/bulbasaur_by_songokukai-d4gecpp.png
...
最後下載超夢 (Mewtwo) 的影像:
$ mkdir dataset/mewtwo
$ python search_bing_api.py --query "mewtwo" --output dataset/mewtwo
[INFO] searching Bing API for 'mewtwo'
[INFO] 250 total results for 'mewtwo'
[INFO] making request for group 0-50 of 250...
[INFO] saving images for group 0-50 of 250...
[INFO] fetching: http://sickr.files.wordpress.com/2011/09/mewtwo.jpg
[INFO] fetching: http://4.bp.blogspot.com/-_7XMdCIyKDs/T3f-0h2X4zI/AAAAAAAABmQ/S2904beJlOw/s1600/Mewtwo+Pokemon+Wallpapers+3.jpg
[INFO] fetching: http://2.bp.blogspot.com/-3jDdQdPl1yQ/T3f-61gJXEI/AAAAAAAABmg/AUmKm65ckv8/s1600/Mewtwo+Pokemon+Wallpapers.jpg
...
下面讓我們通過一個黑科技命令來計算每次執行查詢命令時,程式下載的影像總數。
$ find . -type d -print0 | while read -d '' -r dir; do
> files=("$dir"/*)
> printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
> done
2 files in directory .
5 files in directory ./dataset
235 files in directory ./dataset/bulbasaur
245 files in directory ./dataset/charmander
245 files in directory ./dataset/mewtwo
238 files in directory ./dataset/pikachu
230 files in directory ./dataset/squirtle
在這裡我們可以看到,對於每一種神奇寶貝,相應的下載目錄下大約有 230-245 張圖片。理想情況下,我希望在圖片庫中,每種神奇寶貝都有 1,000 幅圖片左右,但為了做示例能簡單一些,又考慮到網路開銷(對於沒有快速/穩定的 Internet 連線的使用者),我只為每一隻神奇寶貝下載了 250 張圖片來當作圖片庫。
▌完善深度學習影像資料集
但是,我們每次下載下來的圖片並不一定全都和我們的搜尋關鍵詞有關係。雖說大部分應該都是這些神奇寶貝的圖片,但是總有幾張漏網之魚。不幸的是,這項工作是手動的,你需要到你的圖片目錄下一張一張去確認,然後刪掉與關鍵字不相符的圖片。
不過在蘋果電腦的 macOS 系統中這個過程還是非常快的。
我只需要開啟我的 “Finder” ,在 “CoverFloow” 檢視下,瀏覽所有圖片檔案即可。
圖3:.我正在使用 macOS 的 “Cover Flow” 檢視,以便快速瀏覽影像並過濾出我不想在深度學習資料集中使用的影像。
如果我發現了任何與關鍵字不相關的圖片,只需要在鍵盤上按 cmd+delete 刪除檔案即可。其他的作業系統上也有類似的快捷方式和工具。
刪除掉與目標不相關的圖片後,讓我們再重新做一次圖片計數:
$ find . -type d -print0 | while read -d '' -r dir; do
> files=("$dir"/*);
> printf "%5d files in directory %s\n" "${#files[@]}" "$dir";
> done
3 files in directory .
5 files in directory ./dataset
234 files in directory ./dataset/bulbasaur
238 files in directory ./dataset/charmander
239 files in directory ./dataset/mewtwo
234 files in directory ./dataset/pikachu
223 files in directory ./dataset/squirtle
看這個新的圖片計數結果——每個目錄下我都僅僅刪除了很少的不相關圖片,這說明 Bing Image Search API 還是非常好用的。
另外,在實際操作中還應該剔除下載重複的圖片,在這裡,我沒有做這個步驟是因為在剔除不相關圖片時,我沒有發現太多的重複(除了小火龍的圖片,不知道為什麼會有那麼多重複)。如果想了解如何查詢到重複,可以參考下面這篇文章:this blog post on image hashing(https://www.pyimagesearch.com/2017/11/27/image-hashing-opencv-python/)
▌結語
本文講解了如何利用 Microsoft’s Bing Image Search API 來快速建立我們自己的深度學習影像資料集。我們學習了通過使用 API 來自動下載圖片,這比使用 Google Image 時需要手動下載每一張圖片更為方便。如果你想按照本文所講述的知識實際操作一下的話,你可以選擇 Bing Image Search API ,另外它將提供 30 天的免費試用期。
原文作者:Adrian Rosebrock
原文連結:https://www.pyimagesearch.com/2018/04/09/how-to-quickly-build-a-deep-learning-image-dataset/
AI科技大本營現招聘AI記者和資深編譯,有意者請將簡歷投至:gulei@csdn.net,期待你的加入!
AI科技大本營讀者群(計算機視覺、機器學習、深度學習、NLP、Python、AI硬體、AI+金融、AI+PM方向)正在招募中,和你志同道合的小夥伴也在這裡!關注AI科技大本營微信公眾號,後臺回覆:讀者群,新增營長請務必備註姓名,研究方向。
☟☟☟點選 | 閱讀原文 | 檢視更多精彩內容
相關文章
- 深度學習資料集深度學習
- 資源 | 25個深度學習開源資料集,have fun !深度學習
- 機器學習,深度學習必備資料集機器學習深度學習
- 如何分分鐘構建強大又好用的深度學習環境?深度學習
- Ruby和Python哪個更強大?學習分析Python
- 構建深度學習和TensorFlow智慧應用深度學習
- 在 Google Colab 中快速實踐深度學習Go深度學習
- 深度學習(一)深度學習學習資料深度學習
- 使用Apache Spark和BigDL來構建深度學習驅動的大資料分析ApacheSpark深度學習大資料
- Java、PHP、Python哪個更容易學習?JavaPHPPython
- 深度學習(一)之MNIST資料集分類深度學習
- 專注深度學習模型精度和效能提升、資料採集清洗深度學習模型
- TensorFlow、Keras、CNTK...到底哪種深度學習框架更好用?Keras深度學習框架
- 重磅福利!!機器學習和深度學習學習資料合集機器學習深度學習
- 深度學習資料深度學習
- 新手學C和Python哪個更容易?Python
- 雲端計算和大資料學哪個好?雲端計算學習大資料
- 深度學習實驗資料集網站推薦深度學習網站
- 深度學習常用的資料集,包括各種資料跟影象資料深度學習
- PHP和Python哪個更適合Web開發?Python學習!PHPPythonWeb
- Java、PHP、Python哪個更容易學習?竟是它!JavaPHPPython
- webpack 快速構建 React 學習環境(1)WebReact
- 教你在R中使用Keras和TensorFlow構建深度學習模型Keras深度學習模型
- 從影像中檢測和識別表格,北航&微軟提出新型資料集TableBank微軟
- 【深度學習】深度解讀:深度學習在IoT大資料和流分析中的應用深度學習大資料
- 資料結構——並查集 學習筆記資料結構並查集筆記
- 如何用深度學習處理結構化資料?深度學習
- 影像分割中的深度學習:U-Net 體系結構深度學習
- 深度學習煉丹-資料處理和增強深度學習
- 【快速學習】docker構建java專案實踐DockerJava
- 快速學習丨使用Blazor構建Web應用BlazorWeb
- Google線上深度學習神器ColabGo深度學習
- 五個給機器學習和資料科學入門者的學習建議機器學習資料科學
- 相親和學習到底哪個重要?
- 學習哪個程式語言呢?Python和C#哪個好學?PythonC#
- 構建你的資料科學作品集:機器學習專案資料科學機器學習
- Access和Python學哪個好?學習分享!Python
- 10個python常用且好用的機器學習及深度學習庫!Python機器學習深度學習