Machine learning 用神经网络实现连续回归中的梯度

Machine learning 用神经网络实现连续回归中的梯度,machine-learning,neural-network,gradient,regression,Machine Learning,Neural Network,Gradient,Regression,我正在尝试实现一个回归NN,它有3层(1个输入层、1个隐藏层和1个输出层,结果是连续的)。作为基础,我从类中提取了分类NN,但更改了成本函数和梯度计算,以适应回归问题(而不是分类问题): 我现在的功能是: function [J grad] = nnCostFunctionLinear(nn_params, ... input_layer_size, ...

我正在尝试实现一个回归NN,它有3层(1个输入层、1个隐藏层和1个输出层,结果是连续的)。作为基础,我从类中提取了分类NN,但更改了成本函数和梯度计算,以适应回归问题(而不是分类问题):

我现在的功能是:

function [J grad] = nnCostFunctionLinear(nn_params, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, ...
                                   X, y, lambda)

Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
                 hidden_layer_size, (input_layer_size + 1));

Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
                 num_labels, (hidden_layer_size + 1));

m = size(X, 1);

a1 = X;
a1 = [ones(m, 1) a1];
a2 = a1 * Theta1';
a2 = [ones(m, 1) a2];
a3 = a2 * Theta2';
Y = y;

J = 1/(2*m)*sum(sum((a3 - Y).^2))

th1 = Theta1;
th1(:,1) = 0; %set bias = 0 in reg. formula
th2 = Theta2;
th2(:,1) = 0;

t1 = th1.^2;
t2 = th2.^2;
th = sum(sum(t1)) + sum(sum(t2));
th = lambda * th / (2*m);
J = J + th; %regularization


del_3 = a3 - Y;
t1 = del_3'*a2;
Theta2_grad = 2*(t1)/m + lambda*th2/m;

t1 = del_3 * Theta2;
del_2 = t1 .*  a2;
del_2 = del_2(:,2:end);
t1 = del_2'*a1;
Theta1_grad = 2*(t1)/m + lambda*th1/m;

grad = [Theta1_grad(:) ; Theta2_grad(:)];
end
然后我在fmincg算法中使用这个函数,但在第一次迭代中,fmincg结束了它的工作。我认为我的梯度是错误的,但我找不到错误


有人能帮忙吗?

如果我理解正确,您的第一块代码(如下所示)——

是在输出层获得输出a(3)

Ng关于NN的幻灯片具有以下配置,用于计算a(3)。它与您的代码呈现的内容不同

  • 在中间/输出层,您没有执行激活功能
    g
    ,例如
    sigmoid
    功能

对于无正则化项的成本函数
J
,Ng的幻灯片具有以下公式:

我不明白为什么您可以使用以下公式计算:

J = 1/(2*m)*sum(sum((a3 - Y).^2))

因为您根本不包括
log
函数

Mikhaill,我也一直在使用神经网络进行连续回归,在某些时候也遇到了类似的问题。在这里最好的做法是在运行模型之前,根据数值计算测试梯度计算。如果这不正确,fmincg将无法训练模型。(顺便说一句,我不鼓励你使用数值梯度,因为所涉及的时间要大得多)

考虑到您从Ng的Coursera课程中获得了这个想法,我将为您实现一个可能的解决方案,尝试使用相同的八度符号

    % Cost function without regularization.
    J = 1/2/m^2*sum((a3-Y).^2); 

    % In case it´s needed, regularization term is added (i.e. for Training).
    if (reg==true);
 J=J+lambda/2/m*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2)));
    endif;

    % Derivatives are computed for layer 2 and 3.
    d3=(a3.-Y);
    d2=d3*Theta2(:,2:end);

    % Theta grad is computed without regularization.
    Theta1_grad=(d2'*a1)./m;
    Theta2_grad=(d3'*a2)./m;

    % Regularization is added to grad computation.
    Theta1_grad(:,2:end)=Theta1_grad(:,2:end)+(lambda/m).*Theta1(:,2:end);
    Theta2_grad(:,2:end)=Theta2_grad(:,2:end)+(lambda/m).*Theta2(:,2:end);

    % Unroll gradients.
    grad = [Theta1_grad(:) ; Theta2_grad(:)];
请注意,由于您已经去掉了所有的sigmoid激活,因此导数计算非常简单,并简化了原始代码

下一步: 1.检查此代码以了解它对您的问题是否有意义。 2.使用渐变检查测试渐变计算。
3.最后,使用fmincg并检查是否得到不同的结果。

尝试使用sigmoid函数来计算第二层(隐藏层)值,并在计算目标(输出)值时避免使用sigmoid


在将输入传递给NNCOST函数之前,对输入进行规范化。

根据第5周的《线性系统NN课堂讲稿指南》,您应在初始代码中进行以下更改:

  • 移除num_标签或将其设为1(也可在重塑()中)
  • 无需将y转换为逻辑矩阵
  • 对于a2-将sigmoid()函数替换为tanh()
  • d2计算中-将乙状结肠半径(z2)替换为(1-tanh(z2)。^2)
  • 从输出层移除sigmoid(a3=z3
  • 将未规范化部分中的成本函数替换为线性函数:J=(1/(2*m))*sum((a3-y)。^2
  • 创建predictLinear():使用predict()函数作为基础,第一层假设用tanh()替换sigmoid,第二层假设删除第二个sigmoid,使用max()函数删除行,使用隐藏层假设的输出作为预测结果
  • 在课堂讲稿中的测试用例上验证您的nnCostFunctionLinear()

  • log()和sigmoid()-逻辑回归NN的方法。在coursera的例子中,这是癌症检测,但我想预测房屋成本Hi Mikhail,这是一个一年多前的问题,但我想知道你是否已经解决了这个问题?实际上,另一个人问了同样的问题,我在那里提供了我的代码,与Andrew Ng的checkNNGradients(lambda)相比,得到了1e-4的相对差异:如果你已经解决了这个问题,得到的相对差异更小,请通过回答你自己的问题来更新;否则,希望我的代码有帮助。谢谢那是什么语言??这不是octave/matlab(吴教授在..中教授的内容)@javadba,这是octave
        % Cost function without regularization.
        J = 1/2/m^2*sum((a3-Y).^2); 
    
        % In case it´s needed, regularization term is added (i.e. for Training).
        if (reg==true);
     J=J+lambda/2/m*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2)));
        endif;
    
        % Derivatives are computed for layer 2 and 3.
        d3=(a3.-Y);
        d2=d3*Theta2(:,2:end);
    
        % Theta grad is computed without regularization.
        Theta1_grad=(d2'*a1)./m;
        Theta2_grad=(d3'*a2)./m;
    
        % Regularization is added to grad computation.
        Theta1_grad(:,2:end)=Theta1_grad(:,2:end)+(lambda/m).*Theta1(:,2:end);
        Theta2_grad(:,2:end)=Theta2_grad(:,2:end)+(lambda/m).*Theta2(:,2:end);
    
        % Unroll gradients.
        grad = [Theta1_grad(:) ; Theta2_grad(:)];
    
    function [J grad] = nnCostFunction1(nnParams, ...
                                       inputLayerSize, ...
                                       hiddenLayerSize, ...
                                       numLabels, ...
                                       X, y, lambda)
    
    Theta1 = reshape(nnParams(1:hiddenLayerSize * (inputLayerSize + 1)), ...
                     hiddenLayerSize, (inputLayerSize + 1));
    
    Theta2 = reshape(nnParams((1 + (hiddenLayerSize * (inputLayerSize + 1))):end), ...
                     numLabels, (hiddenLayerSize + 1));
    
    Theta1Grad = zeros(size(Theta1));
    Theta2Grad = zeros(size(Theta2));
    
    m = size(X,1);
    
    a1 = [ones(m, 1) X]';
    z2 = Theta1 * a1;
    a2 = sigmoid(z2);
    a2 = [ones(1, m); a2];
    z3 = Theta2 * a2;
    a3 = z3;
    
    Y = y';
    
    r1 = lambda / (2 * m) * sum(sum(Theta1(:, 2:end) .* Theta1(:, 2:end)));
    r2 = lambda / (2 * m) * sum(sum(Theta2(:, 2:end) .* Theta2(:, 2:end)));
    
    J = 1 / ( 2 * m ) * (a3 - Y) * (a3 - Y)' + r1 + r2;
    
    delta3 = a3 - Y;
    delta2 = (Theta2' * delta3) .* sigmoidGradient([ones(1, m); z2]);
    delta2 = delta2(2:end, :);
    
    Theta2Grad = 1 / m * (delta3 * a2');
    Theta2Grad(:, 2:end) = Theta2Grad(:, 2:end) + lambda / m * Theta2(:, 2:end);
    Theta1Grad = 1 / m * (delta2 * a1');
    Theta1Grad(:, 2:end) = Theta1Grad(:, 2:end) + lambda / m * Theta1(:, 2:end);
    
    grad = [Theta1Grad(:) ; Theta2Grad(:)];
    
    end