Blame projects/neural/train.cx4.inc.cpp

Ivan Mahonin b579b3
#ifndef TRAIN_CX4_INC_CPP
Ivan Mahonin b579b3
#define TRAIN_CX4_INC_CPP
Ivan Mahonin b579b3
Ivan Mahonin b579b3
Ivan Mahonin b579b3
#include "train.segment.inc.cpp"
Ivan Mahonin b579b3
#include "segment.cx4.inc.cpp"
Ivan Mahonin b579b3
#include "layer.inc.cpp"
Ivan Mahonin b579b3
Ivan Mahonin b579b3
Ivan Mahonin b579b3
class TrainerCx4: public TrainerSegment {
Ivan Mahonin b579b3
protected:
Ivan Mahonin b579b3
  FILE *f;
Ivan Mahonin b579b3
  std::vector<unsigned char> data;
Ivan Mahonin b579b3
  std::vector<NeuronReal> values;
Ivan Mahonin b579b3
  std::vector<NeuronReal> valuesMeasure;
Ivan Mahonin b579b3
  std::vector<unsigned char> tmpdata;
Ivan Mahonin b579b3
  std::vector<int> shuffle;
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  Layout trainLayout;
Ivan Mahonin b579b3
  Layout measureLayout;
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  size_t imageSize;
Ivan Mahonin b579b3
  size_t preparedImageSize;
Ivan Mahonin b579b3
  int imagesInFile;
Ivan Mahonin b579b3
  int imagesInMemory;
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  volatile unsigned int seed;
Ivan Mahonin b579b3
Ivan Mahonin b579b3
public:
Ivan Mahonin b579b3
  Layer *layerFull;
Ivan Mahonin b579b3
  Layer *layerPre;
Ivan Mahonin b579b3
  int loadImagesCount;
Ivan Mahonin b579b3
  int blocksPerLoading;
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  const char *infile;
Ivan Mahonin b579b3
  const char *cachefile;
Ivan Mahonin b579b3
  const char *outfile;
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  TrainerCx4():
Ivan Mahonin b579b3
    f(),
Ivan Mahonin b579b3
    imageSize(),
Ivan Mahonin b579b3
    preparedImageSize(),
Ivan Mahonin b579b3
    imagesInFile(),
Ivan Mahonin b579b3
    imagesInMemory(),
Ivan Mahonin b579b3
    seed(),
Ivan Mahonin b579b3
    layerFull(),
Ivan Mahonin b579b3
    layerPre(),
Ivan Mahonin b579b3
    loadImagesCount(),
Ivan Mahonin b579b3
    blocksPerLoading(1),
Ivan Mahonin b579b3
    infile(),
Ivan Mahonin b579b3
    cachefile(),
Ivan Mahonin b579b3
    outfile() { }
Ivan Mahonin b579b3
Ivan Mahonin b579b3
protected:
Ivan Mahonin b579b3
  void preprocess(unsigned char *src, NeuronReal *dst) {
Ivan Mahonin b579b3
    struct IL: public Iter {
Ivan Mahonin b579b3
      typedef const unsigned char* DataType;
Ivan Mahonin b579b3
      static inline void iter4(Neuron &n, DataType d, DataAccumType&) { n.v = *d/(NeuronReal)255; }
Ivan Mahonin b579b3
    };
Ivan Mahonin b579b3
    struct IS: public Iter {
Ivan Mahonin b579b3
      typedef NeuronReal* DataType;
Ivan Mahonin b579b3
      static inline void iter4(Neuron &n, DataType d, DataAccumType&) { *d = n.v; }
Ivan Mahonin b579b3
    };
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    Layer &fl = *layerFull;
Ivan Mahonin b579b3
    Layer &bl = *layerPre;
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    iterateNeurons2<IL>(fl.layout, fl.layout, fl.neurons, src);
Ivan Mahonin b579b3
    fl.passFull(&bl, threadsCount);
Ivan Mahonin b579b3
    iterateNeurons2<IS>(bl.layout, bl.layout, bl.neurons, dst);
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  bool loadImage(int fromIndex, int toIndex) {
Ivan Mahonin b579b3
    unsigned char *src = data.data();
Ivan Mahonin b579b3
    if (!layerPre) src += toIndex*imageSize;
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    fseeko64(f, fromIndex*imageSize, SEEK_SET);
Ivan Mahonin b579b3
    if (!fread(src, imageSize, 1, f))
Ivan Mahonin b579b3
      return fclose(f), f = nullptr, false;
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    if (layerPre) preprocess(src, values.data() + toIndex*preparedImageSize);
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    return true;
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  bool loadImages() {
Ivan Mahonin b579b3
    for(int i = 0; i < imagesInMemory; ++i) {
Ivan Mahonin b579b3
      int j = rand()%imagesInFile;
Ivan Mahonin b579b3
      if (i != j) std::swap(shuffle[i], shuffle[j]);
Ivan Mahonin b579b3
    }
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    typedef std::pair<int, int> Pair;
Ivan Mahonin b579b3
    typedef std::set<Pair> Set;
Ivan Mahonin b579b3
    Set set;
Ivan Mahonin b579b3
    for(int i = 0; i < imagesInMemory; ++i)
Ivan Mahonin b579b3
      set.insert(Pair(shuffle[i], i));
Ivan Mahonin b579b3
    for(Set::iterator i = set.begin(); i != set.end(); ++i)
Ivan Mahonin b579b3
      loadImage(i->first, i->second);
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    return true;
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  void prepareMeasure() {
Ivan Mahonin b579b3
    if (measuresPerBlock <= 0) return;
Ivan Mahonin b579b3
    int sy = segment->sy;
Ivan Mahonin b579b3
    int sx = segment->sx;
Ivan Mahonin b579b3
    int sz = segment->sz;
Ivan Mahonin b579b3
    int sxz = sx*sz;
Ivan Mahonin b579b3
    int w = (layerPre ? layerPre : layerFull)->layout.getW();
Ivan Mahonin b579b3
    int h = (layerPre ? layerPre : layerFull)->layout.getH();
Ivan Mahonin b579b3
    int rowstride = w*sz;
Ivan Mahonin b579b3
    NeuronReal *dst = valuesMeasure.data();
Ivan Mahonin b579b3
    for(int i = 0; i < measuresPerBlock; ++i) {
Ivan Mahonin b579b3
      int index = rand()%imagesInMemory;
Ivan Mahonin b579b3
      int x = rand()%(w - sx + 1);
Ivan Mahonin b579b3
      int y = rand()%(h - sy + 1);
Ivan Mahonin b579b3
      if (layerPre) {
Ivan Mahonin b579b3
        const NeuronReal *src = values.data() + index*preparedImageSize + y*rowstride + x*sz;
Ivan Mahonin b579b3
        for(int j = 0; j < sy; ++j, src += rowstride, dst += sxz)
Ivan Mahonin b579b3
          memcpy(dst, src, sxz*sizeof(*dst));
Ivan Mahonin b579b3
      } else {
Ivan Mahonin b579b3
        const unsigned char *src = data.data() + index*preparedImageSize + y*rowstride + x*sz;
Ivan Mahonin b579b3
        for(int j = 0; j < sy; ++j, src += rowstride - sxz)
Ivan Mahonin b579b3
        for(int k = 0; k < sxz; ++k, ++src, ++dst)
Ivan Mahonin b579b3
          *dst = *src/(NeuronReal)255;
Ivan Mahonin b579b3
      }
Ivan Mahonin b579b3
    }
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  bool prepare() override {
Ivan Mahonin b579b3
    assert(infile);
Ivan Mahonin b579b3
    assert(layerFull);
Ivan Mahonin b579b3
    assert(loadImagesCount > 0);
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    Layer &fl = layerFull->front();
Ivan Mahonin b579b3
    Layer &bl = layerFull->back();
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    imageSize = fl.layout.getActiveCount();
Ivan Mahonin b579b3
    f = fopen(infile, "rb");
Ivan Mahonin b579b3
    if (!f) return false;
Ivan Mahonin b579b3
    fseeko64(f, 0, SEEK_END);
Ivan Mahonin b579b3
    imagesInFile = ftello64(f)/imageSize;
Ivan Mahonin b579b3
    if (imagesInFile < 1) return fclose(f), f = nullptr, false;
Ivan Mahonin b579b3
    imagesInMemory = loadImagesCount > imagesInFile ? imagesInFile : loadImagesCount;
Ivan Mahonin b579b3
    
Ivan Mahonin e4740d
    for(Layer *l = layerFull; l; l = l->next)
Ivan Mahonin e4740d
      l->split(threadsCount);
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    Layout l = layerPre ? layerPre->layout : layerFull->layout;
Ivan Mahonin b579b3
    assert(l.getW() >= segment->sx);
Ivan Mahonin b579b3
    assert(l.getH() >= segment->sy);
Ivan Mahonin b579b3
    assert(l.getD() == segment->sz);
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    measureLayout = Layout(segment->sx, segment->sy, segment->sz);
Ivan Mahonin b579b3
    valuesMeasure.resize(measuresPerBlock * measureLayout.getActiveCount());
Ivan Mahonin b579b3
    if (layerPre) {
Ivan Mahonin b579b3
      assert(l);
Ivan Mahonin b579b3
      preparedImageSize = layerPre->layout.getActiveCount();
Ivan Mahonin b579b3
      trainLayout = Layout(l.getW(), l.getH(), l.getD());
Ivan Mahonin b579b3
      data.resize(imageSize);
Ivan Mahonin b579b3
      values.resize(imagesInMemory * preparedImageSize);
Ivan Mahonin b579b3
    } else {
Ivan Mahonin b579b3
      trainLayout = measureLayout;
Ivan Mahonin b579b3
      data.resize(imagesInMemory * imageSize);
Ivan Mahonin b579b3
      values.resize(segment->sx * segment->sy * segment->sz);
Ivan Mahonin b579b3
    }
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    segment->f_values = values.data();
Ivan Mahonin b579b3
    segment->layout = trainLayout;
Ivan Mahonin b579b3
    tmpdata.resize(bl.layout.getActiveCount());
Ivan Mahonin b579b3
    if (tmpdata.size() < imageSize) tmpdata.resize(imageSize);
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
    size_t memsize = data.size()*sizeof(data.front())
Ivan Mahonin b579b3
                   + values.size()*sizeof(values.front())
Ivan Mahonin b579b3
                   + valuesMeasure.size()*sizeof(valuesMeasure.front())
Ivan Mahonin b579b3
                   + tmpdata.size()*sizeof(tmpdata.front());
Ivan Mahonin b579b3
    printf("allocated size: %lld\n", (long long)(memsize));
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    shuffle.resize(imagesInFile);
Ivan Mahonin b579b3
    for(int i = 0; i < imagesInFile; ++i)
Ivan Mahonin b579b3
      shuffle[i] = i;
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    if (!loadImages()) return false;
Ivan Mahonin b579b3
    prepareMeasure();
Ivan Mahonin b579b3
    return true;
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  void finish() override
Ivan Mahonin b579b3
    { if (f) fclose(f), f = nullptr; }
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    
Ivan Mahonin b579b3
  bool prepareBlock(int block, bool measureOnly) override {
Ivan Mahonin b579b3
    if (block > 0 && blocksPerLoading > 0 && (block % blocksPerLoading) == 0 && !loadImages())
Ivan Mahonin b579b3
      return false;
Ivan Mahonin b579b3
    seed = rand();
Ivan Mahonin b579b3
    return true;
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  
Ivan Mahonin b579b3
  void finishBlock(int block) override {
Ivan Mahonin b579b3
    if (outfile) {
Ivan Mahonin b579b3
      struct IL: public Iter {
Ivan Mahonin b579b3
        typedef const unsigned char* DataType;
Ivan Mahonin b579b3
        static inline void iter4(Neuron &n, DataType d, DataAccumType&) { n.v = *d/(NeuronReal)255; }
Ivan Mahonin b579b3
      };
Ivan Mahonin b579b3
      struct IS: public Iter {
Ivan Mahonin b579b3
        typedef unsigned char* DataType;
Ivan Mahonin b579b3
        static inline void iter4(Neuron &n, DataType d, DataAccumType&) { *d = n.v < 0 ? 0 : n.v > 1 ? 255 : (unsigned char)(n.v*255.999); }
Ivan Mahonin b579b3
      };
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      Layer &fl = *layerFull;
Ivan Mahonin b579b3
      Layer &bl = fl.back();
Ivan Mahonin b579b3
Ivan Mahonin b579b3
      std::string outfile0(outfile);
Ivan Mahonin b579b3
      std::string outfile1 = outfile0 + ".1.tga";
Ivan Mahonin b579b3
      outfile0 += ".0.tga";
Ivan Mahonin b579b3
Ivan Mahonin b579b3
      int index = rand()%imagesInFile;
Ivan Mahonin b579b3
      fseeko64(f, index*imageSize, SEEK_SET);
Ivan Mahonin b579b3
      fread(tmpdata.data(), imageSize, 1, f);
Ivan Mahonin b579b3
      tgaSave(outfile0.c_str(), tmpdata.data(), fl.layout.getW(), fl.layout.getH(), fl.layout.getD());
Ivan Mahonin b579b3
Ivan Mahonin b579b3
      iterateNeurons2<IL>(fl.layout, fl.layout, fl.neurons, tmpdata.data());
Ivan Mahonin b579b3
      fl.passFull(&bl, threadsCount);
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      iterateNeurons2<IS>(bl.layout, bl.layout, bl.neurons, tmpdata.data());
Ivan Mahonin b579b3
      tgaSave(outfile1.c_str(), tmpdata.data(), bl.layout.getW(), bl.layout.getH(), bl.layout.getD());
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      segment->saveDemo();
Ivan Mahonin b579b3
    }
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
Ivan Mahonin b579b3
Ivan Mahonin b579b3
  void loadData(Barrier &barrier, int block, int iter, bool measureOnly) override {
Ivan Mahonin b579b3
    int tid = barrier.tid;
Ivan Mahonin b579b3
    int threads = barrier.threads;
Ivan Mahonin b579b3
    int sx = segment->sx;
Ivan Mahonin b579b3
    int sy = segment->sy;
Ivan Mahonin b579b3
    int sz = segment->sz;
Ivan Mahonin b579b3
    int sxz = sx*sz;
Ivan Mahonin b579b3
Ivan Mahonin b579b3
    if (measureOnly) {
Ivan Mahonin b579b3
      if (!tid) {
Ivan Mahonin b579b3
        segment->layout = measureLayout;
Ivan Mahonin b579b3
        segment->f_values = valuesMeasure.data() + iter*sy*sxz;
Ivan Mahonin b579b3
        x = y = z = 0;
Ivan Mahonin b579b3
      }
Ivan Mahonin b579b3
    } else
Ivan Mahonin b579b3
    if (layerPre) {
Ivan Mahonin b579b3
      if (!tid) {
Ivan Mahonin b579b3
        unsigned int s = randomNext(seed & iter);
Ivan Mahonin b579b3
        int index = (s = randomNext(s))%imagesInMemory;
Ivan Mahonin b579b3
        x = (s = randomNext(s)) % (layerPre->layout.getW() - sx + 1);
Ivan Mahonin b579b3
        y = (s = randomNext(s)) % (layerPre->layout.getH() - sy + 1);
Ivan Mahonin b579b3
        z = 0;
Ivan Mahonin b579b3
        segment->layout = trainLayout;
Ivan Mahonin b579b3
        segment->f_values = values.data() + index*preparedImageSize;
Ivan Mahonin b579b3
      }
Ivan Mahonin b579b3
    } else {
Ivan Mahonin b579b3
      int w = layerFull->layout.getW();
Ivan Mahonin b579b3
      int h = layerFull->layout.getH();
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      unsigned int s = randomNext(seed & iter);
Ivan Mahonin b579b3
      int index = (s = randomNext(s))%imagesInMemory;
Ivan Mahonin b579b3
      int x0    = (s = randomNext(s))%(w - sx + 1);
Ivan Mahonin b579b3
      int y0    = (s = randomNext(s))%(h - sy + 1);
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      int rowstride = w*sz;
Ivan Mahonin b579b3
      int dr = rowstride*threads - sxz;
Ivan Mahonin b579b3
      int vdr = sxz*(threads - 1);
Ivan Mahonin b579b3
Ivan Mahonin b579b3
      const unsigned char *id0 = data.data() + index*imageSize + y0*rowstride + x0*sz;
Ivan Mahonin b579b3
      const unsigned char *id = id0 + tid*rowstride;
Ivan Mahonin b579b3
      NeuronReal *iv = values.data() + tid*sxz;
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      for(const unsigned char *e = id0 + sy*rowstride; id < e; id += dr, iv += vdr)
Ivan Mahonin b579b3
      for(const unsigned char *e = id + sxz;        id < e; ++id, ++iv)
Ivan Mahonin b579b3
        *iv = *id/(NeuronReal)255;
Ivan Mahonin b579b3
      
Ivan Mahonin b579b3
      if (!tid) {
Ivan Mahonin b579b3
        segment->layout = trainLayout;
Ivan Mahonin b579b3
        segment->f_values = values.data();
Ivan Mahonin b579b3
        x = 0, y = 0, z = 0;
Ivan Mahonin b579b3
      }
Ivan Mahonin b579b3
    }
Ivan Mahonin b579b3
  }
Ivan Mahonin b579b3
};
Ivan Mahonin b579b3
Ivan Mahonin b579b3
Ivan Mahonin b579b3
#endif