python cnn模型_ZfNet解卷积:可视化CNN模型( PythonCode可视化Cifar10)
前言
由來已久,ANN方法被稱為模式識別里面的“黑盒”方法,因為ANN模型不能使用明確的函數——形式化的數學公式進行表示,同時也意味著應對評價模型,面對函數尋求最優解的優化方程也不能形式化表示。
基于NN的分層堆疊性,NN即使以特定結構三層網便可以以任意精度逼近任意非線性函數,也同時表示函數形式在NN中的難以形式化。K曾經證明(1957),在單位超立方體內的任意連續函數,都可以選擇適當的參數展開為兩級級數求和問題。后來的研究發現,任意一個從x到y的映射,都存在一個合適的三層神經網絡以任意的精度逼近它。反過來看,從神經網絡結構和參數,去描述函數的一個形式,涉及到擬合問題,是個不確定問題。進而以此歸結出基于模型函數的優化函數,則是不可能完成的事情。從這個角度上看來,NN是個語義和語法的黑箱。
好在對于學習來說,形式化是非必須的,可形式化的SVM也面臨著核函數的形式化難題,而CNN可以從語義層次進行解析,以彌補語法不能完備的缺憾。
ZFNet思想及過程
從科學的觀點出發,如果不能歸納,只能進行遍歷。如果不知道神經網絡為什么取得了如此好的效果,那么只能靠不停的實驗來尋找更好的模型。
ZFNet使用一個多層的反卷積網絡來可視化訓練過程中特征的演化及發現潛在的問題;同時根據遮擋圖像局部對分類結果的影響來探討對分類任務而言到底那部分輸入信息更重要。
反卷積可視化:一個卷積層加一個對應的反卷積層;
輸入是feature map,輸出是圖像像素;
過程包括反池化操作、relu和反卷積過程。反池化:嚴格意義上的反池化是無法實現的。作者采用近似的實現,在訓練過程中記錄每一個池化操作的一個z*z的區域內輸入的最大值的位置,這樣在反池化的時候,就將最大值返回到其應該在的位置,其他位置的值補0。
relu糾正:
卷積神經網絡使用relu非線性函數來保證輸出的feature map總是為正數。在反卷積的時候,也需要保證每一層的feature map都是正值,所以這里還是使用relu作為非線性激活函數。
濾波:
使用原卷積核的轉秩和feature map進行卷積。反卷積其實是一個誤導,這里真正的名字就是轉秩卷積操作。反卷積網中利用卷積網中的相同的濾波器的轉置應用到糾正過的特征圖中,而不是上層的輸出。也就是對濾波器進行水平方向和垂直方向的翻轉。從高層向下投影使用轉換變量switch,這個轉化變量switch產生自向上的卷積網的最大池化操作。由于重建由一個單獨的激活獲得,因此也就只對應于原始輸入圖像的一小塊。
上圖左半部分是一個解卷積層,右半部分為一個卷積層。解卷積層將會重建一個來自下一層的卷積特征近似版本。圖中使用switc來記錄在卷積網中進行最大池化操作時每個池化區域的局部最大值的位置,經過非池化操作之后,原來的非最大值的位置都置為0。
特征可視化:
每個特征單獨投影到像素空間揭露了不同的結構能刺激不同的一個給定的特征圖,因此展示了它對于變形的輸入內在的不變性。下圖即在一個已經訓練好的網絡中可視化后的圖。
上圖所示是訓練結束后,模型各個隱藏層提取的特征,圖所示的是給定輸出特征時,反卷積產生的最強的9個輸入特征。將這些計算所得的特征,用像素空間表示后,可以清晰地看出:一組特定的輸入特征(通過重構獲得),將刺激卷積網產生一個固定的輸出特征。圖2的右邊是對應的輸入圖片,和重構特征相比,輸入圖片和其之間的差異性很大,而重構特征只包含那些具有判別能力的紋理結構。例如,第5層第1行第2列的9張輸入圖片各不相同差異很大,而對應的重構輸入特征則都顯示了背景中的草地,沒有顯示五花八門的前景。
每一層的可視化結果都展示了網絡的層次化特點。第2層展示了物體的邊緣和輪廓,以及與顏色的組合,第3層擁有了更復雜的不變性,主要展示了相似的紋理,第4層不同組重構特征存在著重大差異性,開始體現了類與類之間的差異,第5層每組圖片都展示了存在重大差異的一類物體。
訓練過程中的feature變化:
外表突然的變化導致圖像中的一個變換即產生了最強烈的激活。模型的底層在少數幾個epoches就能收斂聚集,然而上層在一個相當多的epoches(40-50)之后才能有所變化,這顯示了讓模型完全訓練到完全收斂的必要性。可以由下圖看到顏色對比度都逐步增強。
特征不變性
下圖所示,5個不同的例子,它們分別被平移、旋轉和縮放。圖5右邊顯示了不同層特征向量所具有的不變性能力。在第一層,很小的微變都會導致輸出特征變化明顯,但是越往高層走,平移和尺度變化對最終結果的影響越小,網絡的輸出對于平移和尺度變化都是穩定的。卷積網無法對旋轉操作產生不變性,除非物體具有很強的對稱性,看似是個偽命題。
同類不同圖像的一致性分析
對五張小狗(同一類)的不同圖片的不同區域進行掩蓋,然后進行分析觀察探究深度模型是對一類物體的那部分進行一致性分析的過程...............
第5層隨機遮擋的情況比其他眼睛鼻子被遮擋的情況一致性分析較差,而第7層中,這四類卻都差不多,那是因為底層判別的是一類物體共有的部分,而高層判別的是類別中不同的品種這種更高維的部分了。
遷移學習的可行性
把預訓練的CNN模型用于新的場景,是遷移學習的應用表現。底層CNN-featureMap的通用性為這種移動提供了一個有力的實驗支持。遷移學習一般從復雜模型遷移到簡單模型,且一般使用遷移模型的底層部分,高層模型需要進行重建。
PythonCode
code1.訓練Cifar10網絡
下載Cifar10的數據集:得到
mean.binaryproto 文件
cifar10_test_lmdb?? cifar10_train_lmdb 文件夾,把三個文件和目錄,復制到examples\cifar10 目錄
建立CMD文件 cifar10_train_full.cmd 到工程的根目錄,與example平級
內容為:D:\Works\CNN\MsCaffe\Build\x64\Release/caffe.exe train --solver=examples/cifar10/cifar10_quick_solver.prototxt
pause
運行cmd命令
訓練結果:
生成結果到 examples/cifar10/根目錄,生成了H5后綴的訓練模型。
2. 可視化Caffe model
在Eclipse工程中,添加一個py文件,內容為:
#coding=utf-8
"""
Caffe visualize
Display and Visualization Functions and caffe model.
Copyright (c) 2017 Matterport, Inc.
Licensed under the MIT License (see LICENSE for details)
Written by wishchin yang
MayBe I should use jupyter notebook
"""
import numpy as np
import matplotlib.pyplot as plt
import os,sys,caffe
#%matplotlib inline
#編寫一個函數,用于顯示各層的參數
def show_feature(data, padsize=1, padval=0):
data -= data.min();
data /= data.max();
# force the number of filters to be square
n = int(np.ceil(np.sqrt(data.shape[0])));
padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3);
data = np.pad(data, padding, mode='constant', constant_values=(padval, padval));
# tile the filters into an image
data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)));
data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:]);
plt.imshow(data);
plt.axis('off');
#第一個實例,測試cifar10模型
def mainex():
caffe_root='D:/Works/CNN/MsCaffe/';
os.chdir(caffe_root);
sys.path.insert(0,caffe_root+'python');
plt.rcParams['figure.figsize'] = (8, 8);
plt.rcParams['image.interpolation'] = 'nearest';
plt.rcParams['image.cmap'] = 'gray';
net = caffe.Net(caffe_root + 'examples/cifar10/cifar10_quick_train_test.prototxt',
caffe_root + 'examples/cifar10/cifar10_quick_iter_4000.caffemodel.h5',
caffe.TEST);
[(k, v[0].data.shape) for k, v in net.params.items()];
# 第一個卷積層,參數規模為(32,3,5,5),即32個5*5的3通道filter
weight = net.params["conv1"][0].data
print(weight.shape);
show_feature(weight.transpose(0, 2, 3, 1));
# 第二個卷積層的權值參數,共有32*32個filter,每個filter大小為5*5
weight = net.params["conv2"][0].data;
print weight.shape;
show_feature( weight.reshape(32**2, 5, 5) );
# 第三個卷積層的權值,共有64*32個filter,每個filter大小為5*5,取其前1024個進行可視化
weight = net.params["conv3"][0].data ;
print weight.shape ;
show_feature(weight.reshape(64*32, 5, 5)[:1024]);
if __name__ == '__main__':
import argparse
mainex();
調試運行.............................................
結果顯示:
conv1層????????????????????????????????????????????????????????????????????????????????????????? ???? conv2層
? ???
結果分析:迭代4000次訓練的結果不是特別好,并沒有訓練得到明顯的底層特征。
總結
以上是生活随笔為你收集整理的python cnn模型_ZfNet解卷积:可视化CNN模型( PythonCode可视化Cifar10)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《交管12123》账号删除方法-交管12
- 下一篇: vst3插件_Blue Cat Audi