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

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