深度學習(二):卷積神經(jīng)網(wǎng)絡(上)

一虫几、基本原理

卷積神經(jīng)網(wǎng)絡(convolutional neural network, CNN)是一種具有局部連接、權重共享等特性的深層前饋神經(jīng)網(wǎng)絡翔忽。其啟發(fā)來源于生物學上的感受野(receptive field)瘪吏,一般由卷積層卓研、池化層和全連接層組成趴俘。在圖像處理問題上,普通全連接神經(jīng)網(wǎng)絡參數(shù)過多且不能提取局部不變特性奏赘,卷積神經(jīng)網(wǎng)絡則克服了這些缺點寥闪,取得了很好的效果。

卷積層依靠 濾波器(filter)(又稱卷積核(convolution kernel) )進行特征提取磨淌,可將卷積核看做掃描器疲憋,通過掃描輸入數(shù)據(jù)來提取特征,一般卷積核大小為3x3和5x5梁只。假設輸入輸入矩陣大小為n缚柳,卷積核大小為m,步長stride為s搪锣,零填充(zero padding)為p秋忙,則經(jīng)過一輪卷積后,輸出大小為(n?m+2p)/s+1构舟。卷積的基本過程如下動圖所示:

卷積的動態(tài)過程

卷積層的三維示意

卷積層可以顯著減少網(wǎng)絡中連接的數(shù)量灰追,但特征映射數(shù)組中神經(jīng)元個數(shù)并未顯著減少,如果直接接入分類器,仍然易出現(xiàn)過擬合。為解決這個問題哎垦,在卷積層后加入池化層,以降低特征維數(shù)苦蒿,避免過擬合。常用池化有兩種:最大池化(max pooling)渗稍,即取一個區(qū)域最大值刽肠;平均池化(mean pooling)溃肪,即取一個區(qū)域平均值免胃。通過池化音五,原始數(shù)據(jù)的大小被壓縮,特征也減少羔沙。常用的池化層大小為2x2躺涝。

一個典型的卷積網(wǎng)絡是由卷積層、匯聚層扼雏、全連接層交叉堆疊而成坚嗜。在卷積網(wǎng)絡中,參數(shù)為卷積核中權重以及偏置诗充。和全連接前饋網(wǎng)絡類似苍蔬,卷 積網(wǎng)絡也可以通過誤差反向傳播算法來進行參數(shù)學習。在全連接前饋神經(jīng)網(wǎng)絡中蝴蜓,梯度主要通過每一層的誤差項δ進行反向傳播碟绑, 并進一步計算每層參數(shù)的梯度。在卷積神經(jīng)網(wǎng)絡中茎匠,主要有兩種不同功能的神經(jīng)層:卷積層和匯聚層格仲。而 參數(shù)為卷積核以及偏置,因此只需要計算卷積層中參數(shù)的梯度诵冒。

典型的卷積網(wǎng)絡結(jié)構

二凯肋、基本實現(xiàn)

下面通過pytorch對手寫體數(shù)字識別的例子來實現(xiàn)卷積神經(jīng)網(wǎng)絡的過程。

  1. 庫的導入以及數(shù)據(jù)的下載汽馋。采用MNIST數(shù)據(jù)集侮东,該數(shù)據(jù)集中,訓練集有6萬張圖片豹芯,測試集有1萬張圖片悄雅,使用torchvision可以非常簡便地下載和讀取數(shù)據(jù)。
import torch 
import torchvision
import torch.utils.data
import torchvision.transforms as transforms
from sklearn.manifold import TSNE
import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt

batch_size = 100

train_dataset = torchvision.datasets.MNIST(root='Data', train=True, transform = transforms.ToTensor(), download = True)
test_dataset = torchvision.datasets.MNIST(root='Data', train=False, transform = transforms.ToTensor(), download = False)
train_loader = torch.utils.data.DataLoader(dataset = train_dataset, batch_size = batch_size, shuffle = True)
test_loader = torch.utils.data.DataLoader(dataset = test_dataset, batch_size = batch_size, shuffle = True)

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
  1. 函數(shù)結(jié)構的設計告组。用于圖像處理的卷積神經(jīng)網(wǎng)絡一般分為兩個部分:特征提取和特征利用煤伟。特征提取由卷積層完成,經(jīng)過池化層來避免特征的簡單重復木缝,最后全連接層利用特征運算得到目標結(jié)果便锨。其詳細結(jié)構參數(shù)如下圖和代碼所示:
網(wǎng)絡結(jié)構
class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = torch.nn.Sequential(
                torch.nn.Conv2d(1,64,kernel_size=3,padding=1),
                torch.nn.ReLU(),
                torch.nn.Conv2d(64,128,kernel_size=3,padding=1),
                torch.nn.ReLU(),
                torch.nn.MaxPool2d(stride=2,kernel_size=2))
        self.dense = torch.nn.Sequential(
                torch.nn.Linear(128*14*14,1024),
                torch.nn.ReLU(),
                torch.nn.Dropout(p=0.5),
                torch.nn.Linear(1024,10))
    def forward(self,x):
        x = self.conv1(x)
        x = x.view(-1,128*14*14)
        x = self.dense(x)
        return x
  1. 網(wǎng)絡訓練過程。損失函數(shù)采用交叉熵我碟,優(yōu)化方法采用Adam放案,共迭代5次,每次中由于batch_size為100矫俺,故需循環(huán)600次才能完成訓練吱殉,每循環(huán)100次掸冤,輸出一下結(jié)果。
net = Net().to(device)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(),lr=0.001)

num_epochs = 5
for epoch in range(num_epochs):
    for idx,(images,labels) in enumerate(train_loader):
        images = images.to(device)
        labels = labels.to(device)
        #print(images.shape)
        preds = net(images)
        loss = criterion(preds,labels)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if idx % 100 == 0:
            print('epoch:{}, batch:{}, loss:{}'.format(epoch,idx,loss))

下圖為訓練過程的不同階段的結(jié)果友雳,從中可以一窺卷積作用的過程稿湿。

原始圖片
經(jīng)過一層卷積
經(jīng)過一層卷積和一個激活層
經(jīng)過兩層卷積和兩個激活層
再經(jīng)過一個池化層
  1. 測試過程。訓練好的結(jié)構在10000張測試圖上的表現(xiàn)為正確率99.07 %押赊,這充分說明了卷積神經(jīng)網(wǎng)絡的有效性饺藤。
with torch.no_grad():
    correct = 0
    total = 0
    for images, labels in test_loader:
        images = images.to(device)
        labels = labels.to(device)
        outputs = net(images)
        predicted = torch.argmax(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
    print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))

Test Accuracy of the model on the 10000 test images: 99.07 %。

  1. 結(jié)果可視化流礁。為了更加形象說明分類的效果涕俗,通過t-SNE降維方法繪制了其可視化結(jié)果。
def plot_with_labels(lowDWeights, labels):
    plt.cla()
    X, Y = lowDWeights[:, 0], lowDWeights[:, 1]
    for x, y, s in zip(X, Y, labels):
        c = cm.rainbow(int(255 * s / 9)); plt.text(x, y, s, backgroundcolor=c, fontsize=9)
    plt.xlim(X.min(), X.max()); plt.ylim(Y.min(), Y.max()); plt.title('Visualize last layer'); plt.show(); plt.pause(0.01)
     
#visualization of trained flatten layer (t-SNE)
tsne = TSNE(perplexity=30,n_components=2,init='pca',n_iter=5000)
plot_only = 500
low_dim_embs = tsne.fit_transform(outputs.data.cpu().numpy())[:plot_only,:]
plot_labels = labels.cpu().numpy()[:plot_only]
plot_with_labels(low_dim_embs,plot_labels)
分類結(jié)果可視化

四神帅、問題探討

圖像的上采樣與下采樣

縮小圖像(或稱為下采樣(subsampled)或降采樣(downsampled))的主要目的有兩個:1再姑、使得圖像符合顯示區(qū)域的大小找御;2元镀、生成對應圖像的縮略圖。
放大圖像(或稱為上采樣(upsampling)或圖像插值(interpolating))的主要目的是放大原圖像,從而可以顯示在更高分辨率的顯示設備上萎坷。
下采樣原理:對于一幅圖像I尺寸為M凹联,對其進行s倍下采樣,即得到(M/s)尺寸的得分辨率圖像哆档,即把原始圖像s*s窗口內(nèi)的圖像變成一個像素蔽挠,這個像素點的值就是窗口內(nèi)所有像素的均值或最大值。
上采樣原理:圖像放大幾乎都是采用內(nèi)插值方法瓜浸,即在原有圖像像素的基礎上在像素點之間采用合適的插值算法插入新的元素澳淑。插值方式有很多種,如最近鄰插值插佛,雙線性插值杠巡,均值插值,中值插值等方法雇寇。

參考資料

[1] Vishnu Subramanian. Deep Learning with PyTorch. Packet Publishing. 2018.
[2] 邱錫鵬 著氢拥,神經(jīng)網(wǎng)絡與深度學習. https://nndl.github.io/ 2019.
[3] 肖智清 著,神經(jīng)網(wǎng)絡與PyTorch實戰(zhàn). 北京:機械工業(yè)出版社. 2018.
[4] 唐進民 編著锨侯,深度學習之PyTorch實戰(zhàn)計算機視覺. 北京:電子工業(yè)出版社. 2018.
[5] Ian Goodfellow 等 著, 趙申劍等 譯, 深度學習. 北京:人民郵電出版社, 2017.
[6] https://blog.csdn.net/stf1065716904/article/details/78450997

丈夫只手把吳鉤嫩海,意氣高于百尺樓∏舫眨——李鴻章《入都十首·其一》

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叁怪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子深滚,更是在濱河造成了極大的恐慌奕谭,老刑警劉巖涣觉,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異血柳,居然都是意外死亡官册,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門混驰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攀隔,“玉大人,你說我怎么就攤上這事栖榨。” “怎么了明刷?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵婴栽,是天一觀的道長。 經(jīng)常有香客問我辈末,道長愚争,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任挤聘,我火速辦了婚禮轰枝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘组去。我一直安慰自己鞍陨,他們只是感情好,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布从隆。 她就那樣靜靜地躺著诚撵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪键闺。 梳的紋絲不亂的頭發(fā)上寿烟,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音辛燥,去河邊找鬼筛武。 笑死,一個胖子當著我的面吹牛挎塌,可吹牛的內(nèi)容都是我干的徘六。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼勃蜘,長吁一口氣:“原來是場噩夢啊……” “哼硕噩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缭贡,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤炉擅,失蹤者是張志新(化名)和其女友劉穎辉懒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谍失,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡眶俩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了快鱼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颠印。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖抹竹,靈堂內(nèi)的尸體忽然破棺而出线罕,到底是詐尸還是另有隱情,我是刑警寧澤窃判,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布钞楼,位于F島的核電站,受9級特大地震影響袄琳,放射性物質(zhì)發(fā)生泄漏询件。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一唆樊、第九天 我趴在偏房一處隱蔽的房頂上張望宛琅。 院中可真熱鬧,春花似錦逗旁、人聲如沸嘿辟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仓洼。三九已至,卻和暖如春堤舒,著一層夾襖步出監(jiān)牢的瞬間色建,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工舌缤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留箕戳,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓国撵,卻偏偏與公主長得像陵吸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子介牙,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容