基于ReLU和Softmax的简单深度神经网络matlab代码设计 - 20170427
更新时间:2024-01-24 18:04:01 阅读量: 教育文库 文档下载
基于ReLU和Softmax的简单深度神经网络matlab代码设计
本文以matlab为工具介绍下如何实现神经元激活函数为ReLU的深度神经网络。ReLU函数的数学公式很简单ReLU(x)=max(x,0),但其对DNN的贡献是巨大的。若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) ifrt(k)<=0
TrainLabel(k)=1; else
TrainLabel(k)=2; end end
save('MyData.mat','TrainData','TrainLabel')
第二步:网络配置、参数初始化和转换
将第一步中准备好的数据载入内存中,并采用以下程序运行数据。
1. Main_function
clear all clc
close all
loadMyData.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;%网络最后一层神经元数数目,再考虑一个偏置。
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;
%%每次训练的小批量样本数
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代码如下,都是
2
Andrew Ng的教程里面的提供的。
2. Main_module_without_minFunc1
clear all clc
close all
loadMyData.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;
3
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;
% %%每次训练的小批量样本数
% 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. 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);%传进来的样本数
%开始前馈,网络虽然多层,但只是重复而已
4
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
4. relu
function re = relu(x) re = max(x,0)-1; end
5. drelu
functiondre= drelu(x) dre=zeros(size(x)); dre(x>0)=1;
dre(x==0)=0.5;%这句可以不要 end
6. 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
7. 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);
6
curPos = curPos+blen; % Set previous layer size
prevLayerSize = netconfig.layersizes{d}; end end
8. stack2params
function [params, netconfig] = stack2params(stack) params = []; for d = 1:numel(stack) params = [params ; stack{d}.w(:) ; stack{d}.b(:) ]; end ifnargout> 1 ifnumel(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
loadMyData.mat
loadweights_matrix.mat
inputsize=size(TrainData ,1);%获取数据的维度 datanum=size(TrainData ,2);%获取数据的数量 % netsize=[inputsize,50,50,50];
%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。
netsize=[inputsize,4,3]; classnum=2;%类别数目
7
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
functionv_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
8
正在阅读:
基于ReLU和Softmax的简单深度神经网络matlab代码设计 - 2017042701-24
形容花香的成语02-14
经典散文岁月风平11-21
大学无机化学复习题05-12
高一地理必修一知识点总结07-28
金融中介学 复习整理04-09
联想思维03-09
白丽教授分享无限极产品功效05-14
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 神经网络
- 深度
- 20170427
- 基于
- Softmax
- 代码
- 简单
- matlab
- 设计
- ReLU
- xxxxxxxxx污水处理站情况说明
- 以中医文化建设为核心加快医院发展步伐1
- 高中班团会设计方案
- 最高人民法院《全国民事审判工作会议纪要》法办442号
- 二〇一一年浙江省学生艺术特长水平 - 图文
- 电力工程造价试卷 带答案
- 加强干部挂职轮岗交流的探索与实践
- 2018超星尔雅学习通《大学生创新基础》期末考试答案完整版
- 材料分析测试方法试题及答案
- 人和动物体内三大营养物质的代谢
- 概要介绍ICMP、TCP及UDP 三种高级扫描技术及原理
- 湖南省07-10年真题
- 浅谈小学高效课堂的构建
- 铁路工程概预算软件使用说明书
- 2017-2018年人教版六年级上册数学第一二单元试卷试题试卷
- 2018年初中毕业生学业考试最新模拟考语文试题及答案(11)
- 醉花阴 优秀教案
- 学业测试-中职语文第二册4-6单元张香来
- 毕业设计论文 - 图文
- 传感器与检测技术