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