Blame simple/neural/nntrain.inc.c.copy

ec0d7e
#ifndef NNTRAIN_INC_C
ec0d7e
#define NNTRAIN_INC_C
ec0d7e
ec0d7e
ec0d7e
#include "nnlayer.inc.c"
ec0d7e
ec0d7e
ec0d7e
typedef struct NeuralTrainer {
ec0d7e
  int sizeX, sizeY, count;
ec0d7e
  double *x, *y;
ec0d7e
} NeuralTrainer;
ec0d7e
ec0d7e
ec0d7e
ec0d7e
NeuralTrainer* ntNew(int sizeX, int sizeY, int count) {
ec0d7e
  assert(sizeX > 0);
ec0d7e
  assert(sizeY > 0);
ec0d7e
  assert(count > 0);
ec0d7e
  NeuralTrainer *nt = calloc(sizeof(NeuralTrainer), 1);
ec0d7e
  nt->sizeX = sizeX;
ec0d7e
  nt->sizeY = sizeY;
ec0d7e
  nt->count = count;
ec0d7e
  nt->x = calloc(sizeof(double)*(sizeX + sizeY)*count, 1);
ec0d7e
  nt->y = nt->x + sizeX*count;
ec0d7e
  return nt;
ec0d7e
}
ec0d7e
ec0d7e
ec0d7e
void ntFree(NeuralTrainer *nt) {
ec0d7e
  free(nt->x);
ec0d7e
  free(nt);
ec0d7e
}
ec0d7e
ec0d7e
ec0d7e
double ntTrain(NeuralTrainer *nt, NeuralLayer *nl, int blocks, int blockSize, int repeats, double qmin, double qminSample) {
ec0d7e
  assert(!nl->prev);
ec0d7e
  assert(nt->sizeX == nl->size);
ec0d7e
  assert(nt->sizeY == nlBack(nl)->size);
ec0d7e
ec0d7e
  printf("training: %d x %d x %d = %d:\n", blocks, blockSize, repeats, blocks*blockSize*repeats);
ec0d7e
  double qmax, qsum;
ec0d7e
  int total = 0;
ec0d7e
  int samples = 0;
ec0d7e
  for(int i = 0; i < blocks; ++i) {
ec0d7e
    qmax = qsum = 0;
ec0d7e
    int repeatsPerBlock = 0;
ec0d7e
    for(int j = 0; j < blockSize; ++j, ++samples) {
ec0d7e
      int index = rand() % nt->count;
ec0d7e
      double *x = nt->x + nt->sizeX*index;
ec0d7e
      double *y = nt->y + nt->sizeY*index;
ec0d7e
      double q = 0;
ec0d7e
      for(int k = 0; k < repeats; ++k) {
ec0d7e
        double qq = nlTrainPass(nl, x, y);
ec0d7e
        ++total, ++repeatsPerBlock;
ec0d7e
        if (!k) q = qq;
ec0d7e
        if (qq <= qminSample) break;
ec0d7e
      }
ec0d7e
      if (qmax < q) qmax = q;
ec0d7e
      qsum += q;
ec0d7e
    }
ec0d7e
    printf("  blocks %d (samples: %d, total: %d (%lf)): %lf, %lf\n", i+1, samples, total, repeatsPerBlock/(double)blockSize - 1, qmax, qsum/blockSize);
ec0d7e
    if (qmax <= qminSample) break;
ec0d7e
  }
ec0d7e
  printf("done\n");
ec0d7e
ec0d7e
  return qmax;
ec0d7e
}
ec0d7e
ec0d7e
ec0d7e
NeuralTrainer* ntNewSymbolMap(const char *filename, int sizeX, int sizeY) {
ec0d7e
  FILE *f = fopen(filename, "rb");
ec0d7e
  if (!f)
ec0d7e
    return printf("cannot open file '%s' for read\n", filename), NULL;
ec0d7e
  fseek(f, 0, SEEK_END);
ec0d7e
  size_t fs = ftell(f);
ec0d7e
  fseek(f, 0, SEEK_SET);
ec0d7e
ec0d7e
  size_t testSize = sizeX + 1;
ec0d7e
  int count = fs/testSize;
ec0d7e
  if (!count)
ec0d7e
    return printf("file '%s' is lesser minimal size\n", filename), fclose(f), NULL;
ec0d7e
ec0d7e
  unsigned char *data = calloc(testSize, count);
ec0d7e
  if (count != fread(data, testSize, count, f))
ec0d7e
    return printf("cannot read from file '%s'\n", filename), fclose(f), NULL;
ec0d7e
ec0d7e
  fclose(f);
ec0d7e
ec0d7e
  NeuralTrainer *nt = ntNew(sizeX, sizeY, count);
ec0d7e
  const unsigned char *d = data;
ec0d7e
  double *x = nt->x, *y = nt->y, *ey = y + sizeY*count;
ec0d7e
  const double delta = 0;
ec0d7e
  for(double *p = y; p < ey; ++p) *p = delta;
ec0d7e
  while(y < ey) {
ec0d7e
    for(double *e = x + sizeX; x < e; ++x, ++d)
ec0d7e
      *x = *d/255.0;
ec0d7e
    assert(*d < sizeY);
ec0d7e
    y[*d++] = 1 - delta;
ec0d7e
    y += sizeY;
ec0d7e
  }
ec0d7e
  return nt;
ec0d7e
}
ec0d7e
ec0d7e
ec0d7e
void ntPrintSymbol(NeuralTrainer *nt, int index, int width) {
ec0d7e
  assert(index >= 0 && index < nt->count);
ec0d7e
  assert(width > 0);
ec0d7e
  for(int i = 0; i < nt->sizeX; ++i) {
ec0d7e
    if (i && !(i % width)) printf("\n");
ec0d7e
    printf("%c", nt->x[nt->sizeX*index + i] > 0 ? '#' : '.');
ec0d7e
  }
ec0d7e
  printf("\n");
ec0d7e
  for(int i = 0; i < nt->sizeY; ++i)
ec0d7e
    printf(" %4.1lf", nt->y[nt->sizeY*index + i]);
ec0d7e
  printf("\n");
ec0d7e
}
ec0d7e
ec0d7e
ec0d7e
#endif