Java 梯度下降铰链损失最小化的正确实现

Java 梯度下降铰链损失最小化的正确实现,java,machine-learning,Java,Machine Learning,我复制了铰链损失函数(也是它所基于的LossC和LossFunc)。然后我将其包括在梯度下降算法中,如下所示: do { iteration++; error = 0.0; cost = 0.0; //loop through all instances (complete one epoch) for (p = 0; p < number_of_files__train; p++) { // 1. Calcula

我复制了铰链损失函数(也是它所基于的LossC和LossFunc)。然后我将其包括在梯度下降算法中,如下所示:

  do 
  {
    iteration++;
    error = 0.0;
    cost = 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
      //cost = hypothesis - outputs__train[p];
      cost = HingeLoss.loss(hypothesis, outputs__train[p]);
      System.out.println( "cost " + cost );

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

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

    }

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

  /* Root Mean Squared Error */
  //System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( error/number_of_files__train ) );
  System.out.println("Iteration " + iteration + " : RMSE = " + Math.sqrt( error/number_of_files__train ) );

  } 
  while( error != 0 );

您为gradient提供的代码看起来不像铰链损失的渐变。请看一个有效的公式,例如:

我不熟悉铰链损失函数,所以我会阅读它,但您能告诉我们一些您试图解决的问题吗?data.csv中有什么?您试图用梯度下降近似什么函数(您是否使用GD进行线性回归?逻辑回归?其他一些函数?)这可以帮助我们理解这里发生了什么。我正在尝试解决一个分类问题,作为输入,我有特征向量、单词包样式,即每个训练示例是所有文档(全球词典)中总单词的频率计数在特定文档中出现的单词的数量,以及出现的次数,基于从中学习到的权重,我想说一个文档是关于体育还是无神论的。类标签表示为{0,1}你想用什么函数来将一份文件归类为体育或无神论?我只是想澄清一下:我试图理解发生了什么。目前你的假设似乎是你权重的线性组合。对吗?我想梯度下降法可以训练权重,然后我对这些权重应用一个记录hts将为一种标签生成一个0,为另一种标签生成一个1,这就是你所说的线性组合吗?嗯,好的。我想我现在明白了。看起来你正在试图设计一个线性支持向量机,而不是实际使用支持向量机。你可以使用梯度下降法来训练线性支持向量机,但你的方法有点奇怪。首先,让我们来看看让我们尝试修复显而易见的问题:对于支持向量机(以及铰链损失函数)你的类必须是-1和1,而不是0和1。如果你将你的类编码为0和1,铰链损失函数将不起作用。我想梯度的计算和损失函数的计算是两个独立的部分,不是吗?我想损失函数将取代g中的
成本
radient calculation,我刚刚对我的原始帖子进行了编辑,以显示损失函数代码,该代码确实与您在那里发布的代码类似。您认为我刚才所说的正确吗?每个损失函数的导数/梯度不同。您需要实现铰链损失[您提供的代码中的损失]和有效梯度[使用你提供的代码中的deriv]。@lejlot:我在评论中慢慢达到了目的。马修:梯度下降的要点是它通过遵循梯度来优化函数。因此,为了优化铰链损失函数,你需要遵循梯度(导数)但是,为了让铰链损失在第一时间起作用,您需要对类进行不同的编码:如果没有这种编码,GD仍然无法做任何有用的事情。
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 cost, int number_of_files__train)
{
    double m = number_of_files__train;

    double[] gradient = new double[ globo_dict_size];//one for bias?

    for (int i = 0; i < gradient.length; i++) 
    {
        gradient[i] = (1.0/m) * cost * feature_matrix[ file_index ][ i ] ;
    }

    return gradient;
}
/**
 * Computes the HingeLoss loss
 *
 * @param pred the predicted value
 * @param y the target value
 * @return the HingeLoss loss
 */
public static double loss(double pred, double y)
{
    return Math.max(0, 1 - y * pred);
}

/**
 * Computes the first derivative of the HingeLoss loss
 *
 * @param pred the predicted value
 * @param y the target value
 * @return the first derivative of the HingeLoss loss
 */
public static double deriv(double pred, double y)
{
    if (pred * y > 1)
        return 0;
    else
        return -y;
}