windows下caffe+CPUOnly实现MNIST手写分类
?
工具下載
微軟官方移植的Caffe:https://github.com/Microsoft/caffe
對屬性表的操作
需要把實例屬性表的后綴改成vs可用的.props
打開同一個文件夾下的Caffe.sln,查看其中的屬性表
<CpuOnlyBuild>true</CpuOnlyBuild>
???????<UseCuDNN>false</UseCuDNN>
分別指的是只利用CPU的環境和利用GPU進行CUDA編程,只能二選一,保持一個為true。
如果想進行CUDA編程首先要確保自己的GPU是英偉達NVIDIA的,然后在https://developer.nvidia.com/cudnn下載cuDNN(CUDA Deep Neural Network library),一個專門為深度神經網絡提供GPU加速的庫。下載好解壓縮之后,
?<!-- CuDNN 4 and 5 are supported -->
???????<CuDnnPath></CuDnnPath>
要填寫cuDNN的路徑。
解決方案
可以看到,解決方案中有16個項目(不用數,有顯示)。我們最關注的是caffe和libcaffe。
對caffe:
右擊“解決方案‘Caffe’”,選擇“屬性”,將“配置屬性”-“配置”修改成Release和x64
(這一步是使用Release來進行編譯,若用Debug,則之后每次都要打開vs,會不方便)
注意:在上圖頂部工具欄中的“解決方案配置”和“解決方案平臺”框,若你的vs2013中將這兩個框在工具欄中顯示,則要在工具欄中將配置改成Release和x64,否則直接右擊“解決方案Caffe”來更改配置是無效的。
對libcaffe:
右擊解決方案中的libcaffe項目,選擇“屬性”,在打開的屬性頁中選擇“C/C++”-“常規”,將“將警告視為錯誤”設為“否。然后右擊libcaffe項目,生成。期間會利用NuGet對caffe的一些依賴文件進行自動還原。同時會在caffe-master的同級目錄生成文件夾NugetPackages。里面是一些依賴庫(包括OpenCV),這也是選擇windows版caffe的好處。
這時候就可以生成解決方案了。但是打開解決方法的屬性可以看到默認的是只編譯libcaffe。我們可以選擇編譯其他項目。
此時在\caffe-master目錄下會生成Build文件夾,即為我們編譯成功的文件夾,而\caffe-master\Build\x64\Release目錄下則會有我們編譯出的caffe.exe執行文件。
MINIST下載、轉換和訓練
這是一個手寫數字數據集,有60,000個訓練樣本,10,000個測試樣本,測試集和訓練集是沒有交集的。數字尺寸都已經標準化,并且保證數字在圖像中心。數字是20x20像素的,圖像是28x28像素大小。
下載地址:http://yann.lecun.com/exdb/mnist/
train-images-idx3-ubyte.gz:? training set images (9912422 bytes)
train-labels-idx1-ubyte.gz:? training set labels (28881 bytes)
t10k-images-idx3-ubyte.gz:?? test set images (1648877 bytes)
t10k-labels-idx1-ubyte.gz:?? test set labels (4542 bytes)
圖像是以矩陣在一個特殊的格式中存儲的,所以是無法直接打開查看的。若發現下載的文件比官方給出的大,則說明瀏覽器已經自動解壓縮了。這個時候只需要重命名就可以移除.gz文件了。
這四個文件不能直接用于caffe的訓練和測試。需要利用生成的Release中的convert_mnist_data.exe把四個文件轉換為caffe所支持的leveldb或lmdb文件。lmdb是lightning(閃電的) memory-mapped database manager的縮寫,能夠把原始數據通過更為高效的存儲方式存儲,從而加快讀取和訓練速度(lmdb比leveldb更快,可以看看剛剛的NugetPackages文件夾,當中就包含著對應的庫)。具體轉換方法如下:
a)??????四個文件放到 . \examples\mnist\mnist_data文件夾下。
b)??????在caffe-windows安裝的根目錄下,新建一個convert-mnist-data-train.bat文件轉換為訓練數據,并在文件中添加代碼:
Build\x64\Release\convert_mnist_data.exe--backend=lmdbexamples\mnist\mnist_data\train-images.idx3-ubyteexamples\mnist\mnist_data\train-labels.idx1-ubyteexamples\mnist\mnist_data\mnist_train_lmdb?
Pause
再新建一個convert-mnist-data-test.bat轉換測試數據,代碼為:
Build\x64\Release\convert_mnist_data.exe--backend=lmdb examples\mnist\mnist_data\t10k-images.idx3-ubyteexamples\mnist\mnist_data\t10k-labels.idx1-ubyteexamples\mnist\mnist_data\mnist_test_lmdb?
Pause
運行
a)??????轉換好的訓練\測試數據集(mnist_train_lmdb\ mnist_train_lmdb或mnist_train_leveldb\mnist_train_leveldb)文件夾放在.\examples\mnist中。
b)??????修改lenet_solver.prototxt 中solver_mode: CPU;修改lenet_train_test.prototxt中
source:"examples/mnist/mnist_train_lmdb"
source:"examples/mnist/mnist_test_lmdb"
backend: LMDB
保證訓練集和測試集的路徑正確。
c)??????在caffe-windows根目錄下新建一個run.bat,文件中代碼:
Build\x64\Release\caffe.exe? train--solver=examples/mnist/lenet_solver.prototxt?
Pause
d)??????保存并雙擊運行run.bat,會開始打印一些日志文件。當迭代次數達到lenet_solver.prototxt定義的max_iter時,就可以認為訓練結束了。訓練完成后會在examples/mnist生成 .caffemodel 文件和 .solverstate 文件。分別是訓練一半和訓練結束的結果。
Ps:lenet_solver.prototxt是examples/mnist下的.prototxt文件。定義了網絡的結構。可以用vs打開。
solver.prototxt是solver配置文件,規定了如何優化求解loss function(非凸函數沒有解析解)。比如最常用的方法是Stochastic Gradient Descent (type:"SGD")。
這兩個文件很重要,因為它們決定了網絡是如何設計的,可以自己設計網絡,從而生成自己的.caffemodel 文件
Ps: 官方文檔Lenet NIST tutorial 給出的方法:在Linux下,直接利用
./data/mnist/get_mnist.sh ./examples/mnist/create_mnist.sh得到MNIST文件并且轉換為Lmdb格式。.sh是Linux下的腳本文件測試
雖然之前的步驟應該都成功了,但是沒有結果感覺還是不踏實。現在終于可以開始測試了。測試手寫數字就是機器學習中的hello world,還有點小興奮呢。
訓練集圖片均值文件
第一步,仍然要通過一個根目錄下的bat文件利用release下面的compute_image_mean.exe。
bat命令:Build\x64\Release\compute_image_mean.exeexamples\mnist\mnist_train_lmdb mean.binaryproto --backend=lmdb
然后就可以得到一個mean.binaryproto文件。含義是圖片減去均值后的殘差圖片。
然后我們需要修改\examples\mnist\lenet_train_test.prototxt。預處理transform_param中要添加mean_file文件。如下圖:
開始mnist測試
依然是通過bat,利用的是caffe.exe。
Build\x64\Release\caffe.exe test--model=examples\mnist\lenet_train_test.prototxt-weights=examples\mnist\lenet_iter_10000.caffemodel
Pause
批處理文件一不小心寫錯了好幾回。在這里我們指定了測試模式,隨后指定模型和訓練出來的參數。
?
可以看到前面是時間和日期。測試是以batch為單位進行的,從0~49一共50個batch。分別給出了每個batch的accuracy和loss。準確率在99%左右。
問題1:但是重新保存修改之后的\examples\mnist\lenet_train_test.prototxt預處理transform_param,即使用減去均值的殘差圖像,準確率反而下降了。如上圖,準確率只有92%。
連接https://blog.csdn.net/swj110119/article/details/53423957的測試結果和我一樣。他認為是均值預處理之后相對于均值濾波,圖像變模糊了。這里其實有兩個問題,一個是都說利用均值文件是為了提高準確率,但是這里卻下降了;一個是預處理是簡單地對測試圖像進行圖像相減呢,還是會重新調整網絡權重,生成一個新的網絡?
問題2:50個batch是由上面決定的呢?:”從一到二”博客里面說是caffe.cpp中一個叫做FLAGS_iterations的變量指定的。但是看了一下代碼也沒有什么宏定義直接顯示50
自己手寫數據測試
剛才是以batch測試的,還是沒有直觀的感受。
1.畫圖和準備標簽
開啟畫圖,調整到像素大小為28x28.然后手寫0~9的數字,保存為bmp格式。這里有一個問題,雖然利用classification.exe不再需要轉換成lmdb格式,但是也要求是單通道的。
Ps:如果保存的格式為單色位圖bmp格式,它與單通道有什么關系呢?單色位圖是黑白二值圖像;單通道是只有一個通道,灰度圖,圖像的色階是0~255的。
事實證明是沒什么關系的。完全是對圖像的兩個角度的衡量。三通道當然可以生成二值圖像。只不過當imread以參數為0讀入圖像時就無需轉換成gray了。
把轉換好的單通道bmp圖像放在\examples\mnist目錄下。同時準備一個標簽文件label.txt,里面是0~9的數字。
2. 通過test_personal.bat利用classification.exe去識別某張圖片
Build\x64\Release\classification.exeexamples\mnist\lenet.prototxt examples\mnist\lenet_iter_10000.caffemodelmean.binaryproto examples\mnist\label.txt examples\mnist\8.bmp
Pause
下圖是對“8”的識別情況
可惜“9”識別錯了
Reference:
1.??????Caffe編譯https://blog.csdn.net/xierhacker/article/details/51834563
2.??????Mnist轉換https://blog.csdn.net/foreyang00/article/details/71122866
3.??????prototxt文件的設置解讀https://blog.csdn.net/u014696921/article/details/52166015
4.??????從零到一http://www.cnblogs.com/yixuan-xu/p/5858595.html
5.??????從一到二http://www.cnblogs.com/yixuan-xu/p/5862657.html
?
總結
以上是生活随笔為你收集整理的windows下caffe+CPUOnly实现MNIST手写分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 两种装饰器
- 下一篇: 操作系统之死锁