采用ReLU作为激活函数的简单深度神经网络matlab代码设计
来源:互联网 发布:淘宝买卖交易平台 编辑:程序博客网 时间:2024/06/10 20:27
本文介绍下如何实现神经元激活函数为ReLU的深度神经网络。ReLU函数的数学公式很简单ReLU(x)=max(x,0)。若DNN用于数据分类,则可以简单的认为其主要由两个部分组成:多隐层网络+分类器。分类器采用softmax。
第一步:准备数据
1)将你需要分类的样本数据以每列的形式保存于矩阵中;->TrainData
2)将每个样本的类别标记按数据顺序存为一行向量,类别为1,2,3,…,n;->TrainLabel
并将数据保存入MyData.mat数据文件中。
采用以下程序实现数据的生成。
x=1:10
y=1:8:80
rt=x.*x-50*x+40*y-y.^2;
TrainData=[x;y];
for k=1:10
v_rt_k=rt(k)
if rt(k)<=0
TrainLabel(k)=1;
else
TrainLabel(k)=2;
end
end
save('MyData.mat','TrainData','TrainLabel')
第二步:网络配置、参数初始化和转换
将第一步中准备好的数据载入内存中,并采用以下程序运行数据。
1. Main_function without minFunc
clear all
clc
close all
load MyData.mat
inputsize=size(TrainData ,1);%获取数据的维度
datanum=size(TrainData ,2);%获取数据的数量
% netsize=[inputsize,50,50,50];
%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。
netsize=[inputsize,4,3];
classnum=2;%类别数目
lastsize=netsize(end)+1;%网络最后一层神经元数数目,再考虑一个偏置。
stack = initializeNet(netsize);%初始化网络参数,以结构体的形式保存。
v_stack=stack
v_stack_1=stack{1}
v_stack_1_w=stack{1}.w
v_stack_1_b=stack{1}.b
v_stack_2=stack{2}
v_stack_2_w=stack{2}.w
v_stack_2_b=stack{2}.b
%在训练时,往往需要将参数转成一列向量,提供给损失函数。stack ->stackTheta,netconfig保存一些结构参数
[stackTheta, netconfig] = stack2params(stack);
v_stackTheta=stackTheta
v_netconfig=netconfig
v_netconfig_layersizes=netconfig.layersizes
v_lastsize=lastsize
SoftmaxTheta = 0.0005 * randn(lastsize * classnum, 1);
v_SoftmaxTheta=SoftmaxTheta
Theta=[ SoftmaxTheta ; stackTheta ];%最终网络需要的参数
% the following part is for the traing epoch.
batchsize=10;
% batchsize=5;
%%每次训练的小批量样本数</span>
batchnum=floor(size(TrainData,2)/batchsize);
DataNum=size(TrainData,2);
alpha=1e-2;
%这是学习率,一般随着网络的悬念都需要不断的减小
lambda = 1e-4; % Weight decay parameter
for epoch=1:16000
v_epoch=epoch
idx=randperm(DataNum);
for t=1:batchnum
subdata=TrainData(:,idx((t-1)*batchsize+1:(t)*batchsize));
sublabel=TrainLabel(idx((t-1)*batchsize+1:(t)*batchsize));
[cost,grad]=ReLUDNNCost(Theta,classnum,lastsize,netconfig,lambda,subdata,sublabel);
Theta=Theta-alpha*grad;
v_grad=grad
end
end
% Note: 当Theta传递进入损失函数内部时,还需要从Theta抽出stackTheta,再转成stack代码如下,都是Andrew Ng的教程里面的提供的。
2. Main_function with minFunc of UFLDL
clear all
clc
close all
load MyData.mat
inputsize=size(TrainData ,1);%获取数据的维度
datanum=size(TrainData ,2);%获取数据的数量
% netsize=[inputsize,50,50,50];
%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。
netsize=[inputsize,4,3];
classnum=2;%类别数目
lastsize=netsize(end)+1;%网络最后一层神经元数数目,再考虑一个偏置。
% v_lastsize=lastsize
stack = initializeNet(netsize);%初始化网络参数,以结构体的形式保存。
v_stack=stack
v_stack_1=stack{1}
v_stack_1_w=stack{1}.w
v_stack_1_b=stack{1}.b
v_stack_2=stack{2}
v_stack_2_w=stack{2}.w
v_stack_2_b=stack{2}.b
%在训练时,往往需要将参数转成一列向量,提供给损失函数。stack ->stackTheta,netconfig保存一些结构参数
[stackTheta, netconfig] = stack2params(stack);
v_stackTheta=stackTheta
v_netconfig=netconfig
v_netconfig_layersizes=netconfig.layersizes
v_lastsize=lastsize
SoftmaxTheta = 0.0005 * randn(lastsize * classnum, 1);
v_SoftmaxTheta=SoftmaxTheta
Theta=[ SoftmaxTheta ; stackTheta ];%最终网络需要的参数
% the following part is for the minFunc in the UFLDL tutorial
options.Method = 'lbfgs';
options.maxIter = 20000;
options.MaxFunEvals=1000000;
options.display = 'on';
lambda = 1e-4;
[OptTheta, cost] = minFunc( @(p)ReLUDNNCost(p,classnum,lastsize,netconfig,lambda, TrainData,TrainLabel),Theta, options);
v_TrainLabel=TrainLabel
save('weights_matrix_minFunc.mat','OptTheta')
% % the following part is for the SGD traing epoch.
% batchsize=10;
% % batchsize=5;
% %%每次训练的小批量样本数</span>
% batchnum=floor(size(TrainData,2)/batchsize);
% DataNum=size(TrainData,2);
% alpha=1e-2;
% %这是学习率,一般随着网络的悬念都需要不断的减小
% lambda = 1e-4; % Weight decay parameter
% for epoch=1:16000
% v_epoch=epoch
% idx=randperm(DataNum);
% for t=1:batchnum
% subdata=TrainData(:,idx((t-1)*batchsize+1:(t)*batchsize));
% sublabel=TrainLabel(idx((t-1)*batchsize+1:(t)*batchsize));
% [cost,grad]=ReLUDNNCost(Theta,classnum,lastsize,netconfig,lambda,subdata,sublabel);
% Theta=Theta-alpha*grad;
% v_grad=grad
% end
% end
% save('weights_matrix_minFunc.mat','Theta')
3. Main_function2 with minFunc of UFLDL
clear all
clc
close all
load MyData.mat
inputsize=size(TrainData ,1);%获取数据的维度
datanum=size(TrainData ,2);%获取数据的数量
% netsize=[inputsize,50,50,50];
%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。
netsize=[inputsize,4,3];
classnum=2;%类别数目
lastsize=netsize(end)+1;%网络最后一层神经元数数目,再考虑一个偏置。
% v_lastsize=lastsize
stack = initializeNet(netsize);%初始化网络参数,以结构体的形式保存。
v_stack=stack
v_stack_1=stack{1}
v_stack_1_w=stack{1}.w
v_stack_1_b=stack{1}.b
v_stack_2=stack{2}
v_stack_2_w=stack{2}.w
v_stack_2_b=stack{2}.b
%在训练时,往往需要将参数转成一列向量,提供给损失函数。stack ->stackTheta,netconfig保存一些结构参数
[stackTheta, netconfig] = stack2params(stack);
v_stackTheta=stackTheta
v_netconfig=netconfig
v_netconfig_layersizes=netconfig.layersizes
v_lastsize=lastsize
SoftmaxTheta = 0.0005 * randn(lastsize * classnum, 1);
v_SoftmaxTheta=SoftmaxTheta
Theta=[ SoftmaxTheta ; stackTheta ];%最终网络需要的参数
% the following part is for the traing epoch.
batchsize=10;
% batchsize=5;
%%每次训练的小批量样本数</span>
batchnum=floor(size(TrainData,2)/batchsize);
DataNum=size(TrainData,2);
alpha=1e-2;
%这是学习率,一般随着网络的悬念都需要不断的减小
lambda = 1e-4; % Weight decay parameter
for epoch=1:16000
v_epoch=epoch
idx=randperm(DataNum);
for t=1:batchnum
subdata=TrainData(:,idx((t-1)*batchsize+1:(t)*batchsize));
sublabel=TrainLabel(idx((t-1)*batchsize+1:(t)*batchsize));
[cost,grad]=ReLUDNNCost(Theta,classnum,lastsize,netconfig,lambda,subdata,sublabel);
Theta=Theta-alpha*grad;
v_grad=grad
end
v_trainLabels=sublabel
end
save('weights_matrix2.mat','Theta')
4. ReLUDNNCost
function [cost,grad] = ReLUDNNCost(theta,numClasses,lasthiddenSize, netconfig,lambda, trainData,trainLabels)
%参数获取的一些操作
softmaxTheta = reshape(theta(1:lasthiddenSize*numClasses), numClasses, lasthiddenSize);
stack = params2stack(theta(lasthiddenSize*numClasses+1:end), netconfig);
%从theta向量中抽取网络权值参数并转化
stackgrad = cell(size(stack));
PARA=cell(numel(stack),1);%这里保存在应用BP算法求梯度时需要的数据
datanum=size(trainData,2);%传进来的样本数
%开始前馈,网络虽然多层,但只是重复而已
data=trainData;
for d = 1:numel(stack)
PARA{d}.a=data;
z2=(stack{d}.w*data)+stack{d}.b*ones(1,datanum);
a2=relu(z2);%RelU函数
data=a2;
PARA{d}.daz=drelu(z2);%RelU函数的导函数
end
a2=[a2;ones(1,datanum)];
%开始求解损失
% v_trainLabels=trainLabels
% v_datanum=datanum
groundTruth = full(sparse(trainLabels, 1:datanum, 1));
% %这是Andrew NG教程原版的语句,但其在应用小批量样本训练时会出错,下一行是另一种实现方式
% v_trainLabels=trainLabels
% v_numClasses=numClasses
% v_element1=repmat(trainLabels,numClasses,1)
% v_element2=(1:1:numClasses)'
% groundTruth=bsxfun(@eq,repmat(trainLabels,numClasses,1),(1:1:numClasses)');
% v_groundTruth=groundTruth
% pause
M = softmaxTheta*a2;
h = exp(M);
h = bsxfun(@rdivide, h, sum(h));
% v_size_groundTruth=size(groundTruth)
% v_log_h=size(log(h))
cost = -1/datanum*sum(sum(groundTruth.*log(h)))+lambda/2*sum(sum(softmaxTheta.^2));
%softmax 损失函数,没啥好说的
softmaxThetaGrad = -1/datanum*((groundTruth-h)*a2')+lambda*softmaxTheta;
%softmax 目标函数对softmaxTheta的导数,
predelta=-softmaxTheta'*(groundTruth-h);
%想理解这里,还有后面的梯度是如何计算出的,建议看那本关于矩阵的工具书《The Matrix Cookbook》
predelta=predelta(1:end-1,:);
for d = numel(stack):-1:1
delta=predelta.*PARA{d}.daz;
stackgrad{d}.w=delta*PARA{d}.a'/datanum;%.*PARA{d}.idx
stackgrad{d}.b=sum(delta,2)/datanum;
predelta=stack{d}.w'*delta;
end
grad = [softmaxThetaGrad(:) ; stack2params(stackgrad)];
end
5. relu
function re = relu(x)
re = max(x,0)-1;
end
6. drelu
function dre= drelu(x)
dre=zeros(size(x));
dre(x>0)=1;
dre(x==0)=0.5;%这句可以不要
end
7. initializeNet
function stack = initializeNet(netsize)
layersize=length(netsize(:));
stack = cell(layersize-1,1);
for l=1:layersize-1
hiddenSize=netsize(l+1);
visibleSize=netsize(l);
r =sqrt(6) / sqrt(hiddenSize+visibleSize+1);
stack{l}.w= rand(hiddenSize, visibleSize) * 2 * r - r; stack{l}.b= zeros(hiddenSize, 1);
end
end
8. params2stack
function stack = params2stack(params, netconfig)
depth = numel(netconfig.layersizes);
stack = cell(depth,1);
prevLayerSize = netconfig.inputsize; % the size of the previous layer
curPos = double(1); % mark current position in parameter vector
for d = 1:depth
% Create layer d
stack{d} = struct;
% Extract weights
wlen = double(netconfig.layersizes{d} * prevLayerSize);
stack{d}.w = reshape(params(curPos:curPos+wlen-1), netconfig.layersizes{d}, prevLayerSize);
curPos = curPos+wlen;
% Extract bias
blen = double(netconfig.layersizes{d});
stack{d}.b = reshape(params(curPos:curPos+blen-1), netconfig.layersizes{d}, 1);
curPos = curPos+blen;
% Set previous layer size
prevLayerSize = netconfig.layersizes{d};
end
end
9. stack2params
function [params, netconfig] = stack2params(stack)
params = [];
for d = 1:numel(stack)
params = [params ; stack{d}.w(:) ;
stack{d}.b(:) ];
end
if nargout > 1
if numel(stack) == 0
netconfig.inputsize = 0;
netconfig.layersizes = {};
else
netconfig.inputsize = size(stack{1}.w, 2);
netconfig.layersizes = {};
for d = 1:numel(stack)
netconfig.layersizes = [netconfig.layersizes ; size(stack{d}.w,1)];
end
end
end
end
第三步,采用已训练的深度网络对输入数据进行测试
1. Main_test_function
clear all
clc
close all
load MyData.mat
load weights_matrix.mat
inputsize=size(TrainData ,1);%获取数据的维度
datanum=size(TrainData ,2);%获取数据的数量
% netsize=[inputsize,50,50,50];
%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。
netsize=[inputsize,4,3];
classnum=2;%类别数目
netconfig2.inputsize=netsize(1)
netconfig2.layersizes{1}=netsize(2)
netconfig2.layersizes{2}=netsize(3)
netconfig2.layersizes=netconfig2.layersizes'
lastsize=netsize(end)+1;%网络最后一层神经元数数目,再考虑一个偏置。
v_result = forward_computation(Theta,classnum,lastsize,netconfig2,TrainData)
v_TrainLabel=TrainLabel
2. forward_computation
function v_result = forward_computation(theta,numClasses,lasthiddenSize, netconfig,trainData,trainLabels)
%参数获取的一些操作
softmaxTheta = reshape(theta(1:lasthiddenSize*numClasses), numClasses, lasthiddenSize);
stack = params2stack(theta(lasthiddenSize*numClasses+1:end), netconfig);
%从theta向量中抽取网络权值参数并转化
stackgrad = cell(size(stack));
PARA=cell(numel(stack),1);%这里保存在应用BP算法求梯度时需要的数据
datanum=size(trainData,2);%传进来的样本数
%开始前馈,网络虽然多层,但只是重复而已
data=trainData;
for d = 1:numel(stack)
PARA{d}.a=data;
z2=(stack{d}.w*data)+stack{d}.b*ones(1,datanum);
a2=relu(z2);%RelU函数
data=a2;
PARA{d}.daz=drelu(z2);%RelU函数的导函数
end
a2=[a2;ones(1,datanum)];
M = softmaxTheta*a2;
h = exp(M);
h = bsxfun(@rdivide, h, sum(h));
v_result=h
end
- 采用ReLU作为激活函数的简单深度神经网络matlab代码设计
- 神经网络的激活函数sigmoid RELU
- 神经网络回顾-Relu激活函数
- python绘制神经网络中的ReLU激活函数图像(附代码)
- 【神经网络】RELU 激活函数及其他相关的函数
- 人工神经网络之激活函数 -RELU函数
- 神经网络之激活函数(sigmoid、tanh、ReLU)
- 神经网络之激活函数(sigmoid、tanh、ReLU)
- ReLU激活函数:简单之美
- ReLU激活函数:简单之美
- 深度学习神经网络激活函数的优点
- 深度学习笔记(4)——Sigmoid和Relu激活函数的对比
- tensorflow激活函数relu()的详解
- 深度学习常用激活函数之— Sigmoid & ReLU & Softmax
- 深度学习常用激活函数之— Sigmoid & ReLU & Softmax
- 深度学习——激活函数Sigmoid/Tanh/ReLU
- 深度学习常用激活函数之— Sigmoid & ReLU & Softmax
- 深度学习常用激活函数之— Sigmoid & ReLU & Softmax
- 搜索引擎研究
- java几种集合遍历速度对比(博客园迁移)
- React-navigation导航系统(1)
- 数据结构与算法(16)——树基本概念
- LOMBOK安装与使用
- 采用ReLU作为激活函数的简单深度神经网络matlab代码设计
- Android Handler.post 难道真的可以在子线程更新UI???
- React-navigation导航系统(2)
- 【CS231n笔记】06 Training Neural Networks, Part 2
- Lombok安装-消除冗长的 java 代码
- [Java] 高精度数据类型
- java实现简单计算器
- 数组中元素的排序,查找
- 指针及scanf函数的运用