項目背景
今天詳解以下Xception算法,同時應用它做一個鳥類識別。由于Xception模型在極大的減少了網(wǎng)絡參數(shù)量和計算復雜度的同時,可以保持卓越的性能表現(xiàn)。因此,Xception模型已經(jīng)被廣泛地應用與圖像分類、目標檢測等任務中。
本次實戰(zhàn)案例就是一個典型的圖像分類。
本次項目實戰(zhàn)鳥類數(shù)據(jù)集主要分為4類,分別為bananaquit(蕉林鶯)、Black Skimmer (黑燕鷗類)、Black Throated Bushtiti (黑喉樹鶯)、Cockatoo (鳳頭鸚鵡或葵花鸚鵡),總計565張。
本項目基于百度AI Studio平臺實現(xiàn),原項目地址為:https://aistudio.baidu.com/aistudio/projectdetail/6375104
一、理論基礎
1.前言
在計算機視覺領域,卷積神經(jīng)網(wǎng)絡(CNN)已經(jīng)成為最主流的方法,比如GoogLenet,VGG-16,Incepetion等模型。CNN史上的一個里程碑事件是ResNet模型的出現(xiàn),ResNet可以訓練出更深的CNN模型,從而實現(xiàn)更高的準確度。ResNet模型的核心是通過建立前面層與后面層之間的“短路連接”(shortcuts,skip connection),進而訓練出更深的CNN網(wǎng)絡。
隨著圖像分類的準確率不斷提高,網(wǎng)絡的深度越來越深,圖像分類的錯誤率也越來越低,從2012的AlexNet,2013年的ZFNet,2014年的GoogLeNet,再到后面2015年的ResNet,準確率已經(jīng)超過了人類的水平,所以單純從準確率方面考慮的話已經(jīng)很難提升了;因此人們就開始從其他方面考慮,比如參數(shù)量和計算量,軟硬件協(xié)同等。
今天我們要介紹的是Xception模型,Xception是Google繼Inception后提出的對Inception V3的另一種改進,主要是采用深度可分離卷積(Depthwise Separable Convolution)來替換原來Inception V3中的卷積操作。
2.設計理念
前面說了,由于CNN模型的精度已經(jīng)很難進一步提升,所以研究者們就把注意力放到了減少模型參數(shù)量和計算量上,因此Xception應運而生。而Xception就是研究者們在Inception V3模型上的進一步改進,通過用Depthwise Separable Convolution(深度可分離卷積)替換Inception V3中的多尺寸卷積核特征響應操作,最終達到了精度的略微提升和參數(shù)量的減少。在講解Xception之前,我們先對它的前身Inception進行一番了解,然后再一步步往Xception方面講述。
2.1 多尺寸卷積核
Inception 最初提出的版本,其核心思想就是使用多尺寸卷積核去觀察輸入數(shù)據(jù)。
舉個例子,我們看某個景象由于遠近不同,同一個物體的大小也會有所不同,那么不同尺度的卷積核觀察的特征就會有這樣的效果。于是就有了如下的網(wǎng)絡結構圖:
于是我們的網(wǎng)絡就變胖了,增加了網(wǎng)絡的寬度,同時也提高了對于不同尺度的適應程度。
2.2 點卷積
但是我們的網(wǎng)絡變胖了的同時,計算量也變大了,所以我們就要想辦法減少參數(shù)量來減少計算量,于是在 Inception v1 中的最終版本加上了 1x1 卷積核。
使用 1x1 卷積核對輸入的特征圖進行降維處理,這樣就會極大地減少參數(shù)量,從而減少計算。
舉個例子,輸入數(shù)據(jù)的維度是 256 維,經(jīng)過 1x1 卷積之后,我們輸出的維度是 64 維,參數(shù)量是原來的 1 4 \frac{1}{4} 41? 。
這就是 Pointwise Convolution,俗稱叫做 1x1 卷積,簡寫為 PW,主要用于數(shù)據(jù)降維,減少參數(shù)量。
也有使用 PW 做升維的,在 MobileNet v2 中就使用 PW 將 3 個特征圖變成 6 個特征圖,豐富輸入數(shù)據(jù)的特征。
想深入了解 MobileNet v2 的可以看看原文 MobileNet V2 - arxiv.org ,再對照地讀這篇MobileNet V2 論文初讀 - Michael Yuan。
2.3 卷積核替換
就算有了 PW ,由于 5x5 和 7x7 卷積核直接計算參數(shù)量還是非常大,訓練時間還是比較長,我們還要再優(yōu)化。
人類的智慧是無窮的,于是就想出了使用多個小卷積核替代大卷積核 的方法,這就是 Inception v3,如下圖所示:
使用兩個 3x3 卷積核來代替 5x5 卷積,效果上差不多,但參數(shù)量減少很多,達到了優(yōu)化的目的。不僅參數(shù)量少,層數(shù)也多了,深度也變深了。
除了規(guī)整的的正方形,我們還有分解版本的 3x3 = 3x1 + 1x3,這個效果在深度較深的情況下比規(guī)整的卷積核更好。
我們假設輸入 256 維,輸出 512 維,計算一下參數(shù)量:
5x5 卷積核
256
×
5
×
5
×
512
=
3276800
256\times5\times5\times512=3276800
256×5×5×512=3276800
兩個 3x3 卷積核
256
×
3
×
3
×
256
+
256
×
3
×
3
×
512
=
589824
+
1179648
=
1769472
256\times3\times3\times256+256\times3\times3\times512=589824+1179648=1769472
256×3×3×256+256×3×3×512=589824+1179648=1769472
結果對比
1769472
3276800
=
0.54
\frac{1769472}{3276800}=0.54
32768001769472?=0.54
我們可以看到參數(shù)量對比,兩個 3x3 的卷積核的參數(shù)量是 5x5 一半,可以大大加快訓練速度。
2.4 Bottleneck
我們發(fā)現(xiàn)就算用了上面的結構和方法,我們的參數(shù)量還是很大,于是乎我們結合上面的方法創(chuàng)造出了 Bottleneck 的結構降低參數(shù)量。
Bottleneck 三步走是先 PW卷積 對數(shù)據(jù)進行降維,再進行常規(guī)卷積核的卷積,最后 PW 卷積對數(shù)據(jù)進行升維。我們舉個例子,方便我們了解:
根據(jù)上圖,我們來做個對比計算,假設輸入 feature map 的維度為 256 維,要求輸出維度也是 256 維。有以下兩種操作:
● 直接使用 3x3 的卷積核。256 維的輸入直接經(jīng)過一個 3×3×256 的卷積層,輸出一個 256 維的 feature map ,那么參數(shù)量為:256×3×3×256 = 589,824 。
● 先經(jīng)過 1x1 的卷積核,再經(jīng)過 3x3 卷積核,最后經(jīng)過一個 1x1 卷積核。 256 維的輸入先經(jīng)過一個 1×1×64 的卷積層,再經(jīng)過一個 3x3x64 的卷積層,最后經(jīng)過 1x1x256 的卷積層,則總參數(shù)量為:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632 。
經(jīng)過兩種方式的對比,我們可以很明顯的看到后者的參數(shù)量遠小于前者的。Bottleneck 的核心思想還是利用多個小卷積核替代一個大卷積核,利用 1x1 卷積核替代大的卷積核的一部分工作。
2.5 深度可分離卷積(Depthwise Separable Conv)
我們發(fā)現(xiàn)參數(shù)量還是很多,于是人們又想啊想,得出了 Depthwise Separable Conv 。這個idea最早是來自這篇論文 Design of Efficient Convolutional Layers using Single Intra-channel Convolution, Topological Subdivisioning and Spatial “Bottleneck” Structure,后面被 Google 用在 MobileNet 和 Xception 中發(fā)揚光大。
這個卷積的的大致意思是對每一個深度圖分別進行卷積再融合,步驟是先 Depthwise Conv 再 Pointwise Conv,大大減少了參數(shù)量。下圖是 Xception 模塊的結構:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MMOGpbfw-1687398336494)(https://ai-studio-static-online.cdn.bcebos.com/0133cb468d7e46ebb3e5a5a854f4f7939aadb080d5e6444da97c06c69859c045)]
大致的步驟是這樣的:
● 分別按不同通道進行一次卷積(生成 輸入通道數(shù) 張 Feature Maps)- DW
● 再將這些 Feature Maps 一起進行第二次卷積 - PW
文字看起來有點抽象,我們用例子來理解一下。
輸入的是 2 維的數(shù)據(jù),我們要進行 3x3 卷積并輸出 3 維的數(shù)據(jù),與正常卷積對比:
常規(guī)卷積運算
標準卷積的參數(shù)量計算公式(不帶偏置)為:
輸入特征圖:
W
i
n
p
u
t
×
H
i
n
p
u
t
×
C
i
n
p
u
t
W_{input}\times H_{input}\times C_{input}
Winput?×Hinput?×Cinput?
卷積核:
K
h
×
K
w
K_h\times K_w
Kh?×Kw?
輸出特征圖:
W
o
u
t
p
u
t
×
H
o
u
t
p
u
t
×
C
o
u
t
p
u
t
W_{output}\times H_{output}\times C_{output}
Woutput?×Houtput?×Coutput?
參數(shù)量(既卷積核的參數(shù)):
C
i
n
p
u
t
×
K
h
×
K
w
×
C
o
u
t
=
3
×
3
×
3
×
4
=
108
C_{input}\times K_h\times K_w\times C_{out}=3\times3\times3\times4=108
Cinput?×Kh?×Kw?×Cout?=3×3×3×4=108
其中 W i n p u t W_{input} Winput?表示輸入特征圖的寬, H i n p u t H_{input} Hinput?表示輸入特征圖的高, C i n p u t C_{input} Cinput?表示輸入特征圖的通道數(shù)。而 K h 和 K w K_h 和K_w Kh?和Kw?則表示卷積核高和寬的尺寸大小, W o u t p u t W_{output} Woutput?表示輸出特征圖的寬, H o u t p u t H_{output} Houtput?表示輸出特征圖的高, C o u t p u t C_{output} Coutput?表示輸出特征圖的通道數(shù)。
DW卷積
不同于常規(guī)卷積操作,Depthwise Convolution的一個卷積核負責一個通道,一個通道只被一個卷積核卷積。上面所提到的常規(guī)卷積每個卷積核是同時操作輸入圖片的每個通道。
對于一張 5 × 5 5\times5 5×5像素、三通道彩色輸入圖片(shape為5×5×3),Depthwise Convolution首先經(jīng)過第一次卷積運算,不同于上面的常規(guī)卷積,DW完全是在二維平面內(nèi)進行。卷積核的數(shù)量與上一層的通道數(shù)相同(通道和卷積核一一對應)。所以一個三通道的圖像經(jīng)過運算后生成了3個Feature map(如果有same padding則尺寸與輸入層相同為 5 × 5 5\times5 5×5)。
一個大小為 64 × 64 64\times64 64×64像素、三通道彩色圖片首先經(jīng)過第一次卷積運算,不同之處在于此次的卷積完全是在二維平面內(nèi)進行,且卷積核(Filters)的數(shù)量與上一層的通道數(shù)相同。所以一個三通道的圖像經(jīng)過運算后生成了3個Feature map,如下圖所示。
參數(shù)量為:
C
i
n
p
u
t
×
K
h
×
K
w
×
1
=
3
×
3
×
3
×
1
=
27
C_{input}\times K_h\times K_w\times 1=3\times3\times3\times 1=27
Cinput?×Kh?×Kw?×1=3×3×3×1=27
Depthwise Convolution完成后的Feature map數(shù)量與輸入層的通道數(shù)相同,但是這種運算對輸入層的每個channel獨立進行卷積運算后就結束了,沒有有效的利用不同F(xiàn)eature map在相同空間位置上的信息。因此需要增加另外一步操作來將這些Feature map進行組合生成新的Feature map,即接下來的Pointwise Convolution。
PW卷積
Pointwise Convolution的運算與常規(guī)卷積運算非常相似,不同之處在于卷積核的尺寸為 1 × 1 × M 1\times1\times M 1×1×M,M為上一層的通道數(shù)。所以這里的卷積運算會將上一步的Feature map在深度方向上進行加權組合,生成新的Feature map。有幾個卷積核(Filters)就有幾個Feature map。如下圖所示。
參數(shù)量為:
C
i
n
p
u
t
×
1
×
1
×
C
o
u
t
p
u
t
=
3
×
1
×
1
×
4
=
12
C_{input}\times1\times 1\times C_{output}=3\times1\times1\times4=12
Cinput?×1×1×Coutput?=3×1×1×4=12
經(jīng)過Pointwise Convolution之后,同樣輸出了4張Feature map,與常規(guī)卷積的輸出維度相同。
Depthwise Separable Conv 卷積
標準的深度可分離卷積如下圖所示:
深度可分離卷積分為DW卷積和PW卷積,因此要分開計算再相加,參數(shù)量計算公式如下(不帶偏置):
參數(shù)量公式: K h × K w × 1 × C i n p u t + 1 × 1 × C i n p u t × C o u t p u t K_{h}\times K_{w}\times1 \times C_{input} +1\times1\times C_{input}\times C_{output} Kh?×Kw?×1×Cinput?+1×1×Cinput?×Coutput?
DW卷積參數(shù)量:
C
o
u
n
t
D
W
=
C
i
n
p
u
t
×
K
h
×
K
w
×
1
=
3
×
3
×
3
×
1
=
27
Count_{DW}=C_{input}\times K_h\times K_w\times 1=3\times3\times3\times 1=27
CountDW?=Cinput?×Kh?×Kw?×1=3×3×3×1=27
PW卷積參數(shù)量:
C
o
u
n
t
P
W
=
C
i
n
p
u
t
×
1
×
1
×
C
o
u
t
p
u
t
=
3
×
1
×
1
×
4
=
12
Count_{PW}=C_{input}\times1\times 1\times C_{output}=3\times1\times1\times4=12
CountPW?=Cinput?×1×1×Coutput?=3×1×1×4=12
總的參數(shù)量:
C
o
u
n
t
D
W
+
C
o
u
n
t
P
W
=
3
×
3
×
3
×
1
+
3
×
1
×
1
×
4
=
27
+
12
=
39
Count_{DW}+Count_{PW}=3\times3\times3\times1+3\times1\times1\times4=27+12=39
CountDW?+CountPW?=3×3×3×1+3×1×1×4=27+12=39
參數(shù)量對比
39
108
=
0.36
\frac{39}{108}=0.36
10839?=0.36
我們可以看到,參數(shù)量是正常卷積的將近一半,但實際上可以更少,只不過在輸入輸出維度相差不大的情況下,效果沒那么明顯。
理論計算
P
D
W
=
I
×
D
k
×
D
k
+
I
×
O
P_{DW}=I\times D_k\times D_k +I\times O
PDW?=I×Dk?×Dk?+I×O
P
N
o
r
m
a
l
=
I
×
D
k
×
D
k
×
O
P_{Normal}=I\times D_k\times D_k \times O
PNormal?=I×Dk?×Dk?×O
P
D
W
P
N
o
r
m
a
l
=
1
O
+
1
D
k
2
≈
1
D
k
2
\frac{P_{DW}}{P_{Normal}}=\frac{1}{O}+\frac{1}{D^{2}_{k}}\approx \frac{1}{D^{2}_{k}}
PNormal?PDW??=O1?+Dk2?1?≈Dk2?1?
其中 I I I為輸入通道數(shù), O O O 是輸出通道數(shù), D k D_k Dk? 是標準卷積核大小。
我們可以看到,當我們使用 3x3 卷積核的時候,參數(shù)量約等于標準卷積核的 1 9 \frac{1}{9} 91? ,大大減少參數(shù)量,從而加快訓練速度。因此,在理論上普通卷積參數(shù)量是深度可分離卷積的9倍左右。
這里需要說明的是,Xception模型中的Depthwiss Separable Conv和傳統(tǒng)的不太一樣,傳統(tǒng)的Depthwise Separable Conv是先進行 3 × 3 3\times3 3×3卷積,再進行 1 × 1 1\times1 1×1卷積操作(類似于mobileNet中的一樣),而Xception模型中則是先進行 1 × 1 1\times1 1×1卷積,再進行 3 × 3 3\times3 3×3卷積操作,但中間為了保證數(shù)據(jù)不被破壞,沒有添加Relu層,而mobileNet與它不同的是中間添加了Relu層。
3.網(wǎng)絡結構
Xception的具體網(wǎng)絡結構如圖所示:
Xception包含三個部分:輸入部分(Entry flow),中間部分(Middle flow)和結尾部分(Exit flow);其中所有卷積層和可分離卷積層后面都使用Batch Normalization處理,所有的可分離卷積層使用一個深度乘數(shù)1(深度方向并不進行擴充)。
- 對于Entry flow,首先使用了兩個3x3卷積(conv1,conv2)降低特征圖尺寸,同時增加了特征圖個數(shù);接著是3個含跳連的深度可分離卷積堆疊模塊。
- 對于Middle flow,包含了8個一模一樣的含跳連的深度可分離卷積堆疊模塊。
- 對于Exit flow,首先是一個含跳連的深度可分離卷積堆疊模塊,接著是一些深度可分離卷積層以及全局平均池化層,最后用全連接層輸出分類結果。
4.評估分析
Xception論文中主要在JFT數(shù)據(jù)集與ImageNet數(shù)據(jù)集上與Inception V3模型做了比較,Xception和Inception V3模型的參數(shù)量大小如下圖所示:
由此可以看出, 在參數(shù)量和速度,Xception參數(shù)量少于Inception V3,但速度更快。 同時與Inception V3相比,在分類性能上,Xception在ImageNet上領先較小,但在JFT上領先很多。
在ImageNet數(shù)據(jù)集下的測試結果如下圖所示:
在JFT數(shù)據(jù)集下的測試結果如下圖所示:
二、數(shù)據(jù)預處理
# 解壓數(shù)據(jù)集
!unzip /home/aistudio/data/data223822/bird_photos.zip -d /home/aistudio/work/dataset
由于我們處理數(shù)據(jù)集文件的時候,里面多一個ipynb_checkpoints文件,因此需要通過以下命令刪除以下。切記!一定要刪除~
%cd /home/aistudio/work/dataset
!rm -rf .ipynb_checkpoints
# 劃分數(shù)據(jù)集
import os
import random
train_ratio = 0.7
test_ratio = 1-train_ratio
rootdata = "/home/aistudio/work/dataset"
train_list, test_list = [],[]
data_list = []
class_flag = -1
for a,b,c in os.walk(rootdata):
for i in range(len(c)):
data_list.append(os.path.join(a,c[i]))
for i in range(0, int(len(c)*train_ratio)):
train_data = os.path.join(a, c[i])+' '+str(class_flag)+'\n'
train_list.append(train_data)
for i in range(int(len(c)*train_ratio),len(c)):
test_data = os.path.join(a,c[i])+' '+str(class_flag)+'\n'
test_list.append(test_data)
class_flag += 1
random.shuffle(train_list)
random.shuffle(test_list)
with open('/home/aistudio/work/train.txt','w',encoding='UTF-8') as f:
for train_img in train_list:
f.write(str(train_img))
with open('/home/aistudio/work/test.txt', 'w', encoding='UTF-8') as f:
for test_img in test_list:
f.write(test_img)
三、數(shù)據(jù)讀取
首先我們先導入以下所需庫。
import paddle
import paddle.nn.functional as F
import numpy as np
import math
import random
import os
from paddle.io import Dataset # 導入Datasrt庫
import paddle.vision.transforms as transforms
import xception
from PIL import Image
然后使用 paddle.io.DataLoader 定義數(shù)據(jù)讀取器
transform_BZ = transforms.Normalize(
mean=[0.5, 0.5, 0.5],
std=[0.5, 0.5, 0.5]
)
class LoadData(Dataset):
def __init__(self, txt_path, train_flag=True):
self.imgs_info = self.get_images(txt_path)
self.train_flag = train_flag
self.train_tf = transforms.Compose([
transforms.Resize(224), # 調(diào)整圖像大小為224x224
transforms.RandomHorizontalFlip(), # 隨機左右翻轉圖像
transforms.RandomVerticalFlip(), # 隨機上下翻轉圖像
transforms.ToTensor(), # 將 PIL 圖像轉換為張量
transform_BZ # 執(zhí)行某些復雜變換操作
])
self.val_tf = transforms.Compose([
transforms.Resize(224), # 調(diào)整圖像大小為224x224
transforms.ToTensor(), # 將 PIL 圖像轉換為張量
transform_BZ # 執(zhí)行某些復雜變換操作
])
def get_images(self, txt_path):
with open(txt_path, 'r', encoding='utf-8') as f:
imgs_info = f.readlines()
imgs_info = list(map(lambda x: x.strip().split(' '), imgs_info))
return imgs_info
def padding_black(self, img):
w, h = img.size
scale = 224. / max(w, h)
img_fg = img.resize([int(x) for x in [w * scale, h * scale]])
size_fg = img_fg.size
size_bg = 224
img_bg = Image.new("RGB", (size_bg, size_bg))
img_bg.paste(img_fg, ((size_bg - size_fg[0]) // 2,
(size_bg - size_fg[1]) // 2))
img = img_bg
return img
def __getitem__(self, index):
img_path, label = self.imgs_info[index]
img_path = os.path.join('',img_path)
img = Image.open(img_path)
img = img.convert("RGB")
img = self.padding_black(img)
if self.train_flag:
img = self.train_tf(img)
else:
img = self.val_tf(img)
label = int(label)
return img, label
def __len__(self):
return len(self.imgs_info)
加載訓練集和測試集
train_data = LoadData("/home/aistudio/work/train.txt", True)
test_data = LoadData("/home/aistudio/work/test.txt", True)
#數(shù)據(jù)讀取
train_loader = paddle.io.DataLoader(train_data, batch_size=16, shuffle=True)
test_loader = paddle.io.DataLoader(test_data, batch_size=16, shuffle=True)
四、導入模型
這里我們直接導入提前寫好的xception文件,然后打印輸出以下模型的參數(shù)信息。
import xception
import paddle
model = xception.Xception41(class_num=4)
params_info = paddle.summary(model,(1, 3, 224, 224))
print(params_info)
打印結果如下所示:
通過和Inception V3的參數(shù)量對比,我們發(fā)現(xiàn)確實降低了。
五、模型訓練
epoch_num = 50 #訓練輪數(shù)
batch_size = 16
learning_rate = 0.0001 #學習率
val_acc_history = []
val_loss_history = []
def train(model):
print('start training ... ')
# turn into training mode
model.train()
opt = paddle.optimizer.Adam(learning_rate=learning_rate,
parameters=model.parameters())
for epoch in range(epoch_num):
acc_train = []
for batch_id, data in enumerate(train_loader()):
x_data = data[0]
y_data = paddle.to_tensor(data[1],dtype="int64")
y_data = paddle.unsqueeze(y_data, 1)
logits = model(x_data)
loss = F.cross_entropy(logits, y_data)
acc = paddle.metric.accuracy(logits, y_data)
acc_train.append(acc.numpy())
if batch_id % 100 == 0:
print("epoch: {}, batch_id: {}, loss is: {}".format(epoch, batch_id, loss.numpy()))
avg_acc = np.mean(acc_train)
print("[train] accuracy: {}".format(avg_acc))
loss.backward()
opt.step()
opt.clear_grad()
# evaluate model after one epoch
model.eval()
accuracies = []
losses = []
for batch_id, data in enumerate(test_loader()):
x_data = data[0]
y_data = paddle.to_tensor(data[1],dtype="int64")
y_data = paddle.unsqueeze(y_data, 1)
logits = model(x_data)
loss = F.cross_entropy(logits, y_data)
acc = paddle.metric.accuracy(logits, y_data)
accuracies.append(acc.numpy())
losses.append(loss.numpy())
avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
print("[test] accuracy/loss: {}/{}".format(avg_acc, avg_loss))
val_acc_history.append(avg_acc)
val_loss_history.append(avg_loss)
model.train()
train(model)
paddle.save(model.state_dict(), "model.pdparams")
六、結果可視化
import matplotlib.pyplot as plt
#隱藏警告
import warnings
warnings.filterwarnings("ignore") #忽略警告信息
epochs_range = range(epoch_num)
plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, val_acc_history, label='Val Accuracy')
plt.legend(loc='lower right')
plt.title('Val Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, val_loss_history, label='Val Loss')
plt.legend(loc='upper right')
plt.title('Val Loss')
plt.show()
文章來源:http://www.zghlxwxcb.cn/news/detail-495187.html
七、個體預測結果展示
data_transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Resize((224, 224)),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))])
img = Image.open("/home/aistudio/work/dataset/Bananaquit/161.jpg")
plt.imshow(img)
image=data_transform(img)
plt.rcParams['font.sans-serif']=['FZHuaLi-M14S']
name=['蕉林鶯','黑喉樹鶯','黑燕鷗類','鳳頭鸚鵡']
image=paddle.reshape(image,[1,3,224,224])
model.eval()
predict=model(image)
print(predict.numpy()) #明顯可以看出是第0個標簽大
plt.title(name[predict.argmax(1)])
plt.show()
可視化結果如下所示:文章來源地址http://www.zghlxwxcb.cn/news/detail-495187.html
總結
- Xception(又稱為 Extreme Inception)是一種卷積神經(jīng)網(wǎng)絡架構,在 2016 年由 Google 提出,它的名字是由 ‘Extreme’ 和 ‘Inception’ 兩個詞匯組成的。Xception 采用了 Inception 模型的思想,使用深度可分離卷積來代替?zhèn)鹘y(tǒng)的卷積,從而更加有效地減少了模型的參數(shù)數(shù)量和計算復雜度。
- 在傳統(tǒng)的 Inception 模型中,每個計算單元采用了兩個卷積層,一個 1x1 的卷積層用于降低特征圖的通道數(shù),緊接著是一個 3x3 的卷積層用于進行特征提取。而 Xception 則將 1x1 和 3x3 卷積逐次分開,使用了深度可分離卷積作為基本的計算單元。深度可分離卷積將標準卷積分解為兩部分,首先使用深度卷積來處理每個輸入通道,然后再使用 1x1 的逐點卷積來融合通道,從而獲得與標準卷積近似的特征提取效果。而深度可分離卷積相較于標準卷積而言,可以明顯降低參數(shù)量和訓練計算量。
- 而使用深度可分離卷積單元取代了傳統(tǒng)的卷積操作之后,Xception模型在計算效率,模型大小上都相比 InceptionV3 有大幅的提升。
- 總之,Xception模型的優(yōu)勢是在極大的減少了網(wǎng)絡參數(shù)量和計算復雜度的同時,可以保持卓越的性能表現(xiàn)。因此,Xception模型已經(jīng)被廣泛地應用與圖像分類、目標檢測等任務中。
到了這里,關于Xception算法解析-鳥類識別實戰(zhàn)-Paddle實戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!