用matlab做深度學習,有什麼工具箱可以直接調用嗎?
好像caffe也支持matlab語言,不過好像不太好接入matlab。新手一枚,望多多指教
Matlab那個DeepLearnToolBox,其實入門很不錯的,而且特比好用,代碼寫的非常簡單明了。
DeepLearnToolbox是一個簡單理解CNN過程的工具箱,可以在github下載。
net中一些參數進行說明:
net.fv: 最後一層隱藏層的特徵矩陣,採用的是全連接方式
net.o: 最後輸出的結果,每一列為一個樣本結果
net.od: 最後一層輸出層所對應的殘差
net.fvd: 最後一層隱藏層所對應的誤差(全連接的方式)
test_example_CNN.m
[plain] view plain copy print?
- %function test_example_CNN
- addpath D:DeepLearningDeepLearnToolbox-masterdata
- addpath D:DeepLearningDeepLearnToolbox-masterCNN
- addpath D:DeepLearningDeepLearnToolbox-masterutil
- load mnist_uint8;
- train_x = double(reshape(train_x",28,28,60000))/255; % 訓練集變成60000張28*28的圖片大小 28*28*60000,像素點歸一化到[0,1]
- test_x = double(reshape(test_x",28,28,10000))/255; % 測試集 28*28*10000
- train_y = double(train_y"); %10*6000 每列代表一個標籤 softmax回歸模型
- test_y = double(test_y");
- %% ex1 Train a 6c-2s-12c-2s Convolutional neural network
- %will run 1 epoch in about 200 second and get around 11% error.
- %With 100 epochs you"ll get around 1.2% error
- rand("state",0)
- cnn.layers = { %%% 設置各層feature maps個數及卷積模板大小等屬性
- struct("type", "i") %input layer
- struct("type", "c", "outputmaps", 6, "kernelsize", 5) %convolution layer
- struct("type", "s", "scale", 2) %sub sampling layer
- struct("type", "c", "outputmaps", 12, "kernelsize", 5) %convolution layer
- struct("type", "s", "scale", 2) %subsampling layer
- };
- opts.alpha = 0.01; %迭代下降的速率
- opts.batchsize = 50; %每次選擇50個樣本進行更新 隨機梯度下降,每次只選用50個樣本進行更新
- opts.numepochs = 50; %迭代次數
- cnn = cnnsetup(cnn, train_x, train_y); %對各層參數進行初始化 包括權重和偏置
- cnn = cnntrain(cnn, train_x, train_y, opts); %訓練的過程,包括bp演算法及迭代過程
- [er, bad] = cnntest(cnn, test_x, test_y);
- %plot mean squared error
- figure; plot(cnn.rL);
- % assert(er&<0.12, "Too big error");
cnnsetup.m
[plain] view plain copy print?
- function net = cnnsetup(net, x, y)
- % assert(~isOctave() || compare_versions(OCTAVE_VERSION, "3.8.0", "&>="), ["Octave 3.8.0 or greater is required for CNNs as there is a bug in convolution in previous versions. See http://savannah.gnu.org/bugs/?39314. Your version is " myOctaveVersion]);
- inputmaps = 1; %輸入圖片數量 輸入feature maps數量
- mapsize = size(squeeze(x(:, :, 1))); % 圖片的大小 squeeze 要不要都行28 28
- for l = 1 : numel(net.layers) % layer
- if strcmp(net.layers{l}.type, "s")
- mapsize = mapsize / net.layers{l}.scale; %% sumsampling的featuremap長寬都是上一層卷積層featuremap的一半
- assert(all(floor(mapsize)==mapsize), ["Layer " num2str(l) " size must be integer. Actual: " num2str(mapsize)]);
- for j = 1 : inputmaps
- net.layers{l}.b{j} = 0; % 將偏置初始化0, 權重weight,,這段代碼subsampling層將weight設為1/4 而偏置參數設為0,故subsampling階段無需參數
- end
- end
- if strcmp(net.layers{l}.type, "c")
- mapsize = mapsize - net.layers{l}.kernelsize + 1; % 得到當前層feature map的大小
- fan_out = net.layers{l}.outputmaps * net.layers{l}.kernelsize ^ 2; % fan_out與fan_in都是用來初始化kernel的,不知道why
- for j = 1 : net.layers{l}.outputmaps % output map 當前層feature maps的個數
- fan_in = inputmaps * net.layers{l}.kernelsize ^ 2;
- for i = 1 : inputmaps % input map 共享權值,故kernel參數個數為inputmaps*outputmaps個數,每一個都是5*5
- net.layers{l}.k{i}{j} = (rand(net.layers{l}.kernelsize) - 0.5) * 2 * sqrt(6 / (fan_in + fan_out)); %% 初始化每個feature map對應的kernel參數 -0.5 再乘2歸一化到[-1,1],最終歸一化到[-sqrt(6 / (fan_in + fan_out)),+sqrt(6 / (fan_in + fan_out))] why??
- end
- net.layers{l}.b{j} = 0; % 初始話feture map對應的偏置參數 初始化為0
- end
- inputmaps = net.layers{l}.outputmaps; % 修改輸入feature maps的個數以便下次使用
- end
- end
- % "onum" is the number of labels, that"s why it is calculated using size(y, 1). If you have 20 labels so the output of the network will be 20 neurons.
- % "fvnum" is the number of output neurons at the last layer, the layer just before the output layer.
- % "ffb" is the biases of the output neurons.
- % "ffW" is the weights between the last layer and the output neurons. Note that the last layer is fully connected to the output layer, that"s why the size of the weights is (onum * fvnum)
- fvnum = prod(mapsize) * inputmaps; % S4最後結點個數即為特徵的個數 用作全連接 12*4*4=192維特徵
- onum = size(y, 1); %最終分類的個數 10類
- net.ffb = zeros(onum, 1); %softmat回歸的偏置參數個數
- net.ffW = (rand(onum, fvnum) - 0.5) * 2 * sqrt(6 / (onum + fvnum)); %% softmaxt回歸的權值參數 為10*192個 全連接
- end
cnntrain.m
[plain] view plain copy print?
- function net = cnntrain(net, x, y, opts)
- m = size(x, 3); %% 圖片一共的數量 60000
- numbatches = m / opts.batchsize; % 循環的次數 共1200次,每次使用50個樣本進行
- if rem(numbatches, 1) ~= 0
- error("numbatches not integer");
- end
- net.rL = [];
- for i = 1 : opts.numepochs
- disp(["epoch " num2str(i) "/" num2str(opts.numepochs)]);
- tic;
- kk = randperm(m); %% 隨機產生m以內的不重複的m個數
- for l = 1 : numbatches %% 循環1200次,每次選取50個樣本進行更新
- batch_x = x(:, :, kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize)); %50個樣本的訓練數據
- batch_y = y(:, kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize)); %50個樣本所對應的標籤
- net = cnnff(net, batch_x); %計算前向傳播
- net = cnnbp(net, batch_y); %bp演算法更新參數
- opts.i = i;
- opts.l = l;
- net = cnnapplygrads(net, opts); %% 運用梯度迭代更新參數
- if isempty(net.rL)
- net.rL(1) = net.L;
- end
- net.rL(end + 1) = 0.99 * net.rL(end) + 0.01 * net.L; %為什麼要這樣計算不太明白 net.L為每次迭代時候的cost function
- end
- toc;
- end
- end
cnnff.m
[plain] view plain copy print?
- function net = cnnff(net, x)
- n = numel(net.layers); %% 所具有的層數
- net.layers{1}.a{1} = x; %第一層的激勵值初始化
- inputmaps = 1;
- for l = 2 : n % for each layer %針對每一個卷積層
- if strcmp(net.layers{l}.type, "c")
- % !!below can probably be handled by insane matrix operations
- for j = 1 : net.layers{l}.outputmaps % for each output map %針對該層的每一個feture map
- % create temp output map
- z = zeros(size(net.layers{l - 1}.a{1}) - [net.layers{l}.kernelsize - 1 net.layers{l}.kernelsize - 1 0]); % 該層feture map的大小,最後一位是樣本圖片個數 初始化為0
- for i = 1 : inputmaps % for each input map %針對每一個輸入feature map
- % convolve with corresponding kernel and add to temp output map
- z = z + convn(net.layers{l - 1}.a{i}, net.layers{l}.k{i}{j}, "valid"); %做卷積操作 k{i}{j} 是5*5的double類型,其中a{i}是輸入圖片的feature map 大小為28*28*50 50為圖像數量
- end %% 卷積操作這裡的k是不是應該旋轉180度
- % add bias, pass through nonlinearity
- net.layers{l}.a{j} = sigm(z + net.layers{l}.b{j}); %%獲取sigmoid function的值
- end
- % set number of input maps to this layers number of outputmaps
- inputmaps = net.layers{l}.outputmaps; %% 設置新的輸入feature maps的個數
- elseif strcmp(net.layers{l}.type, "s") %%% 下採樣採用的方法是,2*2相加乘以權值1/4, 沒有取偏置和取sigmoid
- % downsample
- for j = 1 : inputmaps
- z = convn(net.layers{l - 1}.a{j}, ones(net.layers{l}.scale) / (net.layers{l}.scale ^ 2), "valid"); % !! replace with variable %%先卷積後各行各列取結果
- net.layers{l}.a{j} = z(1 : net.layers{l}.scale : end, 1 : net.layers{l}.scale : end, :); %得到的結果是上一層卷積層行列的一半 a=z
- end
- end
- end
- % concatenate all end layer feature maps into vector
- net.fv = []; %%用來保存最後一個隱藏層所對應的特徵 將feature maps變成全連接的形式
- for j = 1 : numel(net.layers{n}.a) % 最後一層隱層具有的feture map數量
- sa = size(net.layers{n}.a{j});
- net.fv = [net.fv; reshape(net.layers{n}.a{j}, sa(1) * sa(2), sa(3))]; %% 最後得到192*50的矩陣,每一列對應一個樣本圖像的特徵,192=4*4*12 12個feturemap
- end
- % feedforward into output perceptrons
- net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2))); %% 結果為10*50的矩陣,每一列表示一個樣本圖像的標籤結果 取了sigmoid function表明是k個二分類器,各類之間不互斥,當然也可以換成softmax回歸
- % net.o = softmax(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2)));
- end
cnnbp.m
[plain] view plain copy print?
- function net = cnnbp(net, y)
- n = numel(net.layers); %layers個數
- % error
- net.e = net.o - y; % 10*50 每一列表示一個樣本圖像
- % loss function
- net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2); %% cost function 沒有加入參數構成貝葉斯學派的觀點
- %% backprop deltas
- net.od = net.e .* (net.o .* (1 - net.o)); % output delta 輸出層的誤差 用來求解 10*50
- net.fvd = (net.ffW" * net.od); % feature vector delta 最後一層隱藏層誤差 如果是下採樣層,由於a=z,所以誤差就是這個結果(導數為1,就是對z求導),如果是卷積層,那麼需要乘以f(z)的導數 192*50
- if strcmp(net.layers{n}.type, "c") % only conv layers has sigm function
- net.fvd = net.fvd .* (net.fv .* (1 - net.fv)); %% 如果最後一個隱藏層是卷積層,直接用該公式就能得到誤差
- end
- % reshape feature vector deltas into output map style
- sa = size(net.layers{n}.a{1}); %%layers{n}共有12個a 每個a都是4*4*50 50 為樣本圖片的個數 n表示最後一層隱藏層
- fvnum = sa(1) * sa(2);
- for j = 1 : numel(net.layers{n}.a) %%最後一個隱藏層一共有多少個feature maps,每個feature map即表示為d{j}變成4*4*50的形式,50為樣本圖片數量,這樣好用於計算前面層次的誤差**** 轉變
- net.layers{n}.d{j} = reshape(net.fvd(((j - 1) * fvnum + 1) : j * fvnum, :), sa(1), sa(2), sa(3)); %將最後一層隱藏層變成feature maps的形式,這樣易求解前一層卷積的結果
- end
- for l = (n - 1) : -1 : 1 %實際是到2終止了,1是輸入層,沒有誤差要求
- if strcmp(net.layers{l}.type, "c") %卷積層的計算方式
- for j = 1 : numel(net.layers{l}.a) %第n-1層具有的feature maps的個數,進行遍歷 每個d{j}是8*8*50的形式, 由於下一層為下採樣層,故後一層d{j}擴展為8*8的(每個點複製成2*2的),按照bp求誤差公式就可以得出,這裡權重就為1/4,
- net.layers{l}.d{j} = net.layers{l}.a{j} .* (1 - net.layers{l}.a{j}) .* (expand(net.layers{l + 1}.d{j}, [net.layers{l + 1}.scale net.layers{l + 1}.scale 1]) / net.layers{l + 1}.scale ^ 2);
- end
- elseif strcmp(net.layers{l}.type, "s") %下採樣層的計算方式
- for i = 1 : numel(net.layers{l}.a) %該層feature maps的個數 每個a都是12*12*50 的大小,其中50為樣本圖片的個數
- z = zeros(size(net.layers{l}.a{1})); %大小等於 當前層feature map的大小
- for j = 1 : numel(net.layers{l + 1}.a) %計算公式來自 Notes on Convolutional Neural Networks的pdf,,將當前層下採樣層與後面的採樣層每個feature map相連接, 故按照bp的公式要進行求和
- z = z + convn(net.layers{l + 1}.d{j}, rot180(net.layers{l + 1}.k{i}{j}), "full"); %%% 可以舉一個簡單的例子進行講解 所有節點相乘都是相加的(因為該結點是與後一層所有的feature maps都是有連接的),
- end %% 卷積 full valid是什麼意思 要弄清楚????
- net.layers{l}.d{i} = z; %% 因為是下採樣層,所以a=z,就f(z)=z,導數就等於1,所以誤差就是所連接結點權值與後一層誤差和
- end
- end
- end
- %% calc gradients %% 對kij求偏導沒有看懂 為什麼要進行求和
- for l = 2 : n
- if strcmp(net.layers{l}.type, "c")
- for j = 1 : numel(net.layers{l}.a)
- for i = 1 : numel(net.layers{l - 1}.a)
- net.layers{l}.dk{i}{j} = convn(flipall(net.layers{l - 1}.a{i}), net.layers{l}.d{j}, "valid") / size(net.layers{l}.d{j}, 3); % 可以看論文中的推導!與論文中先將k rot180,然後再rot整體效果是一樣的。
- end
- net.layers{l}.db{j} = sum(net.layers{l}.d{j}(:)) / size(net.layers{l}.d{j}, 3); %% 對偏置參數b的導數
- end
- end
- end
- net.dffW = net.od * (net.fv)" / size(net.od, 2); %softmax回歸中參數所對應的導數
- net.dffb = mean(net.od, 2); %% softmax回歸中最後參數b所對應的導數
- function X = rot180(X)
- X = flipdim(flipdim(X, 1), 2); % flipdim(X, 1) 行互換 flipdim(X, 2) 列互換
- end
- end
cnnapplygrads.m
[plain] view plain copy print?
- function net = cnnapplygrads(net, opts)
- for l = 2 : numel(net.layers)
- if strcmp(net.layers{l}.type, "c")
- for j = 1 : numel(net.layers{l}.a)
- for ii = 1 : numel(net.layers{l - 1}.a)
- net.layers{l}.k{ii}{j} = net.layers{l}.k{ii}{j} - 1/(opts.i+opts.alpha + opts.l) * net.layers{l}.dk{ii}{j}; %% 梯度下降求更新後的參數
- end
- net.layers{l}.b{j} = net.layers{l}.b{j} - 1/(opts.i+opts.alpha + opts.l) * net.layers{l}.db{j};
- end
- end
- end
- net.ffW = net.ffW - 1/(opts.i+opts.alpha + opts.l) * net.dffW;
- net.ffb = net.ffb - 1/(opts.i+opts.alpha + opts.l) * net.dffb;
- end
cnntest.m
[plain] view plain copy print?
- function [er, bad] = cnntest(net, x, y)
- % feedforward
- net = cnnff(net, x);
- [~, h] = max(net.o);
- [~, a] = max(y);
- bad = find(h ~= a);
- er = numel(bad) / size(y, 2);
- end
用MATLAB做深度學習推薦以下幾種途徑:
1、官方neutral network toolbox自帶的用於深度學習新功能函數,最近每個新版本都會大量更新深度學習方面的內容。支持普通卷積神經網路(ConvNets, CNNs),DAGNN (Directed acyclic graph neural network) 有向圖非循環神經網路、長短記憶網路long short-term memory (LSTM)等。支持預訓練好的網路模型,如GoogLeNet, AlexNet, VGG16, and VGG19,resnet50,另外支持從caffe model zoo直接導入網路的函數importCaffeNetwork、importCaffeLayers,importKerasLayers還有些訓練,提取,可視化特徵的函數trainNetwork、activations、classify、imageDatastore、deepDreamImage等等,遷移學習,特徵提取,訓練自己的網路,基本上你想要的都有。最主要最重要的是其有豐富完善的幫助文檔,很多不錯的實例demo,demo2。具體可以點擊這裡查看Neural Network Toolbox
2、編譯caffe的MATLAB介面matCaffe,用法參見caffe的Matlab介面的使用方法 - CSDN博客。這個用起來也非常方便的,caffe裡面調試網路推薦用這個。
3、樓主提到的matconvnet,是幾年前比較火的第三方工具箱,官網鏈接參看這裡Home - MatConvNet
4、推薦一本最新比較權威的書籍《MATLAB Deep Learning》 2017-Phil Kim博士著作,with machine learning,neural networks and Artificial intelligence,值得一看~http://download.csdn.net/download/cuixing001/10112280
一個是caffe有Matlab的介面,和caffe的c以及python介面調用方式基本一樣,但是如果要用到cuda的話,好像parallel computing toolbox要Matlab2015b以上的版本才有。另一個是Matconvnet有提供常用的CNN模型和pretrianed參數,簡單的一些應用都可以用這個啦。
Deep Learning - MATLAB amp; Simulink - MathWorks 中國
這是官網對於NN TOOLBOX中DL的介紹
可以看下我們公司同事寫的lightnet
libsvm:LIBSVM -- A Library for Support Vector Machines
MatConvNet: CNNs for MATLAB MatConvNet
新手的話,不建議從matlab開始。人生苦短,還是Python好一些。
推薦閱讀:
※caffe finetune問題:按照網上的教程微調alexnet為什麼loss一直是87.3365?
※caffe SolverParameter中的iter_size參數什麼作用?
※GTX1080/1070配置深度學習環境。求指導,剛入手~?
※如何評價Facebook Training ImageNet in 1 Hour這篇論文?
※如何看待賈揚清Caffe2go開源,手機就能訓練神經網路?
TAG:MATLAB | 深度學習DeepLearning | Caffe深度學習框架 |