Blame simple/neural/nn-trainer3-img.cpp

53488e
53488e
#include <ctime></ctime>
53488e
#include <cstdlib></cstdlib>
53488e
#include <cstdio></cstdio>
53488e
53488e
#include <chrono></chrono>
53488e
#include <algorithm></algorithm>
53488e
53488e
#include "nnlayer3.mt.inc.cpp"
53488e
#include "tga.inc.cpp"
53488e
53488e
53488e
long long timeUs() {
53488e
  static std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
53488e
  return (long long)std::chrono::duration_cast<std::chrono::microseconds>( std::chrono::steady_clock::now() - begin ).count();</std::chrono::microseconds>
53488e
}
53488e
53488e
53488e
void imgTrain(Layer &l, const char *datafile, int size, const char *outfile, int blockSize, int blocksCount, Real trainRatio, int threads) {
53488e
  Layer &fl = l.front();
53488e
  Layer &bl = l.back();
53488e
53488e
  assert(!l.prev);
53488e
  assert(datafile);
53488e
  assert(size > 0);
53488e
  assert(fl.countNeurons() == size);
53488e
  assert(bl.countNeurons() == size);
53488e
53488e
  assert(blockSize > 0);
53488e
  assert(blocksCount > 0);
53488e
  assert(trainRatio > 0);
53488e
  assert(threads > 0);
53488e
53488e
  FILE *f = fopen(datafile, "rb");
53488e
  if (!f)
53488e
    { printf("cannot open file: %s\n", datafile); return; }
53488e
  fseeko64(f, 0, SEEK_END);
53488e
  long long fsize = ftello64(f);
53488e
  int xCount = (int)(fsize/size);
53488e
  if (xCount <= 0)
53488e
    { printf("no tests in file: %s\n", datafile); return; }
53488e
53488e
  printf("allocate %lld bytes for tests\n", ((long long)blockSize + 1)*size);
53488e
53488e
  int *block = new int[blockSize*2];
53488e
  int *shuffle = block + blockSize;
53488e
  unsigned char *blockData = new unsigned char[(blockSize + 1)*size];
53488e
  unsigned char *blockResData = blockData + blockSize*size;
53488e
  bool err = false;
53488e
53488e
  for(int j = 0; j < blockSize; ++j)
53488e
    shuffle[j] = j;
53488e
53488e
  TrainMT tmt;
53488e
  tmt.layer = &fl;
53488e
  tmt.dataX = blockData;
53488e
  tmt.dataY = blockData;
53488e
  tmt.strideX = tmt.strideY = size;
53488e
  tmt.shuffle = shuffle;
53488e
  tmt.count = blockSize;
53488e
  tmt.trainRatio = trainRatio;
53488e
53488e
  printf("training %d (%d x %d blocks), tests: %d, ratio: %f:\n", blocksCount*blockSize, blocksCount, blockSize, xCount, trainRatio);
53488e
53488e
  long long t0 = timeUs();
53488e
  for(int i = 0; i < blocksCount; ++i) {
53488e
    for(int j = 0; j < blockSize; ++j) {
53488e
      block[j] = rand()%xCount;
53488e
      std::swap(shuffle[j], shuffle[rand()%blockSize]);
53488e
    }
53488e
    std::sort(block, block + blockSize);
53488e
53488e
    for(int j = 0; j < blockSize; ++j) {
53488e
      fseeko64(f, block[j]*(long long)size, SEEK_SET);
53488e
      if (!fread(blockData + j*size, size, 1, f))
53488e
        { printf("cannot read data from file: %s\n", datafile); err = true; break; }
53488e
    }
53488e
    if (err) break;
53488e
53488e
    //printf("  next data block loaded\n");
53488e
53488e
    long long t = timeUs();
53488e
    double res = tmt.train(threads);
53488e
    long long dt = timeUs() - t;
53488e
53488e
    if (outfile && !fl.saveAll(outfile))
53488e
      { printf("cannot save neural network weights to file: %s\n", outfile); err = true; break; }
53488e
53488e
    unsigned char *data = blockResData;
53488e
    for(Neuron *ibn = bl.neurons, *e = ibn + size; ibn < e; ++ibn, ++data) {
53488e
      Real v = (ibn->v - 0.25)*2;
53488e
      *data = v < 0 ? 0u : v > 1 ? 255u : (unsigned char)(v * 255.999);
53488e
    }
53488e
    tgaSave("data/output/sampleX.tga", blockData + shuffle[blockSize-1]*size, 256, 256, 3);
53488e
    tgaSave("data/output/sampleY.tga", blockResData, 256, 256, 3);
53488e
53488e
    long long t1 = timeUs();
53488e
    long long dt0 = t1 - t0;
53488e
    t0 = t1;
53488e
53488e
    printf("%4d: total: %6d, avg result: %f, time: %f + %f = %f\n", i+1, (i+1)*blockSize, res, (dt0-dt)*0.000001, dt*0.000001, dt0*0.000001);
53488e
53488e
  }
53488e
53488e
  delete[] block;
53488e
  delete[] blockData;
53488e
53488e
  printf("finished\n");
53488e
}
53488e
53488e
53488e
int main() {
53488e
  srand(time(NULL));
53488e
53488e
  const char *datafile = "data/img256-data.bin";
53488e
  const char *outfile = "data/output/img256-weights.bin";
53488e
53488e
  printf("create neural network\n");
53488e
53488e
  Layer l(nullptr, 256, 256, 3);
53488e
  //new Layer(&l, 128, 128, 3,  6);
53488e
  //new Layer(&l,  64,  64, 3,  8);
53488e
  //new Layer(&l,  32,  32, 3, 11);
53488e
  //new Layer(&l,  16,  16, 4, 16);
53488e
  //new Layer(&l,  16,  16, 4, 16);
53488e
  //new Layer(&l,  16,  16, 4, 16);
53488e
  //new Layer(&l,  32,  32, 3, 11);
53488e
  //new Layer(&l,  64,  64, 3,  8);
53488e
  //new Layer(&l, 128, 128, 3,  6);
53488e
  new Layer(&l, 256, 256, 3,  4);
53488e
  new Layer(&l, 256, 256, 3,  4);
53488e
  new Layer(&l, 256, 256, 3,  4);
53488e
53488e
  printf("  neurons: %d, links %d, memSize: %llu\n", l.totalNeurons(), l.totalLinks(), (unsigned long long)l.totalMemSize());
53488e
53488e
  if (outfile) {
53488e
    printf("try load previously saved network\n");
53488e
    l.loadAll(outfile);
53488e
  }
53488e
53488e
  printf("train\n");
53488e
  imgTrain(l, datafile, l.countNeurons(), outfile, 1000, 10000, 0.1, 4);
53488e
53488e
  return 0;
53488e
}
53488e