MATLAB 中的神经网络成本函数
Posted
技术标签:
【中文标题】MATLAB 中的神经网络成本函数【英文标题】:Neural Network Cost Function in MATLAB 【发布时间】:2014-02-21 20:50:39 【问题描述】:我将如何在 matlab 中实现这个神经网络成本函数:
以下是符号所代表的含义:
% m is the number of training examples. [a scalar number]
% K is the number of output nodes. [a scalar number]
% Y is the matrix of training outputs. [an m by k matrix]
% y^(i)_k is the ith training output (target) for the kth output node. [a scalar number]
% x^(i) is the ith training input. [a column vector for all the input nodes]
% h_\theta(x^(i))_k is the value of the hypothesis at output k, with weights theta, and training input i. [a scalar number]
%note: h_\theta(x^(i)) will be a column vector with K rows.
我在嵌套总和、偏差节点和这个方程的一般复杂性方面遇到了问题。我也在苦苦挣扎,因为有 2 个权重矩阵,一个将输入连接到隐藏层,一个将隐藏层连接到输出。到目前为止,这是我的尝试。
定义变量
m = 100 %number of training examples
K = 2 %number of output nodes
E = 2 %number of input nodes
A = 2 %number of nodes in each hidden layer
L = 1 %number of hidden layers
Y = [2.2, 3.5 %targets for y1 and y2 (see picture at bottom of page)
1.7, 2.1
1.9, 3.6
. . %this is filled out in the actual code but to save space I have used ellipsis. there will be m rows.
. .
. .
2.8, 1.6]
X = [1.1, 1.8 %training inputs. there will be m rows
8.5, 1.0
9.5, 1.8
. .
. .
. .
1.4, 0.8]
W1 = [1.3, . . 0.4 %this is just an E by A matrix of random numbers. this is the matrix of initial weights.
. . . - 2
. . . 3.1
. . . - 1
2.1, -8, 1.2, 2.1]
W2 = [1.3, . . 0.4 %this is an A by K matrix of random numbers. this is the matrix of initial weights.
. . . - 2
. . . 3.1
. . . - 1
2.1, -8, 1.2, 2.1]
使用这些权重的假设等于...
Htheta = sigmf( dot(W2 , sigmf(dot(W1 , X))) ) %This will be a column vector with K rows.
使用这些权重的成本函数等于...(这是我苦苦挣扎的地方)
sum1 = 0
for i = 1:K
sum1 = sum1 + Y(k,i) *log(Htheta(k)) + (1 - Y(k,i))*log(1-Htheta(k))
我只是不停地写这样的东西,然后意识到这一切都错了。我一生都无法弄清楚如何进行嵌套求和,或者包括输入矩阵,或者做任何一个。这一切都非常复杂。
如何在 matlab 中创建这个方程?
非常感谢!
注意:代码有奇怪的颜色,因为 *** 不知道我在 MATLAB 中编程。我也把代码直接写到了***中,所以它可能有语法错误。我对我应该如何做这件事的一般想法更感兴趣,而不仅仅是复制和粘贴代码。这就是我不用分号之类的东西的原因。
【问题讨论】:
只是出于好奇,这是 Ng 的课程吗?如果是这样,请尝试将实现向量化而不是编写嵌套循环结构,它会变得更具可读性(和效率)。 是的,这是来自 Ng 的课程。不过,我在他的笔记或讲座中找不到矢量化版本。供参考,以下是讲义:holehouse.org/mlclass/09_Neural_Networks_Learning.html 【参考方案1】:好吧,据我了解,您的问题与神经网络无关,而是基本上询问如何在 matlab 中进行嵌套求和。我真的不想输入上面的整个等式,但是,即第一个总和的第一部分看起来像:
Jtheta = 0
for i=1:m,
for j=1:K,
Jtheta = Jtheta + Y(i, j) * log(Htheta(X(i))(j))
end
end
Jtheta
是您的结果。
【讨论】:
感谢您提供此答案,我想补充一点:我认为如果将其矢量化,效率会更高。具体来说,也许完全摆脱循环并改用矩阵运算? @user1274223 是的,那肯定会好得多,但是我对 Matlab 的知识只有初步的了解,所以不确定语法。您可以添加自己的答案,我很乐意投票。 我想我们在同一页面上,我有一段时间没有使用Matlab了,我一直在使用Octave,但一般的代码结构还是一样的。我还应该写一个答案吗? @user1274223 当然,如果你发现这对提问者会有帮助;) 我写了一个答案。我希望 OP 发现它至少有某种用途;)【参考方案2】:我认为Htheta
是一个 K*2 数组。请注意,您需要在前向成本函数计算中添加偏差(x0
和 a0
)。我向您展示了每个步骤中的数组维度,假设您在输入层、隐藏层和输出层有两个节点作为代码中的 cmets。
m = size(X, 1);
X = [ones(m,1) X]; % m*3 in your case
% W1 2*3, W2 3*2
a2 = sigmf(W1 * X'); % 2*m
a2 = [ones(m,1) a2']; % m*3
Htheta = sigmf(a2 * W2); % m*2
J = (1/m) * sum ( sum ( (-Y) .* log(Htheta) - (1-Y) .* log(1-Htheta) ));
t1 = W1(:,2:size(W1,2));
W2 = W2';
t2 = W2(:,2:size(W2,2));
% regularization formula
Reg = lambda * (sum( sum ( t1.^ 2 )) + sum( sum ( t2.^ 2 ))) / (2*m);
【讨论】:
感谢您的回答。矢量化版本比我使用循环的尝试要好得多。由于偏置单元的权重,我认为 W1 和 W2 是 2*3 和 3*2 矩阵?你为什么要做这段代码:X = [ones(m,1) X]
?这会创建一个 m x 1 的矩阵,X 不应该等于先前计算/收集的训练数据输入吗?
@Blue7 谢谢 Blue7。我认为 x1 和 x2 是您的输入,x0=1 是偏差,并且您总共有 m 个训练样本,所以我将 one(m,1) 添加到数组中。谢谢
@lennon310,这个答案很好,但是theta参数的正则化呢?
@user1274223 已添加。谢谢【参考方案3】:
我已经使用与您上面提到的相同的误差函数实现了神经网络。不幸的是,我已经有一段时间没有使用 Matlab 了,但是我对 Octave 相当精通,希望您仍然可以发现它有用,因为 Octave 中的许多功能与 Matlab 中的功能相似。
@sashkello 为计算成本函数提供了很好的 sn-p 代码。但是,这段代码是用循环结构编写的,我想提供一个矢量化的实现。
为了评估当前的 theta 值,我们需要在整个网络中执行前馈/forward propagation
。我假设您知道如何编写前馈代码,因为您只关心J(theta)
错误。让表示你的前向传播结果的向量为F
执行前馈后,您需要执行等式。请注意,我是以矢量化方式实现的。
J = (-1/m) * sum(sum(Y .* log(F) + (1-Y) .* log(1-F),2));
这将计算总和中涉及的部分:
现在我们必须添加正则化项,即:
通常情况下,我们会有任意数量的 theta 矩阵,但在这种情况下我们有 2 个,所以我们只需执行几个求和即可得到:
J =J + (lambda/(2*m)) * (sum(sum(theta_1(:,2:end).^2,2)) + sum(sum(theta_2(:,2:end).^2,2)));
请注意,在每个总和中,我只从第二列到其余列进行处理。这是因为第一列将对应于我们为“偏差单位”训练的theta
值。
所以有一个 J 计算的矢量化实现。
我希望这会有所帮助!
【讨论】:
这非常有用,非常感谢!是的,我知道如何计算前向传播。只是一个简单的问题:在 matlab 中,sum 命令将向量列中的所有数字相加,这是否与此 octave 代码中的相同,还是我需要不同的命令?此外,在第一个等式的内部总和中,您输入了: "sum(thing_to_sum , 2)" 。在 matlab 中,这将对向量的行求和。这也和八度一样吗?谢谢! 你好@Blue7 很高兴我的回答对你有帮助:) 是的,你是对的,如果 sum() 命令应用于矩阵,Octave 将按列求和。附加的 '2' 参数完全按照您指定的方式执行;它按行求和。我想在这方面是否包含 2 并没有太大区别,因为结果是相同的。感谢您指出这一点:) 要允许任意前馈神经网络架构(例如多个隐藏层),请参阅here。【参考方案4】:这适用于任意数量的隐藏层:
% Allow arbitrary network architectures. Create cell array of all Theta parameters
Theta=Theta1; Theta2;
% Compute unregularised cost (J)
J = 1/m * sum(sum((-y .* log(hX) - (1 - y) .* log(1 - hX))));
% Add regularisation
for i = 1:length(Theta)
J += lambda / 2 / m * sum(sum(Thetai(:,2:end) .^ 2));
end
【讨论】:
以上是关于MATLAB 中的神经网络成本函数的主要内容,如果未能解决你的问题,请参考以下文章