所以在我的头撞墙几个小时之后,我在网上寻找解决问题的方法,并且效果很好。我只是想知道是什么原因导致了我最初的问题。
这里有一些更多的细节。输入是来自MNIST数据集的20x20px图像,有5000个样本,因此X或A1为5000x400。单个隐藏层中有25个节点。输出是一个0-9位的热矢量。 y
(不是Y,这是y的一个热编码)是5000x1向量,值为1-10。
这是我的成本函数的原始代码:
Y = zeros(m, num_labels);
for i = 1:m
Y(i, y(i)) = 1;
endfor
H = sigmoid(Theta2*[ones(1,m);sigmoid(Theta1*[ones(m, 1) X]'))
J = (1/m) * sum(sum((-Y*log(H]))' - (1-Y)*log(1-H]))')))
但后来我发现了这个:
A1 = [ones(m, 1) X];
Z2 = A1 * Theta1';
A2 = [ones(size(Z2, 1), 1) sigmoid(Z2)];
Z3 = A2*Theta2';
H = A3 = sigmoid(Z3);
J = (1/m)*sum(sum((-Y).*log(H) - (1-Y).*log(1-H), 2));
我看到这可能会稍微清洁,但是在功能上导致我的原始代码获得304.88
而另一个获得~0.25
?这是元素明智的乘法吗?
仅供参考,如果您需要写出正式的等式,这与this question的问题相同。
感谢您的帮助!我真的很想知道我哪里出错了
转移评论:
快速浏览一下,在J = (1/m) * sum(sum((-Y*log(H]))' - (1-Y)*log(1-H]))')))
中,括号中有一些东西,但可能是你在这里粘贴它的方式,而不是原始代码,因为这会在你运行时抛出错误。如果我理解正确且Y,H是矩阵,那么在你的第一个版本中Y*log(H)
是矩阵乘法,而在第二个版本中Y.*log(H)
是一个逐项乘法(不是矩阵乘法,只是c(i,j)=a(i,j)*b(i,j)
)。
更新1:
关于你在评论中的问题。从第一个屏幕截图中,您可以在Y矩阵的条目Y(i,k)
中表示每个值yk(i),并将每个值h(x ^(i))k表示为H(i,k)
。所以基本上,对于每个i,你想要计算Y(i,k) log(H(i,k)) + (1-Y(i,k)) log(1-H(i,k))
。您可以将所有值一起执行并将结果存储在矩阵C中。然后C = Y.*log(H) + (1-Y).*log(1-H)
和每个C(i,k)具有上述值。这是一个.*
操作,因为你想对每个矩阵的每个元素(i,k)进行操作(与multiplying the matrices完全不同)。然后,为了得到二维维矩阵C中所有值的总和,你使用八度函数sum
两次:sum(sum(C))
将列和行两者相加(或者作为@Insreducible建议,只是sum(C(:))
)。
请注意,也可能存在其他错误。