使用GPU在caffe上进行CNN训练
1.配置caffe環(huán)境
[請(qǐng)參考此篇博客:http://blog.csdn.net/ws_20100/article/details/48850449]
本篇介紹如何在caffe環(huán)境下,實(shí)現(xiàn)"圖像對(duì)圖像"的卷積神經(jīng)網(wǎng)絡(luò)的訓(xùn)練。
2.文件結(jié)構(gòu)
在配置好的caffe文件夾中,進(jìn)入examples目錄,創(chuàng)建CNN文件夾,并進(jìn)入文件夾
$ cd caffe-master/examples/
$ mkdir CNN
$ cd CNN/
在CNN文件夾下面創(chuàng)建子文件夾
$ mkdir model snapshot TestPhotos TestLabels TrainPhotos TrainLabels
其中,
model用于以后存儲(chǔ)卷積核矩陣和偏置向量;
snapshot用于存儲(chǔ)訓(xùn)練中備份的caffe模型,每一段時(shí)間存儲(chǔ)一次,防止斷電等一些情況;
TrainPhotos、TrainLabels分別存儲(chǔ)訓(xùn)練集輸入和監(jiān)督樣本;
TestPhotos、TestLabels分別存儲(chǔ)測(cè)試集輸入和監(jiān)督樣本,不直接參與到訓(xùn)練中。
然后,將訓(xùn)練所用的輸入樣本和監(jiān)督樣本分別放入到TrainPhotos和TrainLabels中去。注意,樣本文件名無(wú)所謂,但是排列次序必須一一對(duì)應(yīng)。同樣,將測(cè)試所用的輸入樣本和監(jiān)督樣本分別放入到TestPhotos和TestLabels中去。
3.產(chǎn)生訓(xùn)練和測(cè)試數(shù)據(jù)
1.)產(chǎn)生路徑文件
在CNN文件夾下面(以下均是在此文件夾下)創(chuàng)建兩個(gè)路徑文件。
$ vim train.txt
輸入內(nèi)容:
examples/CNN/train.h5
:wq保存文檔。
$ vim test.txt
輸入內(nèi)容:
examples/CNN/test.h5
:wq保存文檔。
2.)產(chǎn)生訓(xùn)練數(shù)據(jù)
$ vim generate_train.m
輸入內(nèi)容:(把輸入圖像切成11*11的像素塊,監(jiān)督圖像為3*3的像素塊(由網(wǎng)絡(luò)結(jié)構(gòu)和卷積核大小決定),步長(zhǎng)為1個(gè)像素)
clear;close all;%% settings folder_input = 'TrainPhotos'; folder_label = 'TrainLabels'; savepath = 'train.h5'; size_input = 11; size_label = 3; % size_input - 12 stride = 1;%% initialization data = zeros(size_input, size_input, 1, 1); label = zeros(size_label, size_label, 1, 1); padding = abs(size_input - size_label) / 2; count = 0;%% read data filepaths_input = dir(fullfile(folder_input,'*.jpg')); filepaths_label = dir(fullfile(folder_label,'*.jpg'));if (length(filepaths_input)==length(filepaths_label))length = length(filepaths_input); elseerror('The Number of Input is NOT equal to the Number of Label.'); end%% generate data for i = 1 : lengthim_input = imread(fullfile(folder_input,filepaths_input(i).name));im_input = rgb2ycbcr(im_input);im_input = im2double(im_input(:, :, 1));im_label = imread(fullfile(folder_label,filepaths_label(i).name));im_label = im2double(im_label(:, :, 1));if size(im_input) == size(im_label)[hei,wid] = size(im_input);elseerror('The size of input and label are not equal.');endfor x = 1 : stride : hei-size_input+1for y = 1 :stride : wid-size_input+1subim_input = im_input(x : x+size_input-1, y : y+size_input-1);subim_label = im_label(x+padding : x+padding+size_label-1, y+padding : y+padding+size_label-1);count = count + 1;data(:, :, 1, count) = subim_input;label(:, :, 1, count) = subim_label;endendend%% randomized the data and label order = randperm(count); data = data(:, :, 1, order); label = label(:, :, 1, order); %% writing to HDF5 chunksz = 128; created_flag = false; totalct = 0;for batchno = 1:floor(count/chunksz)last_read=(batchno-1)*chunksz;batchdata = data(:,:,1,last_read+1:last_read+chunksz); batchlabs = label(:,:,1,last_read+1:last_read+chunksz);startloc = struct('dat',[1,1,1,totalct+1], 'lab', [1,1,1,totalct+1]);curr_dat_sz = store2hdf5(savepath, batchdata, batchlabs, ~created_flag, startloc, chunksz); created_flag = true;totalct = curr_dat_sz(end); end h5disp(savepath);
終端下輸入:
$ matlab -nodesktop -nosplash -logfile generate_train.log -r generate_train
產(chǎn)生訓(xùn)練數(shù)據(jù)train.h5。
3.)產(chǎn)生測(cè)試數(shù)據(jù)
$ vim generate_test.m
generate_test.m只需要將generate_test.m文件開(kāi)頭改為:
clear;close all;%% settings folder_input = 'TestPhotos'; folder_label = 'TestLabels'; savepath = 'test.h5'; size_input = 11; size_label = 3; stride = 30;
將最后一段改成:
%% writing to HDF5 chunksz = 2; created_flag = false; totalct = 0;for batchno = 1:floor(count/chunksz)last_read=(batchno-1)*chunksz;batchdata = data(:,:,1,last_read+1:last_read+chunksz); batchlabs = label(:,:,1,last_read+1:last_read+chunksz);startloc = struct('dat',[1,1,1,totalct+1], 'lab', [1,1,1,totalct+1]);curr_dat_sz = store2hdf5(savepath, batchdata, batchlabs, ~created_flag, startloc, chunksz); created_flag = true;totalct = curr_dat_sz(end); end h5disp(savepath);
終端下輸入:
$ matlab -nodesktop -nosplash -logfile generate_test.log -r generate_test
產(chǎn)生測(cè)試數(shù)據(jù)test.h5。僅僅用于判斷訓(xùn)練到達(dá)什么地步。
4.建立訓(xùn)練文件
1.)建立solver文件
$ vim CNN_solver.prototxt
此為運(yùn)行的配置文件,輸入以下內(nèi)容:
# The train/test net protocol buffer definition net: "examples/CNN/CNN_net.prototxt" test_iter: 556 # Carry out testing every 500 training iterations. test_interval: 500 # The base learning rate, momentum and the weight decay of the network. base_lr: 0.0001 momentum: 0.9 weight_decay: 0 # The learning rate policy lr_policy: "fixed" # Display every 100 iterations display: 100 # The maximum number of iterations max_iter: 15000000 # snapshot intermediate results snapshot: 500 snapshot_prefix: "examples/CNN/snapshot/CNN" # solver mode: CPU or GPU solver_mode: GPU
:wq保存退出。
2.)建立net文件
$ vim CNN_net.prototxt
此為網(wǎng)絡(luò)結(jié)構(gòu)配置文件,可以配置網(wǎng)絡(luò)層數(shù),節(jié)點(diǎn)數(shù),卷積核等參數(shù)。輸入以下內(nèi)容:
name: "CNN" layer {name: "data"type: "HDF5Data"top: "data"top: "label"hdf5_data_param {source: "examples/CNN/train.txt"batch_size: 128}include: { phase: TRAIN } } layer {name: "data"type: "HDF5Data"top: "data"top: "label"hdf5_data_param {source: "examples/CNN/test.txt"batch_size: 2}include: { phase: TEST } }layer {name: "conv1"type: "Convolution"bottom: "data"top: "conv1"param {lr_mult: 1}param {lr_mult: 0.1}convolution_param {num_output: 128kernel_size: 5stride: 1pad: 0weight_filler {type: "gaussian"std: 0.001}bias_filler {type: "constant"value: 0}} }layer {name: "relu1"type: "ReLU"bottom: "conv1"top: "conv1" }layer {name: "conv2"type: "Convolution"bottom: "conv1"top: "conv2"param {lr_mult: 1}param {lr_mult: 0.1}convolution_param {num_output: 64kernel_size: 3stride: 1pad: 0weight_filler {type: "gaussian"std: 0.001}bias_filler {type: "constant"value: 0}} }layer {name: "relu2"type: "ReLU"bottom: "conv2"top: "conv2" }layer {name: "conv3"type: "Convolution"bottom: "conv2"top: "conv3"param {lr_mult: 0.1}param {lr_mult: 0.1}convolution_param {num_output: 1kernel_size: 3stride: 1pad: 0weight_filler {type: "gaussian"std: 0.001}bias_filler {type: "constant"value: 0}} }layer {name: "loss"type: "EuclideanLoss"bottom: "conv3"bottom: "label"top: "loss" }
:wq保存退出。
5.CNN訓(xùn)練
$ vim train.sh
輸入以下shell:
#!/bin/bash
cd ../../
./build/tools/caffe train --solver examples/CNN/CNN_solver.prototxt 2>&1 | tee examples/CNN/CNN.log
增加運(yùn)行權(quán)限:
$ chmod +x train.sh
運(yùn)行腳本文件:
$ ./train.sh
時(shí)間可能會(huì)運(yùn)行幾天,也可以提前退出(Ctrl+C),因?yàn)樵趕napshot中有中間備份存儲(chǔ)。
6.保存濾波器
1.)創(chuàng)建mat文件
$ cp CNN_net.prototxt CNN_mat.prototxt
將CNN_mat.prototxt文件開(kāi)頭兩個(gè)layer段改為:
name: "CNN" input: "data" input_dim: 1 input_dim: 1 input_dim: 11 input_dim: 11input: "label" input_dim: 1 input_dim: 1 input_dim: 3 input_dim: 3
:wq保存即可。
2.)創(chuàng)建M文件
$ vim saveFilters.m
輸入以下內(nèi)容:(第7行可以更改需要轉(zhuǎn)換的caffemodel文件名)
caffe.reset_all(); clear; close all; %% settings %folder = 'examples/CNN/'; folder = './'; model = [folder 'CNN_mat.prototxt']; weights = [folder 'snapshot/CNN_iter_550000.caffemodel']; savepath = [folder 'model/x.mat']; layers = 3;%% load model using mat_caffe net = caffe.Net(model,weights,'test');%% reshap parameters weights_conv = cell(layers,1);for idx = 1 : layersconv_filters = net.layers(['conv' num2str(idx)]).params(1).get_data();[~,fsize,channel,fnum] = size(conv_filters);if channel == 1weights = double(ones(fsize^2, fnum));elseweights = double(ones(channel, fsize^2, fnum));endfor i = 1 : channelfor j = 1 : fnumtemp = conv_filters(:,:,i,j);if channel == 1weights(:,j) = temp(:);elseweights(i,:,j) = temp(:);endendendweights_conv{idx} = weights; end%% save parameters weights_conv1 = weights_conv{1}; weights_conv2 = weights_conv{2}; weights_conv3 = weights_conv{3}; biases_conv1 = double(net.layers('conv1').params(2).get_data()); biases_conv2 = double(net.layers('conv2').params(2).get_data()); biases_conv3 = double(net.layers('conv3').params(2).get_data());save(savepath,'weights_conv1','biases_conv1','weights_conv2','biases_conv2','weights_conv3','biases_conv3');
:wq保存。
3.)運(yùn)行M文件
$ matlab -nodesktop -nosplash -logfile saveFilters.log -r saveFilters
此時(shí),在model中會(huì)生成x.mat文件。
7.CNN重構(gòu)
已經(jīng)知道了x.mat文件中,有三層卷積層的卷積核矩陣weights_conv*和偏置向量biases_conv*。
編寫一個(gè)demo_net.m文件,使用這些參數(shù)構(gòu)建卷積網(wǎng)絡(luò)結(jié)構(gòu),對(duì)輸入圖像(矩陣)進(jìn)行處理,即可得到結(jié)果。
不同應(yīng)用有不同的源碼,這里省略該文件源碼。
本文可能敘述不全面,如有錯(cuò)誤,歡迎指正!
Enjoy~~
轉(zhuǎn)載于:https://www.cnblogs.com/lixuebin/p/10814875.html
總結(jié)
以上是生活随笔為你收集整理的使用GPU在caffe上进行CNN训练的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ReactJS学习笔记八:动画
- 下一篇: solaris 源代码