// executes serial implementation of stochastic gradient descent for // logistic regression with a fixed number of iterations // config_params: {step_size, characteristic_time} void trainStochasticGradientDescent( DataSet training_set, TrainingOptions training_options) { // shuffle datapoints in order to add more stochasticity // shuffleKeyValue(training_set.data_points, training_set.labels, // training_set.num_data_points, training_set.num_features); FeatureType* gradient = new FeatureType[training_set.num_features]; // read configuration parameters double step_size = *training_options.step_size; const double characteristic_time = (fieldExists(training_options.config_params, "characteristic_time")) ? training_options.config_params["characteristic_time"] : CHARACTERISTIC_TIME; size_t curr_num_epochs = (fieldExists(training_options.config_params, "curr_num_epochs")) ? training_options.config_params["curr_num_epochs"] : 0; double annealed_step_size = step_size; for (size_t k = 0; k < training_options.num_epochs; k++) { // simulated annealing (reduces step size as it converges) annealed_step_size = training_options.config_params["initial_step_size"] / (1.0 + (curr_num_epochs * training_set.num_data_points / characteristic_time)); curr_num_epochs++; for (size_t i = 0; i < training_set.num_data_points; i++) { // computes gradient gradientForSinglePoint( training_set.parameter_vector, &training_set.data_points[i * training_set.num_features], training_set.labels[i], training_set.num_features, gradient); // updates parameter vector updateParameters( training_set.parameter_vector, gradient, training_set.num_features, annealed_step_size); } } *training_options.step_size = annealed_step_size; delete[] gradient; }
static void joinerValidateFields(struct joiner *joiner, struct hash *fieldHash, char *oneIdentifier) /* Make sure that joiner refers to fields that exist at * least somewhere. */ { struct joinerSet *js; struct joinerField *jf; for (js=joiner->jsList; js != NULL; js = js->next) { if (oneIdentifier == NULL || wildMatch(oneIdentifier, js->name)) { for (jf = js->fieldList; jf != NULL; jf = jf->next) { if (!fieldExists(fieldHash, js, jf)) { if (!js->expanded) { fprintf(stderr, "Error: "); printField(jf, stderr); fprintf(stderr, " not found in %s line %d of %s\n", js->name, jf->lineIx, joiner->fileName); } } } } } }
void nextMove(ucontext_t *my_context, ucontext_t *caller_context, int player_id, struct field *old_field, struct field *current_field, char *current_move, int *current_rating) { int cx = 0; int cy = 0; for(cy = 0; cy <= 7; cy++) { for(cx = 0; cx <= 7; cx++) { int cf = fieldValue(old_field, cx, cy); int dx, dy, lx, ly; // cx = current x, cy = current y if((cf == 5 && player_id == 1) || (cf == 3 && player_id == 2)) { // Stein, correct player // dx = destination x, dy = destination y dx = fieldAheadLeftX(cx); dy = fieldAheadLeftY(cy); yieldMoveMoveIfPossible(); dx = fieldAheadRightX(cx); dy = fieldAheadRightY(cy); yieldMoveMoveIfPossible(); // dx = opponent x, dy = opponent y, lx = destination x, ly = destination y dx = fieldAheadLeftX(cx); dy = fieldAheadLeftY(cy); lx = fieldAheadLeftX(dx); ly = fieldAheadLeftY(dy); yieldKillMoveIfPossible(); dx = fieldAheadRightX(cx); dy = fieldAheadRightY(cy); lx = fieldAheadRightX(dx); ly = fieldAheadRightY(dy); yieldKillMoveIfPossible(); dx = fieldBackLeftX(cx); dy = fieldBackLeftY(cy); lx = fieldBackLeftX(dx); ly = fieldBackLeftY(dy); yieldKillMoveIfPossible(); dx = fieldBackRightX(cx); dy = fieldBackRightY(cy); lx = fieldBackRightX(dx); ly = fieldBackRightY(dy); yieldKillMoveIfPossible(); } else if((cf == 9 && player_id == 1) || (cf == 7 && player_id == 2)) { // Dame, correct player int i = 0, j = 0; for(j = 0; j < 2; j++) { for(i = -8; i <= 8; i++) { if(j == 1) { dx = cx + i; dy = cy - i; } else { dx = cx - i; dy = cy - i; } if(!fieldExists(dx, dy) || !fieldIsEmpty(old_field, dx, dy)) { continue; } // dx = destination x, dy = destination y if(straightLineIsFree(old_field, cx, cy, dx, dy)) { yieldMoveMoveIfPossible(); } else { lx = dx; ly = dy; // dx = opponent x, dy = opponent y, lx = destination x, ly = destination y if(straightLineHasOnlyOneOpponent(old_field, player_id, cx, cy, lx, ly, &dx, &dy)) { yieldKillMoveIfPossible(); } } } } } } } }
// executes serial implementation of stochastic gradient descent for // softmax regression until convergence or for a fixed number of epochs void trainBatchGradientDescent( DataSet training_set, TrainingOptions training_options) { // read configuration parameters double step_size = *training_options.step_size; double initial_step_size = step_size; const double tolerance = (fieldExists(training_options.config_params, "tolerance")) ? training_options.config_params["tolerance"] : TOLERANCE; FeatureType* gradient = new FeatureType[training_set.num_features * LABEL_CLASS]; // initial loss // double current_loss; // double initial_step_size = step_size; for (size_t epoch = 0; epoch < training_options.num_epochs; epoch++) { // compute gradient and update parameters softmaxGradientForWholeBatch(training_set, gradient); softmaxBoldDriver(training_set, gradient, &step_size); // anneal(epoch, initial_step_size, &step_size, training_set, gradient); // updateParameters(training_set.parameter_vector, // gradient, // training_set.num_features, // initial_step_size); // stop iterating if the gradient is close to zero if (norm2(gradient, training_set.num_features * LABEL_CLASS) < tolerance) break; } *training_options.step_size = step_size; delete[] gradient; }