Blame simple/neural/nn-trainer3.cpp

Ivan Mahonin 53488e
Ivan Mahonin 53488e
#include <ctime>
Ivan Mahonin 53488e
#include <cstdlib>
Ivan Mahonin 53488e
Ivan Mahonin 53488e
#include <chrono>
Ivan Mahonin 53488e
Ivan Mahonin 53488e
#include "nnlayer3.inc.cpp"
Ivan Mahonin 53488e
#include "nnlayer3.mt.inc.cpp"
Ivan Mahonin 53488e
Ivan Mahonin 53488e
Ivan Mahonin 53488e
long long timeUs() {
Ivan Mahonin 53488e
  static std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
Ivan Mahonin 53488e
  return (long long)std::chrono::duration_cast<std::chrono::microseconds>( std::chrono::steady_clock::now() - begin ).count();
Ivan Mahonin 53488e
}
Ivan Mahonin 53488e
Ivan Mahonin 53488e
Ivan Mahonin 53488e
bool train(const char *infile, const char *outfile, Layer &l, int blockSize, int totalCount, Real trainRatio) {
Ivan Mahonin 53488e
  assert(blockSize > 0);
Ivan Mahonin 53488e
  int blockCount = totalCount/blockSize;
Ivan Mahonin 53488e
  assert(blockCount > 0);
Ivan Mahonin 53488e
  assert(!l.prev);
Ivan Mahonin 53488e
  assert(l.countNeurons() && l.back().countNeurons());
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  printf("load training data\n");
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  FILE *f = fopen(infile, "rb");
Ivan Mahonin 53488e
  if (!f)
Ivan Mahonin 53488e
    return printf("cannot open file '%s' for read\n", infile), false;
Ivan Mahonin 53488e
  fseek(f, 0, SEEK_END);
Ivan Mahonin 53488e
  int fs = ftell(f);
Ivan Mahonin 53488e
  fseek(f, 0, SEEK_SET);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  int sizeX = l.countNeurons();
Ivan Mahonin 53488e
  int sizeY = l.back().countNeurons();
Ivan Mahonin 53488e
  int count = fs/(sizeX+1);
Ivan Mahonin 53488e
  if (count < blockSize)
Ivan Mahonin 53488e
    return printf("file '%s' is lesser minimal size\n", infile), fclose(f), false;
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  unsigned char *data = new unsigned char[(sizeX + sizeY)*count];
Ivan Mahonin 53488e
  memset(data, 0, (sizeX + sizeY)*count);
Ivan Mahonin 53488e
  for(int i = 0; i < count; ++i) {
Ivan Mahonin 53488e
    unsigned char *d = data + (sizeX + sizeY)*i;
Ivan Mahonin 53488e
    if (!fread(d, sizeX+1, 1, f) || d[sizeX] >= sizeY)
Ivan Mahonin 53488e
      return printf("cannot read from file '%s'\n", infile), delete[] data, fclose(f), false;
Ivan Mahonin 53488e
    d += sizeX;
Ivan Mahonin 53488e
    unsigned char c = *d;
Ivan Mahonin 53488e
    *d = 0;
Ivan Mahonin 53488e
    d[c] = 255;
Ivan Mahonin 53488e
  }
Ivan Mahonin 53488e
  fclose(f);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  printf("train %d x %d = %d, ratio: %f\n", blockCount, blockSize, blockCount*blockSize, trainRatio);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  int *shuffle = new int[blockSize];
Ivan Mahonin 53488e
  TrainMT tmt;
Ivan Mahonin 53488e
  tmt.layer = &l;
Ivan Mahonin 53488e
  tmt.dataX = data;
Ivan Mahonin 53488e
  tmt.dataY = data + sizeX;
Ivan Mahonin 53488e
  tmt.strideX = tmt.strideY = sizeX + sizeY;
Ivan Mahonin 53488e
  tmt.shuffle = shuffle;
Ivan Mahonin 53488e
  tmt.count = blockSize;
Ivan Mahonin 53488e
  tmt.trainRatio = trainRatio;
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  long long timeStartUs = timeUs();
Ivan Mahonin 53488e
  for(int i = 0; i < blockCount; ++i) {
Ivan Mahonin 53488e
    long long timeBlockStartUs = timeUs();
Ivan Mahonin 53488e
Ivan Mahonin 53488e
    for(int j = 0; j < blockSize; ++j)
Ivan Mahonin 53488e
      shuffle[j] = rand()%count;
Ivan Mahonin 53488e
    double res = tmt.train(4);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
    long long dt = timeUs() - timeBlockStartUs;
Ivan Mahonin 53488e
Ivan Mahonin 53488e
    printf("%4d, total %7d, avg.result %f, time: %f\n", i+1, (i+1)*blockSize, res, dt*0.000001);
Ivan Mahonin 53488e
    if ( ((i+1)%100) == 0 || i+1 == blockCount ) {
Ivan Mahonin 53488e
      if (!l.saveAll(outfile)) return delete[] data, delete[] shuffle, false;
Ivan Mahonin 53488e
      printf("  saved\n");
Ivan Mahonin 53488e
    }
Ivan Mahonin 53488e
  }
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  long long dt = timeUs() - timeStartUs;
Ivan Mahonin 53488e
  printf("finished int time: %f\n", dt*0.000001);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  delete[] shuffle;
Ivan Mahonin 53488e
  delete[] data;
Ivan Mahonin 53488e
  return true;
Ivan Mahonin 53488e
}
Ivan Mahonin 53488e
Ivan Mahonin 53488e
Ivan Mahonin 53488e
int main() {
Ivan Mahonin 53488e
  srand(time(NULL));
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  const char *infile = "data/symbols-data.bin"; // 28x28
Ivan Mahonin 53488e
  const char *outfile = "data/output/weights.bin";
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  printf("create neural network\n");
Ivan Mahonin 53488e
  Layer l(nullptr, 28, 28,  1);
Ivan Mahonin 53488e
  new Layer(&l, 14, 14,  1, 28);
Ivan Mahonin 53488e
  new Layer(&l,  7,  7,  1, 14);
Ivan Mahonin 53488e
  new Layer(&l,  1,  1, 10,  7);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  printf("  neurons: %d, links %d, memSize: %llu\n", l.totalNeurons(), l.totalLinks(), (unsigned long long)l.totalMemSize());
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  //printf("try load previously saved network\n");
Ivan Mahonin 53488e
  //l.loadAll(outfile);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  printf("train\n");
Ivan Mahonin 53488e
  train(infile, outfile, l, 10000, 1000000, 0.01);
Ivan Mahonin 53488e
Ivan Mahonin 53488e
  return 0;
Ivan Mahonin 53488e
}
Ivan Mahonin 53488e