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 数组。请注意,您需要在前向成本函数计算中添加偏差(x0a0)。我向您展示了每个步骤中的数组维度,假设您在输入层、隐藏层和输出层有两个节点作为代码中的 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 中的神经网络成本函数的主要内容,如果未能解决你的问题,请参考以下文章

matlab中的BP神经网络

Matlab的BP神经网络工具箱及其在函数逼近中的应用

[人工神经网络]Matlab中的激活函数及导函数形式

bp神经网络算法 在matlab中的实现

bp神经网络matlab实现时,newff函数中的网络各层神经元的激活函数怎么选啊?

MATLAB中一些函数,用于神经网络