甘 麗
(馬鞍山師范高等??茖W(xué)校,安徽 馬鞍山 243041)
目標識別與分類一直是計算機視覺領(lǐng)域重要的一個應(yīng)用方向,早期的利用尺度不變特征變換[1]、利用方向梯度直方圖等方法因其不能支持太大的數(shù)據(jù)規(guī)模,模型的泛化能力較差,目標檢測技術(shù)的發(fā)展受到一定限制[1]。神經(jīng)網(wǎng)絡(luò)在機器學(xué)習(xí)中的提出,使得目標檢測有了新的發(fā)展,但受計算機性能限制,其理論存在解釋性差,訓(xùn)練時間長等缺點。90年代中期,支持向量機、邏輯回歸等機器學(xué)習(xí)算法的興起也對神經(jīng)網(wǎng)絡(luò)的發(fā)展帶來重大打擊。然而,隨著計算機性能的提高,2006年Hinton教授等人提出深度學(xué)習(xí)概念,讓目標檢測領(lǐng)域有了新的希望與發(fā)展。Chen等人提出利用深度學(xué)習(xí)原理在SAR(Synthetic Aperture Radar)圖像上實現(xiàn)目標識別,在MSTAR數(shù)據(jù)集上的實驗取得了良好的效果[2]。目標識別技術(shù)被廣泛應(yīng)用于人臉識別、自動駕駛、安防監(jiān)控等各個領(lǐng)域。
通過研究卷積神經(jīng)網(wǎng)絡(luò)原理,分析VGG算法模型并進行遷移學(xué)習(xí),在車輛類型的目標檢測中成功應(yīng)用。文中描述了實現(xiàn)車輛品牌類別目標檢測的關(guān)鍵步驟,對圖像目標檢測的應(yīng)用開發(fā)有積極參考作用。
在道路目標檢測領(lǐng)域,檢測不同種類的車輛如貨車、小汽車、行人、騎行人等已有不少成熟的研究[3],本課題主要研究利用遷移學(xué)習(xí)的方法對檢測目標進一步細化,檢測各種不同品牌的小汽車,為道路交通中的目標檢測提供積極的參考作用。采用卷積神經(jīng)網(wǎng)絡(luò)VGG16模型來解決10個車輛品類的目標檢測問題,利用VGG網(wǎng)絡(luò)的預(yù)訓(xùn)練模型,對其進行微調(diào),建立自己的網(wǎng)絡(luò)結(jié)構(gòu),通過訓(xùn)練集數(shù)據(jù)對模型進行訓(xùn)練得到目標模型,然后利用目標模型對測試集數(shù)據(jù)進行預(yù)測,模型學(xué)習(xí)檢測流程如圖1所示。
圖1 模型學(xué)習(xí)檢測流程圖
在計算機視覺領(lǐng)域,圖像特征數(shù)量會對神經(jīng)網(wǎng)絡(luò)效果產(chǎn)生較大壓力,使用卷積神經(jīng)網(wǎng)絡(luò)能很好解決此問題。卷積神經(jīng)網(wǎng)絡(luò)有一個或多個卷積層、池化層以及全連接層等組成[4]。卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)圖如圖2所示。
圖2 卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)圖
卷積層的作用是提取輸入的不同特征,主要參數(shù)有卷積核Size的大小,padding-零填充,stride步長等。通過卷積層的計算能在提取特征的同時不減少圖片特征數(shù)量,但在最后的全連接層依然面臨大量參數(shù),所以需要池化層進行特征數(shù)量的減少。
池化層的作用是對卷積層學(xué)習(xí)到的特征圖進行亞采樣處理,池化方式主要有最大池化和平均池化兩種,目的是為了降低后續(xù)網(wǎng)絡(luò)層的輸入維度,縮減模型大小,提高計算速度。
卷積層、激活層、池化層可以看成是學(xué)習(xí)特征提取層,而學(xué)習(xí)到的特征最終應(yīng)用于模型任務(wù)需要先對所有特征圖扁平化處理,再接一個或多個全連接層,進行模型學(xué)習(xí)[5]。
VGG是非常經(jīng)典的卷積神經(jīng)網(wǎng)絡(luò)模型,該模型結(jié)構(gòu)清晰,層參數(shù)簡單。因其有13個卷積層和3個全連接層,也被稱為VGG16模型。所有卷積層都采用小卷積核(3*3),步長為1,所有池化層都采用2*2池化,步長為2。
模型的訓(xùn)練主要包括模型的訓(xùn)練步驟和數(shù)據(jù)增強。
1.2.1 目標模型訓(xùn)練的步驟
目標模型的訓(xùn)練分為2個階段:預(yù)訓(xùn)練階段和訓(xùn)練集階段。預(yù)訓(xùn)練的VGGNet是在AlexNet的基礎(chǔ)上反復(fù)堆疊3*3的小型卷積核和2*2的最大池化層,不斷加深網(wǎng)絡(luò)結(jié)構(gòu),在CIFAR10的數(shù)據(jù)集上進行訓(xùn)練。訓(xùn)練集階段:在預(yù)訓(xùn)練的模型的基礎(chǔ)上,修改最后輸出結(jié)構(gòu),利用自制數(shù)據(jù)集對剩余網(wǎng)絡(luò)結(jié)構(gòu)進行訓(xùn)練,最后對網(wǎng)絡(luò)模型進行參數(shù)微調(diào)。實驗的目標模型中,預(yù)訓(xùn)練模型引用TensorFlow提供的VGG16模型,目標模型的訓(xùn)練過程如圖3所示。
圖3 目標模型訓(xùn)練圖
1.2.2 數(shù)據(jù)增強
在深度學(xué)習(xí)中,對輸入數(shù)據(jù)進行數(shù)據(jù)增強,可以豐富圖像的訓(xùn)練集,更好地提取圖像特征,泛化模型,數(shù)據(jù)增強還有一個很重要的作用是可以將圖片轉(zhuǎn)化成符合算法的大小要求,比如YOLO算法中圖片大小都要變換成448×448。
數(shù)據(jù)增強一般是通過剪切、旋轉(zhuǎn)、縮放變化、尺度變換、顏色變換等一種或多種組合數(shù)據(jù)增強變換的方式來增加數(shù)據(jù)集的大小[6]。
實驗中,因采集的圖片數(shù)量沒有足夠大,需要減少數(shù)據(jù)集中不相關(guān)特征的數(shù)量。對于實驗中的汽車分類器來說,將現(xiàn)有數(shù)據(jù)集中照片翻轉(zhuǎn)獲得新的數(shù)據(jù)集。通過增強數(shù)據(jù)集,可以有效防止神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)到不相關(guān)的模式,提升效果。
利用Keras框架里面已經(jīng)訓(xùn)練好的VGG16模型,對其進行微調(diào),來做本研究中車輛類別的遷移學(xué)習(xí)實踐。
使用一個ImageDataGenerator圖片生成器,定義圖片處理以及數(shù)據(jù)增強相關(guān)功能,主要實現(xiàn)代碼如下:def __init__(self):
# 1.實例化圖片生成器
# rescale:做歸一化
self.train_generator = ImageDataGenerator(rescale=1. / 255)
self.test_generator = ImageDataGenerator(rescale=1. / 255)
# 指定讀取數(shù)據(jù)的相關(guān)參數(shù)
self.train_dir = “./data/train”
self.test_dir = “./data/test”
self.model_size = (224, 224)
self.batch_size = 32
# 定義基礎(chǔ)模型VGG(沒有最后三個全連接層的結(jié)構(gòu))
self.base_model = VGG16(weights=“imagenet”, include_top=False)
def read_local_data(self):
# 讀取訓(xùn)練數(shù)據(jù)集構(gòu)造gen目標值格式
# 輸入到VGG的形狀
# 目標值的類型
train_gen = self.train_generator.flow_from_directory(directory=self.train_dir,#讀取目錄
target_size=self.model_size,#目標形狀
class_mode=“binary”,#目標值格式
batch_size=self.batch_size,#批數(shù)量大小(樣本批次)
shuffle=True)#讀取的時候打亂數(shù)據(jù)
test_gen = self.test_generator.flow_from_directory(directory=self.test_dir,
target_size=self.model_size,
class_mode=“binary”,
batch_size=self.batch_size,shuffle=True)
return train_gen, test_gen
在不動VGG 輸出結(jié)果的基礎(chǔ)上,加上全局池化層和兩個全連接層,構(gòu)建自己的模型,實現(xiàn)代碼如下:def refine_base_model(self):
x = self.base_model.outputs[0]
x = keras.layers.GlobalAveragePooling2D()(x)
#兩個全連接層1024, 5
x = keras.layers.Dense(1024,activation=tf.nn.relu)(x)
y_prediction = keras.layers.Dense(10,activation=tf.nn.softmax)(x)
#構(gòu)建自己的model
model = Model(inputs=self.base_model.inputs, outputs=y_prediction)
return model
讓 VGG 結(jié)構(gòu)當(dāng)中的權(quán)重參數(shù)不參與訓(xùn)練,代碼如下:
def freeze_base_model(self):
for layer in self.base_model.layers:
layer.trainable = False
return None
編譯(指定優(yōu)化器,定義損失函數(shù),定義準確率)、訓(xùn)練模型,在遷移學(xué)習(xí)算法中,學(xué)習(xí)率初始化為較小的值:0.001,0.0001。因為是在已訓(xùn)練好的模型基礎(chǔ)上更新,所以設(shè)置較小的學(xué)習(xí)率去學(xué)習(xí)。將訓(xùn)練好的模型保存為h5文件格式,實現(xiàn)代碼如下:
def compile(self,transfer_model):
transfer_model.compile(optimizer=keras.optimizers.Adam(),
loss=keras.losses.sparse_categorical_crossentropy,
metrics=[“accuracy”])
def fit(self,model,train_gen,test_gen):
model.fit_generator(train_gen,epochs=30,validation_data=test_gen)
model.save_weights(“./Transfer.h5”)
采用的是TensorFlow平臺,利用Keras框架,采集的數(shù)據(jù)集的統(tǒng)計信息,如表1所列。
表1 訓(xùn)練集和測試集的統(tǒng)計信息
通過實驗,典型測試結(jié)果如圖4所示。
圖4 典型的測試結(jié)果
在設(shè)置30個epoch后,10個車輛品類的訓(xùn)練集精度達近95%,測試集平均精度也達到了近90%。具體精度如表2所示。
表2 各個數(shù)據(jù)集的訓(xùn)練和測試精度值
在增加epoch為50、設(shè)置bath_size值為64,128后,訓(xùn)練精度有所提升,但測試集精度并未明顯提升。
利用深度學(xué)習(xí)模型VGG解決車輛品類的目標檢測問題,采用VGG16模型結(jié)構(gòu), 以ImageNet預(yù)訓(xùn)練卷積層,固定卷積層用自建的車輛品類訓(xùn)練集對剩余網(wǎng)絡(luò)進行預(yù)訓(xùn)練;通過加上池化層和兩個全連接層來微調(diào)網(wǎng)絡(luò)結(jié)構(gòu),構(gòu)建自己的模型;指定優(yōu)化器,定義損失函數(shù),定義準確率后編譯訓(xùn)練,形成Transfer.h5模型文件。實驗結(jié)果表明:深度學(xué)習(xí)算法能很好的提高模型泛化能力,模型在10個品類的測試集上準確率達到近90%。