java - 计算 Theta 更新规则的梯度输出

标签 java gradient-descent

因为它使用了 sigmoid 函数而不是零/一激活函数,所以我想这是计算梯度下降的正确方法,对吗?

  static double calculateOutput( int theta, double weights[], double[][] feature_matrix, int file_index, int globo_dict_size )
  {
     //double sum = x * weights[0] + y * weights[1] + z * weights[2] + weights[3];
     double sum = 0.0;

     for (int i = 0; i < globo_dict_size; i++) 
     {
         sum += ( weights[i] * feature_matrix[file_index][i] );
     }
     //bias
     sum += weights[ globo_dict_size ];

     return sigmoid(sum);
  }

  private static double sigmoid(double x)
  {
      return 1 / (1 + Math.exp(-x));
  }

我正在尝试更新我的 Θ 值的以下代码(相当于感知器中的权重,不是吗?),我得到了这个公式 LEARNING_RATE * localError * feature_matrix__train[p][i] * output_gradient[i] 在我的 related question 中用于此目的.我从我的感知器中注释掉了权重更新。

这个新的更新规则是正确的方法吗?

output_gradient 是什么意思?这是否等于我在 calculateOutput 方法中计算的总和?

      //LEARNING WEIGHTS
      double localError, globalError;
      int p, iteration, output;

      iteration = 0;
      do 
      {
          iteration++;
          globalError = 0;
          //loop through all instances (complete one epoch)
          for (p = 0; p < number_of_files__train; p++) 
          {
              // calculate predicted class
              output = calculateOutput( theta, weights, feature_matrix__train, p, globo_dict_size );
              // difference between predicted and actual class values
              localError = outputs__train[p] - output;
              //update weights and bias
              for (int i = 0; i < globo_dict_size; i++) 
              {
                  //weights[i] += ( LEARNING_RATE * localError * feature_matrix__train[p][i] );

                  weights[i] += LEARNING_RATE * localError * feature_matrix__train[p][i] * output_gradient[i]

              }
              weights[ globo_dict_size ] += ( LEARNING_RATE * localError );

              //summation of squared error (error value for all instances)
              globalError += (localError*localError);
          }

          /* Root Mean Squared Error */
          if (iteration < 10) 
              System.out.println("Iteration 0" + iteration + " : RMSE = " + Math.sqrt( globalError/number_of_files__train ) );
          else
              System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( globalError/number_of_files__train ) );
          //System.out.println( Arrays.toString( weights ) );
      } 
      while(globalError != 0 && iteration<=MAX_ITER);

更新 现在我更新了一些东西,看起来更像这样:

  double loss, cost, hypothesis, gradient;
  int p, iteration;

  iteration = 0;
  do 
  {
    iteration++;
    cost = 0.0;
    loss = 0.0;

    //loop through all instances (complete one epoch)
    for (p = 0; p < number_of_files__train; p++) 
    {

      // 1. Calculate the hypothesis h = X * theta
      hypothesis = calculateHypothesis( theta, feature_matrix__train, p, globo_dict_size );

      // 2. Calculate the loss = h - y and maybe the squared cost (loss^2)/2m
      loss = hypothesis - outputs__train[p];

      // 3. Calculate the gradient = X' * loss / m
      gradient = calculateGradent( theta, feature_matrix__train, p, globo_dict_size, loss );

      // 4. Update the parameters theta = theta - alpha * gradient
      for (int i = 0; i < globo_dict_size; i++) 
      {
          theta[i] = theta[i] - (LEARNING_RATE * gradient);
      }

    }

    //summation of squared error (error value for all instances)
    cost += (loss*loss);


  /* Root Mean Squared Error */
  if (iteration < 10) 
      System.out.println("Iteration 0" + iteration + " : RMSE = " + Math.sqrt( cost/number_of_files__train ) );
  else
      System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( cost/number_of_files__train ) );
  //System.out.println( Arrays.toString( weights ) );

  } 
  while(cost != 0 && iteration<=MAX_ITER);


}

static double calculateHypothesis( double theta[], double[][] feature_matrix, int file_index, int globo_dict_size )
{
    double hypothesis = 0.0;

     for (int i = 0; i < globo_dict_size; i++) 
     {
         hypothesis += ( theta[i] * feature_matrix[file_index][i] );
     }
     //bias
     hypothesis += theta[ globo_dict_size ];

     return hypothesis;
}

static double calculateGradent( double theta[], double[][] feature_matrix, int file_index, int globo_dict_size, double loss )
{
    double gradient = 0.0;

     for (int i = 0; i < globo_dict_size; i++) 
     {
         gradient += ( feature_matrix[file_index][i] * loss);
     }

     return gradient;
}

public static double hingeLoss()
{
    // l(y, f(x)) = max(0, 1 − y · f(x))

    return HINGE;
}

最佳答案

您的calculateOutput 方法看起来是正确的。你的下一段代码我真的不这么认为:

weights[i] += LEARNING_RATE * localError * feature_matrix__train[p][i] * output_gradient[i]

查看您在 other question 中发布的图片:

Update rules for Theta

让我们尝试在您的代码中识别这些规则的每个部分。

  1. Theta0 和Theta1:在您的代码中看起来像 weights[i];希望globo_dict_size = 2;

  2. alpha:似乎是您的LEARNING_RATE

  3. 1/m:我在你的更新规则中找不到这个。 m 是吴恩达视频中训练实例的数量。在你的情况下,我认为它应该是 1/number_of_files__train ;不过这不是很重要,即使没有它也应该能正常工作。

  4. 总和:您使用 calculateOutput 函数执行此操作,您在 localError 变量中使用其结果,您将其乘以 feature_matrix__train [p][i](相当于 Andrew Ng 的符号中的 x(i))。

    这部分是你的偏导数,也是梯度的一部分!

    为什么?因为 [h_theta(x(i)) - y(i)]^2 关于 Theta0 的偏导数等于:

    2*[h_theta(x(i)) - y(i)] * derivative[h_theta(x(i)) - y(i)]
    derivative[h_theta(x(i)) - y(i)] =
    derivative[Theta0 * x(i, 1) + Theta1*x(i, 2) - y(i)] =
    x(i, 1)
    

    当然,您应该推导出全部和。这也是吴恩达使用 1/(2m) 作为成本函数的原因,所以 2 会与我们从中得到的 2 抵消推导。

    请记住 x(i, 1) 或只是 x(1) 应该由所有的组成。在您的代码中,您应该确保:

    feature_matrix__train[p][0] == 1
    
  5. 就是这样!我不知道 output_gradient[i] 应该在您的代码中是什么,您没有在任何地方定义它。

我建议你看看this tutorial更好地了解您使用的算法。由于您使用了 sigmoid 函数,因此您似乎想要进行分类,但是您应该使用不同的成本函数。该文档也涉及逻辑回归。

关于java - 计算 Theta 更新规则的梯度输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28923292/

相关文章:

java - 变量可能尚未初始化错误

java - jersey-client 2.22.2 - 如何在 SslConfigurator 上正确设置 SunPKCS11 keystore ?

java.lang.IllegalArgumentException "Can not set DAO field"与 Spring 4 & Hibernate 4

python - 损失函数作为几个点的最小值,自定义损失函数和梯度

python - TensorFlow 2.0 GradientTape 返回 None 作为手动模型的梯度

python - 了解 PyTorch 中的累积梯度

java - 出现错误考虑在配置中定义类型为 'org.springframework.jdbc.core.JdbcTemplate' 的 bean

java - 适用于 Windows 7(x32) 的 Gdal

python - 理解Numpy中梯度下降算法的梯度

python - tensorflow 行为 : gradient computation across multi-GPU