private void sgdTrain ( ClassificationDataSet D , MatrixOfVecs W , Vec b , int sign_mul , boolean parallel ) { IntList order = new IntList ( D . size ( ) ) ; ListUtils . addRange ( order , 0 , D . size ( ) , 1 ) ; final double lambda_adj = lambda / ( D . size ( ) * epochs ) ; int [ ] owned = new int [ K ] ; //how many points does thsi guy own? int assigned_positive_instances = 0 ; //how many points in the positive class have been assigned? int [ ] assignments = new int [ D . size ( ) ] ; //who owns each data point Arrays . fill ( assignments , - 1 ) ; //Starts out that no one is assigned! Vec dots = new DenseVector ( W . rows ( ) ) ; long t = 0 ; for ( int epoch = 0 ; epoch < epochs ; epoch ++ ) { Collections . shuffle ( order ) ; for ( int i : order ) { t ++ ; double eta = 1 / ( lambda_adj * t ) ; Vec x_i = D . getDataPoint ( i ) . getNumericalValues ( ) ; int y_i = ( D . getDataPointCategory ( i ) * 2 - 1 ) * sign_mul ; //this sets dots = bias, which we then add to with matrix-vector product //result is the same as dots = W x_i + b b . copyTo ( dots ) ; W . multiply ( x_i , 1.0 , dots ) ; if ( y_i == - 1 ) { for ( int k = 0 ; k < K ; k ++ ) if ( dots . get ( k ) > - 1 ) { W . getRowView ( k ) . mutableSubtract ( eta , x_i ) ; b . increment ( k , - eta ) ; } } else //y_i == 1 { int k_true_max = 0 ; for ( int k = 1 ; k < dots . length ( ) ; k ++ ) if ( dots . get ( k ) > dots . get ( k_true_max ) ) k_true_max = k ; if ( dots . get ( k_true_max ) < 1 ) { int z = ASSIGN ( dots , i , k_true_max , owned , assignments , assigned_positive_instances ) ; W . getRowView ( z ) . mutableAdd ( eta , x_i ) ; b . increment ( z , eta ) ; //book keeping if ( assignments [ i ] < 0 ) //first assignment, inc counter assigned_positive_instances ++ ; else //change owner, decrement ownership count owned [ assignments [ i ] ] -- ; owned [ z ] ++ ; assignments [ i ] = z ; } } // W.mutableMultiply(1-eta*lambda); //equivalent form, more stable W . mutableMultiply ( 1 - 1.0 / t ) ; b . mutableMultiply ( 1 - 1.0 / t ) ; } } }
Training procedure that can be applied to each version of the CPM sub - problem .