|
|
53488e |
|
|
|
53488e |
#include <ctime></ctime>
|
|
|
53488e |
#include <cstdlib></cstdlib>
|
|
|
53488e |
#include <cstdio></cstdio>
|
|
|
53488e |
|
|
|
53488e |
#include <algorithm></algorithm>
|
|
|
53488e |
|
|
|
53488e |
#include "nnlayer.lnk.inc.cpp"
|
|
|
53488e |
#include "tga.inc.cpp"
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
void imgTrain(Layer &l, const char *datafile, int size, const char *outfile, double trainRatio, int count) {
|
|
|
53488e |
Layer &bl = l.back();
|
|
|
53488e |
|
|
|
53488e |
assert(!l.prev);
|
|
|
53488e |
assert(datafile);
|
|
|
53488e |
assert(count > 0 && size > 0);
|
|
|
53488e |
assert(l.size == size);
|
|
|
53488e |
assert(bl.size == size);
|
|
|
53488e |
|
|
|
53488e |
int blockSize = 1000;//1024*1024*1024/size;
|
|
|
53488e |
assert(blockSize > 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 |
int *block = new int[blockSize*2];
|
|
|
53488e |
int *shuffle = block + blockSize;
|
|
|
53488e |
double *results = new double[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; results[j] = 0; }
|
|
|
53488e |
|
|
|
53488e |
int blocksCount = (count - 1)/blockSize + 1;
|
|
|
53488e |
|
|
|
53488e |
printf("training %d (%d x %d blocks), tests: %d, ratio: %f:\n", blocksCount*blockSize, blocksCount, blockSize, xCount, trainRatio);
|
|
|
53488e |
|
|
|
53488e |
double avgSum = 0;
|
|
|
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[i], 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 |
double sumQ = 0;
|
|
|
53488e |
for(int j = 0; j < blockSize; ++j) {
|
|
|
53488e |
unsigned char *data = blockData + shuffle[j]*size;
|
|
|
53488e |
for(double *ia = l.a, *e = ia + l.size; ia < e; ++ia, ++data)
|
|
|
53488e |
*ia = *data/255.0;
|
|
|
53488e |
|
|
|
53488e |
double firstQ = 0, q = 0;
|
|
|
53488e |
for(int repeat = 0; repeat < 1; ++repeat) {
|
|
|
53488e |
l.pass();
|
|
|
53488e |
|
|
|
53488e |
for(double *ia = l.a, *iba = bl.a, *ibda = bl.da, *e = ia + l.size; ia < e; ++ia, ++iba, ++ibda) {
|
|
|
53488e |
double d = *ia - *iba;
|
|
|
53488e |
*ibda = d;
|
|
|
53488e |
q += d*d;
|
|
|
53488e |
}
|
|
|
53488e |
q /= size;
|
|
|
53488e |
if (!repeat) firstQ = q;
|
|
|
53488e |
|
|
|
53488e |
bl.backpass(trainRatio);
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
sumQ += firstQ;
|
|
|
53488e |
avgSum += firstQ - results[j];
|
|
|
53488e |
results[j] = firstQ;
|
|
|
53488e |
int avgCnt = i ? blockSize : j + 1;
|
|
|
53488e |
printf(" %4d: total: %6d, avg result: %f, last result: %f -> %f\n", j+1, i*blockSize+j+1, avgSum/avgCnt, firstQ, q);
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
printf("%4d: total: %6d, avg result: %f\n", i+1, (i+1)*blockSize, sumQ/blockSize);
|
|
|
53488e |
|
|
|
53488e |
if (outfile && !l.save(outfile))
|
|
|
53488e |
{ printf("cannot save neural network weights to file: %s\n", outfile); err = true; break; }
|
|
|
53488e |
|
|
|
53488e |
unsigned char *data = blockResData;
|
|
|
53488e |
for(double *iba = bl.a, *e = iba + bl.size; iba < e; ++iba, ++data)
|
|
|
53488e |
*data = (unsigned char)(*iba*255.999);
|
|
|
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 |
|
|
|
53488e |
delete[] block;
|
|
|
53488e |
delete[] results;
|
|
|
53488e |
delete[] blockData;
|
|
|
53488e |
|
|
|
53488e |
printf("finished\n");
|
|
|
53488e |
}
|
|
|
53488e |
|
|
|
53488e |
|
|
|
53488e |
int main() {
|
|
|
53488e |
srand(time(NULL));
|
|
|
53488e |
|
|
|
53488e |
//const char *datafile = "data/img512-data.bin";
|
|
|
53488e |
//const char *outfile = "data/output/img512-weights.bin";
|
|
|
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 |
//Layer l(nullptr, 512*512*3);
|
|
|
53488e |
//new LayerLinkConvolution(l, 512, 512, 3, 256, 256, 3, 32);
|
|
|
53488e |
//new LayerLinkConvolution(l, 256, 256, 3, 128, 128, 3, 64);
|
|
|
53488e |
//new LayerLinkConvolution(l, 128, 128, 3, 64, 64, 3, 128);
|
|
|
53488e |
//new LayerLinkConvolution(l, 64, 64, 3, 32, 32, 3, 256);
|
|
|
53488e |
//new LayerLinkConvolution(l, 32, 32, 3, 16, 16, 4, 256);
|
|
|
53488e |
//new LayerLinkConvolution(l, 16, 16, 4, 16, 16, 4, 256);
|
|
|
53488e |
//new LayerLinkConvolution(l, 16, 16, 4, 16, 16, 4, 256);
|
|
|
53488e |
//new LayerLinkConvolution(l, 16, 16, 4, 32, 32, 3, 256);
|
|
|
53488e |
//new LayerLinkConvolution(l, 32, 32, 3, 64, 64, 3, 128);
|
|
|
53488e |
//new LayerLinkConvolution(l, 64, 64, 3, 128, 128, 3, 64);
|
|
|
53488e |
//new LayerLinkConvolution(l, 128, 128, 3, 256, 256, 3, 32);
|
|
|
53488e |
//new LayerLinkConvolution(l, 256, 256, 3, 512, 512, 3, 16);
|
|
|
53488e |
|
|
|
53488e |
Layer l(nullptr, 256*256*3);
|
|
|
53488e |
new LayerLinkConvolution(l, 256, 256, 3, 128, 128, 3, 32);
|
|
|
53488e |
new LayerLinkConvolution(l, 128, 128, 3, 64, 64, 3, 64);
|
|
|
53488e |
new LayerLinkConvolution(l, 64, 64, 3, 32, 32, 3, 128);
|
|
|
53488e |
new LayerLinkConvolution(l, 32, 32, 3, 16, 16, 4, 256);
|
|
|
53488e |
new LayerLinkConvolution(l, 16, 16, 4, 16, 16, 4, 256);
|
|
|
53488e |
new LayerLinkConvolution(l, 16, 16, 4, 16, 16, 4, 256);
|
|
|
53488e |
new LayerLinkConvolution(l, 16, 16, 4, 32, 32, 3, 128);
|
|
|
53488e |
new LayerLinkConvolution(l, 32, 32, 3, 64, 64, 3, 64);
|
|
|
53488e |
new LayerLinkConvolution(l, 64, 64, 3, 128, 128, 3, 32);
|
|
|
53488e |
new LayerLinkConvolution(l, 128, 128, 3, 256, 256, 3, 16);
|
|
|
53488e |
|
|
|
53488e |
printf(" neurons: %d, links %d, memSize: %llu\n", l.totalSize(), l.totalLinks(), (unsigned long long)l.totalMemSize());
|
|
|
53488e |
|
|
|
53488e |
printf("try load previously saved network\n");
|
|
|
53488e |
l.load(outfile);
|
|
|
53488e |
|
|
|
53488e |
printf("train\n");
|
|
|
53488e |
imgTrain(l, datafile, l.size, outfile, 0.1, 1000000);
|
|
|
53488e |
|
|
|
53488e |
return 0;
|
|
|
53488e |
}
|
|
|
53488e |
|