神经网络在MATLAB中的应用
几天前我问了一个问题,但我想它有点太复杂了,我不希望得到任何答案 我的问题是,我需要使用人工神经网络进行分类。我读过更好的成本函数(或一些书中指定的损失函数)是交叉熵,即神经网络在MATLAB中的应用,matlab,neural-network,Matlab,Neural Network,几天前我问了一个问题,但我想它有点太复杂了,我不希望得到任何答案 我的问题是,我需要使用人工神经网络进行分类。我读过更好的成本函数(或一些书中指定的损失函数)是交叉熵,即J(w)=-1/m*sum_I(yi*ln(hw(xi))+(1-yi)*ln(1-hw(xi))i表示训练矩阵X中的编号数据。我试图在MATLAB中应用它,但我发现它真的很难。有几件事我不知道: 在给定所有训练数据的情况下,我是否应对每个输出求和(I=1,…N,其中N是训练输入的数量) 梯度计算是否正确 数值梯度(gradA
J(w)=-1/m*sum_I(yi*ln(hw(xi))+(1-yi)*ln(1-hw(xi))
i
表示训练矩阵X
中的编号数据。我试图在MATLAB中应用它,但我发现它真的很难。有几件事我不知道:
- 在给定所有训练数据的情况下,我是否应对每个输出求和(I=1,…N,其中N是训练输入的数量)
- 梯度计算是否正确
- 数值梯度(gradAapprox)计算是否正确
close all
clear all
L = @(x) (1 + exp(-x)).^(-1);
NN = @(x,theta) theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')];
% theta = [10 -30 -30];
x = [0 0; 0 1; 1 0; 1 1];
y = [0.9 0.1 0.1 0.1]';
theta0 = 2*rand(9,1)-1;
options = optimset('gradObj','on','Display','iter');
thetaVec = fminunc(@costFunction,theta0,options,x,y);
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
NN(x,theta)'
成本函数:
function [jVal,gradVal,gradApprox] = costFunction(thetaVec,x,y)
persistent index;
% 1 x x
% 1 x x
% 1 x x
% x = 1 x x
% 1 x x
% 1 x x
% 1 x x
m = size(x,1);
if isempty(index) || index > size(x,1)
index = 1;
end
L = @(x) (1 + exp(-x)).^(-1);
NN = @(x,theta) theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')];
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
Dew = cell(2,1);
DewApprox = cell(2,1);
% Forward propagation
a0 = x(index,:)';
z1 = theta{1}*[1;a0];
a1 = L(z1);
z2 = theta{2}*[1;a1];
a2 = L(z2);
% Back propagation
d2 = 1/m*(a2 - y(index))*L(z2)*(1-L(z2));
Dew{2} = [1;a1]*d2;
d1 = [1;a1].*(1 - [1;a1]).*theta{2}'*d2;
Dew{1} = [1;a0]*d1(2:end)';
% NNRes = NN(x,theta)';
% jVal = -1/m*sum(NNRes-y)*NNRes*(1-NNRes);
jVal = -1/m*(a2 - y(index))*a2*(1-a2);
gradVal = [Dew{1}(:);Dew{2}(:)];
gradApprox = CalcGradApprox(0.0001);
index = index + 1;
function output = CalcGradApprox(epsilon)
output = zeros(size(gradVal));
for n=1:length(thetaVec)
thetaVecMin = thetaVec;
thetaVecMax = thetaVec;
thetaVecMin(n) = thetaVec(n) - epsilon;
thetaVecMax(n) = thetaVec(n) + epsilon;
thetaMin = cell(2,1);
thetaMax = cell(2,1);
thetaMin{1} = reshape(thetaVecMin(1:6),[2 3]);
thetaMin{2} = reshape(thetaVecMin(7:9),[1 3]);
thetaMax{1} = reshape(thetaVecMax(1:6),[2 3]);
thetaMax{2} = reshape(thetaVecMax(7:9),[1 3]);
a2min = NN(x(index,:),thetaMin)';
a2max = NN(x(index,:),thetaMax)';
jValMin = -1/m*(a2min-y(index))*a2min*(1-a2min);
jValMax = -1/m*(a2max-y(index))*a2max*(1-a2max);
output(n) = (jValMax - jValMin)/2/epsilon;
end
end
end
编辑: 下面,我向可能感兴趣的人展示我的costFunction的正确版本
function [jVal,gradVal,gradApprox] = costFunction(thetaVec,x,y)
m = size(x,1);
L = @(x) (1 + exp(-x)).^(-1);
NN = @(x,theta) L(theta{2}*[ones(1,size(x,1));L(theta{1}*[ones(size(x,1),1) x]')]);
theta = cell(2,1);
theta{1} = reshape(thetaVec(1:6),[2 3]);
theta{2} = reshape(thetaVec(7:9),[1 3]);
Delta = cell(2,1);
Delta{1} = zeros(size(theta{1}));
Delta{2} = zeros(size(theta{2}));
D = cell(2,1);
D{1} = zeros(size(theta{1}));
D{2} = zeros(size(theta{2}));
jVal = 0;
for in = 1:size(x,1)
% Forward propagation
a1 = [1;x(in,:)']; % added bias to a0
z2 = theta{1}*a1;
a2 = [1;L(z2)]; % added bias to a1
z3 = theta{2}*a2;
a3 = L(z3);
% Back propagation
d3 = a3 - y(in);
d2 = theta{2}'*d3.*a2.*(1 - a2);
Delta{2} = Delta{2} + d3*a2';
Delta{1} = Delta{1} + d2(2:end)*a1';
jVal = jVal + sum( y(in)*log(a3) + (1-y(in))*log(1-a3) );
end
D{1} = 1/m*Delta{1};
D{2} = 1/m*Delta{2};
jVal = -1/m*jVal;
gradVal = [D{1}(:);D{2}(:)];
gradApprox = CalcGradApprox(x(in,:),0.0001);
% Nested function to calculate gradApprox
function output = CalcGradApprox(x,epsilon)
output = zeros(size(thetaVec));
for n=1:length(thetaVec)
thetaVecMin = thetaVec;
thetaVecMax = thetaVec;
thetaVecMin(n) = thetaVec(n) - epsilon;
thetaVecMax(n) = thetaVec(n) + epsilon;
thetaMin = cell(2,1);
thetaMax = cell(2,1);
thetaMin{1} = reshape(thetaVecMin(1:6),[2 3]);
thetaMin{2} = reshape(thetaVecMin(7:9),[1 3]);
thetaMax{1} = reshape(thetaVecMax(1:6),[2 3]);
thetaMax{2} = reshape(thetaVecMax(7:9),[1 3]);
a3min = NN(x,thetaMin)';
a3max = NN(x,thetaMax)';
jValMin = 0;
jValMax = 0;
for inn=1:size(x,1)
jValMin = jValMin + sum( y(inn)*log(a3min) + (1-y(inn))*log(1-a3min) );
jValMax = jValMax + sum( y(inn)*log(a3max) + (1-y(inn))*log(1-a3max) );
end
jValMin = 1/m*jValMin;
jValMax = 1/m*jValMax;
output(n) = (jValMax - jValMin)/2/epsilon;
end
end
end
我对你的代码只看了一眼。这里有一些提示 Q1 如果给定所有训练数据(I=1,…N,其中 N是用于培训的输入数量) 如果您谈论的是成本函数,那么通过训练示例的数量进行求和和和标准化是正常的,以便提供两者之间的比较 我无法从代码中判断您是否有一个矢量化的实现,它将改变答案。请注意,
sum
函数一次只能对单个维度求和,这意味着如果使用(M×N)数组,sum将生成一个1×N数组
成本函数应具有标量输出
Q2
梯度计算是否正确
梯度计算不正确-特别是三角洲看起来错误。试试下面的[PDF]它们非常好
Q3
数值梯度(gradAapprox)计算是否正确
这条线看起来有点可疑。这更有意义吗
output(n) = (jValMax - jValMin)/(2*epsilon);
编辑:实际上,我无法理解你的梯度近似。您应该只在参数中使用正向传播和小的调整来计算渐变。祝你好运 你好,卢克。首先谢谢你的回答。我会仔细阅读你提供的笔记。目前,我只想对Q3说,您的表达式与我在MATLAB中的表达式相同,但从视觉上看,您的表达式更清晰。干杯嘿,卢克,谢谢你的留言。现在一切正常,通过分析和数值计算得到的梯度非常相似,这意味着模型训练正确:)祝你一切顺利,齐科