package org.ea.javacnn.trainers;
import org.ea.javacnn.JavaCNN;
import org.ea.javacnn.data.BackPropResult;
import org.ea.javacnn.data.DataBlock;
import org.ea.javacnn.data.TrainResult;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Trainers take the generated output of activations and gradients in
* order to modify the weights in the network to make a better prediction
* the next time the network runs with a data block.
*
* @author Daniel Persson (mailto.woden@gmail.com)
*/
public abstract class Trainer {
private JavaCNN net;
protected double learning_rate, l1_decay, l2_decay;
protected int batch_size, k;
protected double momentum, eps;
protected List gsum, xsum;
public Trainer(JavaCNN net, int batch_size, float l2_decay) {
this.net = net;
this.learning_rate = 0.01;
this.l1_decay = 0.001;
this.l2_decay = l2_decay;
this.batch_size = batch_size;
this.momentum = 0.9;
this.eps = 1e-8;
gsum = new ArrayList();
xsum = new ArrayList();
this.k = 0; // iteration counter
}
public TrainResult train(DataBlock x, int y) {
this.net.forward(x, true); // also set the flag that lets the net know we're just training
double cost_loss = this.net.backward(y);
double l2_decay_loss = 0.0;
double l1_decay_loss = 0.0;
this.k++;
if(this.k % this.batch_size == 0) {
List pglist = this.net.getBackPropagationResult();
// initialize lists for accumulators. Will only be done once on first iteration
if(this.gsum.size() == 0 && this.momentum > 0.0) {
for(int i=0;i 0 ? 1 : -1);
double l2grad = l2_decay * (p[j]);
double gij = (l2grad + l1grad + g[j]) / this.batch_size; // raw batch gradient
update(i, j, gij, p);
g[j] = 0.0; // zero out gradient so that we can begin accumulating anew
}
}
}
// appending softmax_loss for backwards compatibility, but from now on we will always use cost_loss
// in future, TODO: have to completely redo the way loss is done around the network as currently
// loss is a bit of a hack. Ideally, user should specify arbitrary number of loss functions on any layer
// and it should all be computed correctly and automatically.
return new TrainResult(0, 0, l1_decay_loss, l2_decay_loss, cost_loss, cost_loss, cost_loss + l1_decay_loss + l2_decay_loss);
}
public abstract void update(int i, int j, double gij, double[] p);
public void initTrainData(BackPropResult bpr) {};
}
Ads help maintain this website.