
“工欲善其事,必先利其器”。如果直接使用 Python 完成模型的構(gòu)建、導(dǎo)出等工作,勢必會耗費相當多的時間,而且大部分工作都是深度學(xué)習(xí)中共同擁有的部分,即重復(fù)工作。所以本案例為了快速實現(xiàn)效果,就直接使用將這些共有部分整理成框架的 TensorFlow 和 Keras 來完成開發(fā)工作。TensorFlow 是 Google 公司開源的基于數(shù)據(jù)流圖的科學(xué)計算庫,適合用于機器學(xué)習(xí)、深度學(xué)習(xí)等人工智能領(lǐng)域。Keras 是一個用 Python 編寫的高級神經(jīng)網(wǎng)絡(luò) API,它能夠以 TensorFlow、CNTK 或 Theano 作為后端運行。Keras 的開發(fā)重點是支持快速的實驗,所以,本案例中,大部分與模型有關(guān)的工作都是基于 Keras API 來完成的。而現(xiàn)在版本的 TensorFlow 已經(jīng)將 Keras 集成了進來,所以只需要安裝 TensorFlow 即可。注意,由于本案例采用的 ResNet 網(wǎng)絡(luò)較深,所以模型訓(xùn)練需要消耗的資源較多,需要 GPU 來加速訓(xùn)練過程。
1、環(huán)境安裝
安裝 TensorFlow 的 GPU 版本是相對比較繁雜的事情,需要找對應(yīng)的驅(qū)動,安裝合適版本的 CUDA 和 cuDNN。而一種比較方便的辦法就是使用 Anaconda 來進行 tensorflow-gpu 的安裝。具體的安裝過程可以參考本書的附錄 A.2 部分。其他需要安裝的依賴包的名稱及版本號如下:
其他依賴包可以在 Anaconda 界面上進行選擇安裝,也可以將其添加到 requirements.txt 文件,然后使用 conda install -yes -file requirements.txt 命令進行安裝。另外,Conda 可以創(chuàng)建不同的環(huán)境來支持不同的開發(fā)要求。例如,有些工程需要 TensorFlow 1.15.0 環(huán)境來進行開發(fā),而另外一些工程需要 TensorFlow 2.1.0 來進行開發(fā),替換整個工作環(huán)境或者重新安裝 TensorFlow 都不是很好的選擇。所以,本案例使用 Conda 創(chuàng)建虛擬環(huán)境來解決。
2、數(shù)據(jù)集簡介
在進行模型構(gòu)建和訓(xùn)練之前,需要進行數(shù)據(jù)收集。為了簡化收集工作,本案例采用已標記好的花卉數(shù)據(jù)集 Oxford 102 Flowers。數(shù)據(jù)集可以從 VGG 官方網(wǎng)站上進行下載。單擊如圖 1 所示的 Downloads 區(qū)域的 1、4 和 5 對應(yīng)的超鏈接就可以下載所需要的文件。

■ 圖 1 Oxford 102 Flowers 數(shù)據(jù)集下載網(wǎng)站
該數(shù)據(jù)集由牛津大學(xué)工程科學(xué)系于 2008 年發(fā)布,是一個英國本土常見花卉的圖片數(shù)據(jù)集,包含 102 個類別,每類包含 40 ~ 258 張圖片。在基于深度學(xué)習(xí)的圖像分類任務(wù)中,這樣較為少量的圖片還是比較有挑戰(zhàn)性的。Oxford 102 Flowers 的分類細節(jié)和部分類別的圖片及對應(yīng)的數(shù)量如圖 2 所示。

■ 圖 2 Oxford 102 Flowers 的分類細節(jié)和部分類別的圖片及對應(yīng)的數(shù)量
除了圖片文件(dataset images),數(shù)據(jù)集中還包含圖片分割標記文件(image segmentations)、分類標記文件(the image iabels)和數(shù)據(jù)集劃分文件(the data splits)。由于本案例中不涉及圖片分割,所以使用的是圖片、分類標記和數(shù)據(jù)集劃分文件。
3、數(shù)據(jù)集的下載與處理
Python urllib 庫提供了 urlretrieve()函數(shù)可以直接將遠程數(shù)據(jù)下載到本地??梢允褂?urlretrieve()函數(shù)下載所需文件;然后把壓縮的圖片文件進行解壓,并解析分類標記文件和數(shù)據(jù)集劃分文件;再根據(jù)數(shù)據(jù)集劃分文件并分成訓(xùn)練集、驗證集和測試集;最后,向不同類別的數(shù)據(jù)集中按圖片所標識的花的種類分類存放圖片文件。代碼及詳細注釋如代碼清單 1 所示。
代碼清單 1
import os
from urllib.request import urlretrieve
import tarfile
from scipy. io import loadmat2
from shutil import copyfile
import glob
import numpy as np
"""
函數(shù)說明:按照分類(labels)復(fù)制未分組的圖片到指定的位置10
Parameters:
data path - 數(shù)據(jù)存放目錄
labels - 數(shù)據(jù)對應(yīng)的標簽,需要按標簽放到不同的目錄
"""
def copy_data_files(data path, labels) :
if not os. path, exists( data path) :
os.mkdir(data path)
# 創(chuàng)建分類目錄
for i in range(0,102) :
os.mkdir(os.path.join( data path, str(i)))
for label in labels:
src path = str(label[0])
dst path = os.path. join(data path, label[1], src path. split(os. sep)[ - 1])
copyfile(src path, dst path)
if_name_ _== '_main_':
# 檢查本地數(shù)據(jù)集目錄是否存在,若不存在,則需創(chuàng)建
data set path = "./data'
if not os. path. exists( data set path) :
os.mkdir(data set path)
#下載 102 Category Elower 數(shù)據(jù)集并解壓
flowers archive file = "102flowers.tgz'
flowers_url frefix = "https://www,robots.ox.ac.uk/~vgg/data/flowers/102/'
flowers archive path = os.path, join(data set path, flowers archive file)
if not os path.exists(flowers archive path) :
print("正在下載圖片文件...")
urlretrieve(flowers url frefix + flowers archive file, flowers archive path)
print("圖片文件下載完成.")
print("正在解壓圖片文件...")
tarfile. open(flowers archive path)..extractall(path = data set_path)
print("圖片文件解壓完成,")
# 下載標識文件,標識不同文件的類別
flowers labels file = "imagelabels.mat'
flowers labels path = os.path. join(data set path, flowers labels file)
if not os.path.exists(flowers labels path) :
print("正在下載標識文件...")
urlretrieve(flowers url frefix + flowers labels file, flowers labels path)
print("標識文件下載完成")
flower_labels = loadmat(flowers_labels_path)['labels'][0] - 1
#下載數(shù)據(jù)集分類文件,包含訓(xùn)練集、驗證集和測試集
sets splits file = "setid.mat"
sets splits_path = os.path. join(data set path, sets splits file)
if not os.path,exists( sets splits path) :
print("正在下載數(shù)據(jù)集分類文件...")
urlretrieve(flowers url frefix + sets splits file, sets splits path)
print("數(shù)據(jù)集分類文件下載完成")
sets_splits = loadmat( sets splits path)
# 由于數(shù)據(jù)集分類文件中測試集數(shù)量比訓(xùn)練集多,所以進行了對調(diào)
train set = sets splits['tstid'][0] - 1
valid set = sets splits[ 'valid'][0] - 1
test_set = sets splits['trnid'][0] - 1
# 獲取圖片文件名并找到圖片對應(yīng)的分類標識
image files = sorted(glob.glob(os.path. join(data set path, 'jpg', ' x .jpg')))
image labels = np.array([i for i in zip(image files, flower labels)])
# 將訓(xùn)練集、驗證集和測試集分別放在不同的目錄下
print("正在進行訓(xùn)練集的復(fù)制...")
copy_data files(os.path. join(data set path, 'train'), image labels[train set, :]
print("已完成訓(xùn)練集的復(fù)制,開始復(fù)制驗證集...")
copy_data files(os.path. join(data_set_path, 'valid'), image labels[valid set, :]
print("已完成驗證集的復(fù)制,開始復(fù)制測試集...")
copy_data files(os.path, join(data set_path, 'test'), image labels[test set, :]
print("已完成測試集的復(fù)制,所有的圖片下載和預(yù)處理工作已完成.")
下載的圖片數(shù)據(jù)有 330MB 左右。國外的網(wǎng)站有時候下載比較慢,可以用下載工具下載,或者使用參考書前言中提供的二維碼進行下載。
需要說明的是,分類標記文件 imagelabels.mat 和數(shù)據(jù)集劃分文件 setid.mat 是 MATLAB 的數(shù)據(jù)存儲的標準格式,可以用 MATLAB 程序打開進行查看。本案例中使用 scipy 庫的 loadmat()函數(shù)對 .mat 文件進行讀取。圖片分類后的目錄結(jié)構(gòu)如圖 3 所示。文章來源:http://www.zghlxwxcb.cn/news/detail-407213.html

■ 圖 3 圖片分類后的目錄結(jié)構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-407213.html
到了這里,關(guān)于PyTorch 深度學(xué)習(xí)實戰(zhàn) | 基于 ResNet 的花卉圖片分類的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!