为什么这段代码中的 "theta" 是 NaN?
Why "theta" in this code is NaN?
我正在为我的研究项目在 MATLAB 中学习神经网络(线性回归),这是我使用的代码的一部分。
问题是 "theta" 的值是 NaN ,我不知道为什么。
你能告诉我错误在哪里吗?
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
theta = zeros(2, 1); % initialize fitting parameters
%GRADIENTDESCENT Performs gradient descent to learn theta
% theta = GRADIENTDESCENT(X, y, theta, alpha, num_iters) updates theta by
% taking num_iters gradient steps with learning rate alpha
% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
theta = theta - ((alpha/m)*((X*theta)-y)' * X)';
end
end
% run gradient descent
theta = gradientDescent(X, y, theta, alpha, iterations);
你的功能没问题。但是 X
和 theta
的大小不兼容。一般来说,如果size(X)
是[N, M]
,那么size(theta)
应该是[M, 1]
。
所以我建议更换行
theta = zeros(2, 1);
与
theta = zeros(size(X, 2), 1);
的列数应与 theta
的元素数相同。所以在这个例子中,size(X)
应该是 [133, 2]
.
此外,您应该在调用该函数之前移动该初始化。
例如,如果从函数中删除theta
的初始化,下面的代码不会returnNaN
。
X = rand(133, 1); % or rand(133, 2)
y = rand(133, 1);
theta = zeros(size(X, 2), 1); % initialize fitting parameters
% run gradient descent
theta = gradientDescent(X, y, theta, 0.1, 1500)
编辑:这是对以下评论的回应。
你的问题是梯度下降算法不收敛。自己看,绘制 J_history
,如果算法稳定,它应该永远不会增加。您可以通过在函数 gradientDescent
的 for-loop 中插入以下行来计算 J_history
:
J_history(iter) = mean((X * theta - y).^2);
在您的情况下(即给定数据文件和 alpha = 0.01
),J_history
呈指数增长。如下图所示。请注意 y-axis 是对数刻度。
这是梯度下降不稳定的明显迹象。
有两种方法可以消除这个问题。
选项 1. 使用较小的 alpha
。 alpha
控制梯度下降率。如果太大,算法不稳定。如果太小,算法需要很长时间才能达到最优解。尝试像 alpha = 1e-8
这样的东西,然后从那里开始。例如,alpha = 1e-8
导致以下成本函数:
选项 2. 使用特征缩放 来降低输入量级。执行此操作的一种方法称为 Standarization。以下是使用标准化和生成的成本函数的示例:
data=xlsread('v & t.xlsx');
data(:,1) = (data(:,1)-mean(data(:,1)))/std(data(:,1));
我正在为我的研究项目在 MATLAB 中学习神经网络(线性回归),这是我使用的代码的一部分。 问题是 "theta" 的值是 NaN ,我不知道为什么。 你能告诉我错误在哪里吗?
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
theta = zeros(2, 1); % initialize fitting parameters
%GRADIENTDESCENT Performs gradient descent to learn theta
% theta = GRADIENTDESCENT(X, y, theta, alpha, num_iters) updates theta by
% taking num_iters gradient steps with learning rate alpha
% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
theta = theta - ((alpha/m)*((X*theta)-y)' * X)';
end
end
% run gradient descent
theta = gradientDescent(X, y, theta, alpha, iterations);
你的功能没问题。但是 X
和 theta
的大小不兼容。一般来说,如果size(X)
是[N, M]
,那么size(theta)
应该是[M, 1]
。
所以我建议更换行
theta = zeros(2, 1);
与
theta = zeros(size(X, 2), 1);
的列数应与 theta
的元素数相同。所以在这个例子中,size(X)
应该是 [133, 2]
.
此外,您应该在调用该函数之前移动该初始化。
例如,如果从函数中删除theta
的初始化,下面的代码不会returnNaN
。
X = rand(133, 1); % or rand(133, 2)
y = rand(133, 1);
theta = zeros(size(X, 2), 1); % initialize fitting parameters
% run gradient descent
theta = gradientDescent(X, y, theta, 0.1, 1500)
编辑:这是对以下评论的回应。
你的问题是梯度下降算法不收敛。自己看,绘制 J_history
,如果算法稳定,它应该永远不会增加。您可以通过在函数 gradientDescent
的 for-loop 中插入以下行来计算 J_history
:
J_history(iter) = mean((X * theta - y).^2);
在您的情况下(即给定数据文件和 alpha = 0.01
),J_history
呈指数增长。如下图所示。请注意 y-axis 是对数刻度。
这是梯度下降不稳定的明显迹象。
有两种方法可以消除这个问题。
选项 1. 使用较小的 alpha
。 alpha
控制梯度下降率。如果太大,算法不稳定。如果太小,算法需要很长时间才能达到最优解。尝试像 alpha = 1e-8
这样的东西,然后从那里开始。例如,alpha = 1e-8
导致以下成本函数:
选项 2. 使用特征缩放 来降低输入量级。执行此操作的一种方法称为 Standarization。以下是使用标准化和生成的成本函数的示例:
data=xlsread('v & t.xlsx');
data(:,1) = (data(:,1)-mean(data(:,1)))/std(data(:,1));