这更像是一个Matlab编程问题,而不是一个数学问题。
我想在不同的学习率下运行梯度下降倍数。我有一套学习率
alpha = [0.3, 0.1, 0.03, 0.01, 0.003, 0.001];
每次我运行渐变下降时,我得到一个向量J_vals
作为输出。但是,我不熟悉Matlab,除了做类似的事情之外,还知道如何实现这个:
[theta, J_vals] = gradientDescent(...., alpha(1),...);
J1 = J_vals;
[theta, J_vals] = gradientDescent(...., alpha(2),...);
J2 = J_vals;
等等。
我考虑使用for循环,但后来我不知道如何处理J_vals
(不知道如何将for循环应用于J1
,{{1 }}, 等等)。也许它看起来像这样:
J2
然后我会有一个矢量矢量。
在Python中,我只是运行for循环并将每个新结果追加到列表的末尾。我如何在Matlab中实现这样的东西?还是有更有效的方式?
答案 0 :(得分:3)
如果你知道你将要有多少循环和J_vals
的大小(或者至少是一个合理的上限),我建议预先分配容器数组的大小
J = zeros(n,1);
然后在每个循环上插入新值
J(start:start+n) = J_vals
这样你就不会重新分配记忆。如果您不知道,可以将值附加到数组中。例如,
J = []; % initialize
for i = len(alpha)
[theta, J_vals] = gradientDescent(..., alpha(i),...);
J = [J; J_vals]; % Append column row
end
但这是每次循环重新分配数组的大小。如果它不是太多循环那么它应该没问题。
答案 1 :(得分:2)
只要为行下标添加:
(假设J_vals
是列向量),您的解决方案就可以正常工作了:
for i = len(alpha)
[theta, J_vals] = gradientDescent(..., alpha(i),...);
J(:, i) = J_vals;
%// ^... all rows, column 'i'
end
您甚至可以将其作为返回值:
for i = len(alpha)
[theta, J(:, i)] = gradientDescent(..., alpha(i),...);
%// ^... add returned value directly to our list
end
这两种方法都允许您预先分配矩阵以获得潜在的速度增益。
如果您想要随时构建列表,可以使用@ dpmcmlxxvi的答案中的方法,或者您可以使用特殊的下标end
。但是,这些方法都不与预分配兼容。
for i = len(alpha)
[theta, J(:, end+1)] = gradientDescent(..., alpha(i),...);
%// ^... add new vector after the current end of list
end
我还建议你不要在Matlab中使用i
作为变量名。我知道它对其他语言来说很自然,但在Matlab中它会覆盖内置的虚数常量i
。
请参阅:https://stackoverflow.com/a/14790765/1377097
答案 2 :(得分:1)
Matlab的"cell arrays"有点像Python中的列表。它们的相似之处在于您可以将变量数据类型放入其中。似乎没有人太确定,但most likely the cell array is implemented as an array of object pointers.这意味着追加它(cell_array{length(cell_array) + 1} = new_data
)仍然有些昂贵,但至少你只是附加一个指针而不是整个列。之后,您仍然需要使用cell2mat将单元格数组转换为普通矩阵。
最惯用的Matlab解决方案是预先分配(建议使用@dpmcmlxxvi)。
我认为你所描述的是一个非常常见的用例,不幸的是Matlab需要这样一个冗长的习惯用法。同样令人沮丧的是,文档对于如何实现单元阵列是不透明的,以及附加到单元阵列是否昂贵。