Training procedure that can be applied to each version of the CPM sub-problem. @param D the dataset to train on @param W the weight matrix of vectors to use @param b a vector that stores the associated bias terms for each weigh vector. @param sign_mul Either positive or negative 1. Controls whether
(ClassificationDataSet D, MatrixOfVecs W, Vec b, int sign_mul, ExecutorService ex)
| 423 | * the positive or negative class is to be enveloped by the polytype |
| 424 | */ |
| 425 | private void sgdTrain(ClassificationDataSet D, MatrixOfVecs W, Vec b, int sign_mul, ExecutorService ex) |
| 426 | { |
| 427 | IntList order = new IntList(D.getSampleSize()); |
| 428 | ListUtils.addRange(order, 0, D.getSampleSize(), 1); |
| 429 | |
| 430 | final double lambda_adj = lambda/(D.getSampleSize()*epochs); |
| 431 | |
| 432 | int[] owned = new int[K];//how many points does thsi guy own? |
| 433 | int assigned_positive_instances = 0;//how many points in the positive class have been assigned? |
| 434 | int[] assignments = new int[D.getSampleSize()];//who owns each data point |
| 435 | Arrays.fill(assignments, -1);//Starts out that no one is assigned! |
| 436 | |
| 437 | Vec dots = new DenseVector(W.rows()); |
| 438 | |
| 439 | long t = 0; |
| 440 | for(int epoch = 0; epoch < epochs; epoch++) |
| 441 | { |
| 442 | Collections.shuffle(order); |
| 443 | for(int i : order) |
| 444 | { |
| 445 | t++; |
| 446 | double eta = 1/(lambda_adj*t); |
| 447 | Vec x_i = D.getDataPoint(i).getNumericalValues(); |
| 448 | int y_i = (D.getDataPointCategory(i)*2-1)*sign_mul; |
| 449 | |
| 450 | //this sets dots = bias, which we then add to with matrix-vector product |
| 451 | //result is the same as dots = W x_i + b |
| 452 | b.copyTo(dots); |
| 453 | W.multiply(x_i, 1.0, dots); |
| 454 | |
| 455 | if(y_i == -1) |
| 456 | { |
| 457 | for(int k = 0; k < K; k++) |
| 458 | if(dots.get(k) > -1) |
| 459 | { |
| 460 | W.getRowView(k).mutableSubtract(eta, x_i); |
| 461 | b.increment(k, -eta); |
| 462 | } |
| 463 | } |
| 464 | else//y_i == 1 |
| 465 | { |
| 466 | int k_true_max = 0; |
| 467 | for(int k = 1; k < dots.length(); k++) |
| 468 | if(dots.get(k) > dots.get(k_true_max)) |
| 469 | k_true_max = k; |
| 470 | |
| 471 | if(dots.get(k_true_max) < 1) |
| 472 | { |
| 473 | int z = ASSIGN(dots, i, k_true_max, owned, assignments, assigned_positive_instances); |
| 474 | W.getRowView(z).mutableAdd(eta, x_i); |
| 475 | b.increment(z, eta); |
| 476 | |
| 477 | //book keeping |
| 478 | if(assignments[i] < 0)//first assignment, inc counter |
| 479 | assigned_positive_instances++; |
| 480 | else//change owner, decrement ownership count |
| 481 | owned[assignments[i]]--; |
| 482 | owned[z]++; |
no test coverage detected