您好,欢迎访问三七文档
1基于ReLU和Softmax的简单深度神经网络matlab代码设计本文以matlab为工具介绍下如何实现神经元激活函数为ReLU的深度神经网络。ReLU函数的数学公式很简单ReLU(x)=max(x,0),但其对DNN的贡献是巨大的。若DNN用于数据分类,则可以简单的认为其主要由两个部分组成:多隐层网络+分类器。分类器以softmax为例。第一步:准备数据1)将你需要分类的样本数据以每列的形式保存于矩阵中;-TrainData2)将每个样本的类别标记按数据顺序存为一行向量,类别为1,2,3,…,n;-TrainLabel并将数据保存入MyData.mat数据文件中。采用以下程序实现数据的生成。x=1:10y=1:8:80rt=x.*x-50*x+40*y-y.^2;TrainData=[x;y];fork=1:10v_rt_k=rt(k)ifrt(k)=0TrainLabel(k)=1;elseTrainLabel(k)=2;endendsave('MyData.mat','TrainData','TrainLabel')第二步:网络配置、参数初始化和转换将第一步中准备好的数据载入内存中,并采用以下程序运行数据。1.Main_functionclearallclccloseallloadMyData.matinputsize=size(TrainData,1);%获取数据的维度datanum=size(TrainData,2);%获取数据的数量2%netsize=[inputsize,50,50,50];%可以简单地用一个向量来定义网络的深度,以及每层神经元数目。这表示一个三隐藏层的DNN,神经元数都为50。netsize=[inputsize,4,3];classnum=2;%类别数目lastsize=netsize(end)+1;%网络最后一层神经元数数目,再考虑一个偏置。stack=initializeNet(netsize);%初始化网络参数,以结构体的形式保存。v_stack=stackv_stack_1=stack{1}v_stack_1_w=stack{1}.wv_stack_1_b=stack{1}.bv_stack_2=stack{2}v_stack_2_w=stack{2}.wv_stack_2_b=stack{2}.b%在训练时,往往需要将参数转成一列向量,提供给损失函数。stack-stackTheta,netconfig保存一些结构参数[stackTheta,netconfig]=stack2params(stack);v_stackTheta=stackThetav_netconfig=netconfigv_netconfig_layersizes=netconfig.layersizesv_lastsize=lastsizeSoftmaxTheta=0.0005*randn(lastsize*classnum,1);v_SoftmaxTheta=SoftmaxThetaTheta=[SoftmaxTheta;stackTheta];%最终网络需要的参数%thefollowingpartisforthetraingepoch.batchsize=10;%batchsize=5;%%每次训练的小批量样本数/spanbatchnum=floor(size(TrainData,2)/batchsize);DataNum=size(TrainData,2);alpha=1e-2;%这是学习率,一般随着网络的悬念都需要不断的减小lambda=1e-4;%Weightdecayparameterforepoch=1:16000v_epoch=epochidx=randperm(DataNum);fort=1:batchnumsubdata=TrainData(:,idx((t-1)*batchsize+1:(t)*batchsize));3sublabel=TrainLabel(idx((t-1)*batchsize+1:(t)*batchsize));[cost,grad]=ReLUDNNCost(Theta,classnum,lastsize,netconfig,lambda,subdata,sublabel);Theta=Theta-alpha*grad;v_grad=gradendend%Note:当Theta传递进入损失函数内部时,还需要从Theta抽出stackTheta,再转成stack代码如下,都是AndrewNg的教程里面的提供的。2.ReLUDNNCostfunction[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;ford=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函数的导函数enda2=[a2;ones(1,datanum)];%开始求解损失%v_trainLabels=trainLabels%v_datanum=datanumgroundTruth=full(sparse(trainLabels,1:datanum,1));%%这是AndrewNG教程原版的语句,但其在应用小批量样本训练时会出错,下一行是另一种实现方式%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%pauseM=softmaxTheta*a2;4h=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);%想理解这里,还有后面的梯度是如何计算出的,建议看那本关于矩阵的工具书《TheMatrixCookbook》predelta=predelta(1:end-1,:);ford=numel(stack):-1:1delta=predelta.*PARA{d}.daz;stackgrad{d}.w=delta*PARA{d}.a'/datanum;%.*PARA{d}.idxstackgrad{d}.b=sum(delta,2)/datanum;predelta=stack{d}.w'*delta;endgrad=[softmaxThetaGrad(:);stack2params(stackgrad)];end3.relufunctionre=relu(x)re=max(x,0)-1;end4.drelufunctiondre=drelu(x)dre=zeros(size(x));dre(x0)=1;dre(x==0)=0.5;%这句可以不要end5.initializeNetfunctionstack=initializeNet(netsize)layersize=length(netsize(:));stack=cell(layersize-1,1);forl=1:layersize-1hiddenSize=netsize(l+1);visibleSize=netsize(l);r=sqrt(6)/sqrt(hiddenSize+visibleSize+1);5stack{l}.w=rand(hiddenSize,visibleSize)*2*r-r;stack{l}.b=zeros(hiddenSize,1);endend6.params2stackfunctionstack=params2stack(params,netconfig)depth=numel(netconfig.layersizes);stack=cell(depth,1);prevLayerSize=netconfig.inputsize;%thesizeofthepreviouslayercurPos=double(1);%markcurrentpositioninparametervectorford=1:depth%Createlayerdstack{d}=struct;%Extractweightswlen=double(netconfig.layersizes{d}*prevLayerSize);stack{d}.w=reshape(params(curPos:curPos+wlen-1),netconfig.layersizes{d},prevLayerSize);curPos=curPos+wlen;%Extractbiasblen=double(netconfig.layersizes{d});stack{d}.b=reshape(params(curPos:curPos+blen-1),netconfig.layersizes{d},1);curPos=curPos+blen;%SetpreviouslayersizeprevLayerSize=netconfig.layersizes{d};endend7.stack2paramsfunction[params,netconfig]=stack2params(stack)params=[];ford=1:numel(stack)params=[params;stack{d}.w(:);stack{d}.b(:)];endifnargout1ifnumel(stack)==0netconfig.inputsize=0;netconfig.layersizes={};elsenetconfig.inputsize=size(stack{1}.w,2);netconfig.layersizes={};ford=1:numel(stack)netconfig.layersizes=[netconfig.layersizes;size(stack{d}.w,1)];
本文标题:基于ReLU和Softmax的简单深度神经网络matlab代码设计-20170419
链接地址:https://www.777doc.com/doc-4848675 .html