PetaVision  Alpha
InputLayer.hpp
1 // InputLayer
2 // Base class for layers that take their input from file IO
3 
4 #ifndef __INPUTLAYER_HPP__
5 #define __INPUTLAYER_HPP__
6 
7 #include "HyPerLayer.hpp"
8 #include "checkpointing/CheckpointableFileStream.hpp"
9 #include "columns/HyPerCol.hpp"
10 #include "components/BatchIndexer.hpp"
11 #include "structures/Buffer.hpp"
12 #include "utils/BorderExchange.hpp"
13 #include "utils/BufferUtilsRescale.hpp"
14 
15 #include <memory>
16 #include <random>
17 
18 namespace PV {
19 
20 class InputLayer : public HyPerLayer {
21  protected:
22  // inputPath: Either an individual file to load, or a .txt list of files to load.
23  virtual void ioParam_inputPath(enum ParamsIOFlag ioFlag);
24 
25  // offsetX: offset in X direction
26  // offsetY: offset in Y direction
27  // Defines an offset in image space where the column is viewing the image
28  virtual int ioParam_offsets(enum ParamsIOFlag ioFlag);
29 
30  // maxShiftX: max random shift in X direction
31  // maxShiftY: max random shift in Y direction
32  // Defines the max random shift in image space
33  virtual int ioParam_maxShifts(enum ParamsIOFlag ioFlag);
34  // xFlipEnabled: When true, 50% chance to mirror input horizontally
35  // yFlipEnabled: When true, 50% chance to mirror input vertically
36  virtual int ioParam_flipsEnabled(enum ParamsIOFlag ioFlag);
37  // xFlipToggle: When true, flip every jitter interval instead of randomly
38  // yFlipToggle: When true, flip every jitter interval instead of randomly
39  virtual int ioParam_flipsToggle(enum ParamsIOFlag ioFlag);
40  // jitterChangeInterval: interval measured in displayPeriods
41  // Defines the frequency of the random shifts updates
42  virtual int ioParam_jitterChangeInterval(enum ParamsIOFlag ioFlag);
43 
44  // offsetAnchor: Defines where the anchor point is for the offsets.
45  // Specified as a 2 character string, "xy"
46  // x can be 'l', 'c', or 'r' for left, center, right respectively <br />
47  // y can be 't', 'c', or 'b' for top, center, bottom respectively <br />
48  virtual void ioParam_offsetAnchor(enum ParamsIOFlag ioFlag);
49 
50  // autoResizeFlag: Whether to scale the image to fit layer dimensions
51  virtual void ioParam_autoResizeFlag(enum ParamsIOFlag ioFlag);
52 
53  // aspectRatioAdjustment: either "crop" or "pad"
54  virtual void ioParam_aspectRatioAdjustment(enum ParamsIOFlag ioFlag);
55 
56  // interpolationMethod: either "bicubic" or "nearestNeighbor".
57  virtual void ioParam_interpolationMethod(enum ParamsIOFlag ioFlag);
58 
59  // inverseFlag: If set to true, inverts the input: pixels are mapped linearly
60  // so that the max pixel value is mapped to the min and vice versa.
61  virtual void ioParam_inverseFlag(enum ParamsIOFlag ioFlag);
62 
63  // normalizeLuminanceFlag: If set to true, will normalize the image.
64  // The normalization method is determined by the normalizeStdDev parameter.
65  virtual void ioParam_normalizeLuminanceFlag(enum ParamsIOFlag ioFlag);
66 
67  // normalizeStdDev: This flag is used if normalizeLuminanceFlag is true.
68  // If normalizeStdDev is set to true, the image will normalize with a mean of 0 and std of 1
69  // If normalizeStdDev is set to false, the image will normalize with a min of 0 and a max of 1
70  // If all pixels are equal, the image will normalize so that all pixels are zero.
71  virtual void ioParam_normalizeStdDev(enum ParamsIOFlag ioFlag);
72 
73  // padValue: If the image is being padded (image smaller than layer), the value to use for
74  // padding
75  virtual void ioParam_padValue(enum ParamsIOFlag ioFlag);
76 
77  // initVType: InputLayers do not have a V, do not set
78  virtual void ioParam_InitVType(enum ParamsIOFlag ioFlag) override;
79 
80  // triggerLayerName: InputLayer and derived classes do not use triggering, and always set
81  // triggerLayerName to NULL.
82  virtual void ioParam_triggerLayerName(enum ParamsIOFlag ioFlag) override;
83 
84  // displayPeriod: the number of timesteps each input is displayed before switching to the next.
85  // If this is <= 0 or inputPath does not end in .txt, assumes the input is a single file and will
86  // not change.
87  virtual void ioParam_displayPeriod(enum ParamsIOFlag ioFlag);
88 
89  // start_frame_index: Array specifying the file indices to start at.
90  // If displayPeriod <= 0, this determines which index from the file list will be used.
91  virtual void ioParam_start_frame_index(enum ParamsIOFlag ioFlag);
92 
93  // skip_frame_index: Array specifying how much to increment the file index by each displayPeriod
94  // for each batch
95  virtual void ioParam_skip_frame_index(enum ParamsIOFlag ioFlag);
96 
97  // writeFrameToTimestamp: if true, then every time the frame is updated, it writes the frame
98  // number,
99  // the time and the image filename to a file. The file is placed in a directory "timestamps" in
100  // the outputPath
101  // directory, and the filename is the layer name appended with ".txt".
102  virtual void ioParam_writeFrameToTimestamp(enum ParamsIOFlag ioFlag);
103 
104  // resetToStartOnLoop: If false, then when the end of file for the inputPath file is reached,
105  // it rewinds to index 0. Otherwise, it rewinds to the index it began at (possibly
106  // start_frame_index).
107  virtual void ioParam_resetToStartOnLoop(enum ParamsIOFlag ioFlag);
108 
109  // batchMethod: Specifies how to split the file for batches.
110  // byFile: Each batch skips nbatch, and starts staggered from the beginning of the file list
111  // byList: Each batch skips 1, and starts at index = numFrames/numBatch
112  // bySpecified: User specified start_frame_index and skip_frame_index, one for each batch
113  // random: Randomizes the order of the given file. Does not duplicate indices until all are used
114  virtual void ioParam_batchMethod(enum ParamsIOFlag ioFlag);
115 
116  // Random seed used when batchMethod == random.
117  virtual void ioParam_randomSeed(enum ParamsIOFlag ioFlag);
118 
119  // useInputBCFlag: Specifies if the input should be scaled to fill margins
120  virtual void ioParam_useInputBCflag(enum ParamsIOFlag ioFlag);
121 
122  protected:
123  InputLayer() {}
124 
129  int scatterInput(int localBatchIndex, int mpiBatchIndex);
130  int initialize(const char *name, HyPerCol *hc);
131 
132  // Returns PV_SUCCESS if offsetAnchor is a valid anchor string, PV_FAILURE otherwise.
133  // (two characters long; first characters one of 't', 'c', or 'b'; second characters one of 'l',
134  // 'c', or 'r')
135  int checkValidAnchorString(const char *offsetAnchor);
136 
143  virtual void normalizePixels(int batchElement);
144  virtual void allocateV() override;
145  virtual void initializeV() override;
146  virtual void initializeActivity() override;
147  virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override;
148  virtual Response::Status registerData(Checkpointer *checkpointer) override;
149  virtual Response::Status readStateFromCheckpoint(Checkpointer *checkpointer) override;
150  virtual double getDeltaUpdateTime() override;
151 
152  // Method that signals when to load the next file.
153  // Can be overridden for different file list logic in subclasses.
154  virtual bool readyForNextFile();
155 
160  virtual int countInputImages() = 0;
161 
168  virtual Buffer<float> retrieveData(int inputIndex) = 0;
169 
174  void retrieveInput(double timef, double dt);
175 
180  void retrieveInputAndAdvanceIndex(double timef, double dt);
181  void initializeBatchIndexer();
182 
183  public:
184  InputLayer(const char *name, HyPerCol *hc);
185  virtual ~InputLayer();
186 
187  virtual int requireChannel(int channelNeeded, int *numChannelsResult) override;
188  void makeInputRegionsPointer() { mNeedInputRegionsPointer = true; }
189  virtual Response::Status allocateDataStructures() override;
190  virtual Response::Status updateState(double time, double dt) override;
191 
201  virtual std::string describeInput(int index) { return std::string(""); }
202  virtual bool activityIsSpiking() override { return false; }
203  int getDisplayPeriod() { return mDisplayPeriod; }
204  int getStartIndex(int batchIndex) { return mStartFrameIndex.at(batchIndex); }
205  int getSkipIndex(int batchIndex) { return mSkipFrameIndex.at(batchIndex); }
206  const std::string &getInputPath() const { return mInputPath; }
207 
216  virtual std::string const &getCurrentFilename(int localBatchElement, int mpiBatchIndex) const {
217  return mInputPath;
218  }
219 
220  float *getInputRegionsAllBatchElements() { return mInputRegionsAllBatchElements.data(); }
221 
222  private:
228  void fitBufferToGlobalLayer(Buffer<float> &buffer, int blockBatchElement);
229 
230  void cropToMPIBlock(Buffer<float> &buffer);
231 
232  protected:
233  // If mAutoResizeFlag is enabled, do we crop the edges or pad the edges with mPadValue?
234  BufferUtils::RescaleMethod mRescaleMethod;
235 
236  // If mAutoResizeFlag is enabled, do we rescale with bicubic or nearest neighbor filtering?
237  BufferUtils::InterpolationMethod mInterpolationMethod = BufferUtils::BICUBIC;
238 
239  // When cropping or resizing, which side of the canvas is the origin?
241 
242  // Flag that enables rescaling input buffer to layer dimensions instead of just cropping
243  bool mAutoResizeFlag = false;
244 
245  // Flag that inverts input buffer during post process step
246  bool mInverseFlag = false;
247 
248  // Flag that enables scaling input buffer to extended region instead of restricted region
249  bool mUseInputBCflag = false;
250 
251  // Flag enabling normalization in the post process step
252  bool mNormalizeLuminanceFlag = false;
253 
254  // If true and normalizeLuminanceFlag == true, normalize the standard deviation to 1 and mean = 0
255  // If false and normalizeLuminanceFlag == true, nomalize max = 1, min = 0
256  bool mNormalizeStdDev = true;
257 
258  // Amount to translate input buffer before scattering but after rescaling
259  int mOffsetX = 0;
260  int mOffsetY = 0;
261 
262  // If nonzero, create a sample by shifting image randomly in [-maxRandomShiftX, maxRandomShiftX]
263  // x [-maxRandomShiftY, maxRandomShiftY]
264  int mMaxShiftX = 0;
265  int mMaxShiftY = 0;
266  // How often to change random shifts (measured in displayPeriods)
267  int mJitterChangeInterval = 1;
268 
269  // Are horizontal or vertical mirror flips enabled during the augmentation stage?
270  bool mXFlipEnabled = false;
271  bool mYFlipEnabled = false;
272 
273  // If this is true, toggle mirror flips each time instead of randomly selecting
274  bool mXFlipToggle = false;
275  bool mYFlipToggle = false;
276 
277  // Random seed used when batchMethod == random
278  int mRandomSeed = 123456789;
279 
280  // Object to handle assigning file indices to batch element
281  std::unique_ptr<BatchIndexer> mBatchIndexer;
282  BatchIndexer::BatchMethod mBatchMethod;
283 
284  private:
285  // Data read from disk, one per batch element.
286  std::vector<Buffer<float>> mInputData;
287 
288  // The parts of the mInputData buffers occupied by image data, as opposed to gaps created by
289  // offsets or resizing with padding. When mInputData[b] is first filled using retrieveData,
290  // mInputRegion[b] is created as a buffer of the same size filled with ones.
291  // As operations that translate or resize are applied to mInputData[b], the same operation is
292  // applied to mInputRegion[b]. When normalizePixels() normalizes or scatterInput() copies to the
293  // clayer activity, only those pixels where mInputRegion[b] is nonzero are used.
294  std::vector<Buffer<float>> mInputRegion;
295 
296  bool mNeedInputRegionsPointer = false;
297 
298  // A vector containing the contents of the mInputRegion buffers, allocated as a single array
299  // of size getNumExtendedAllBatches.
300  // Will not be allocated unless the makeInputRegionsPointer() method is called before the
301  // AllocateData stage.
302  std::vector<float> mInputRegionsAllBatchElements;
303 
304  // BorderExchange object for boundary exchange
305  BorderExchange *mBorderExchanger = nullptr;
306 
307  // Value to fill empty region with when using padding
308  float mPadValue = 0.0f;
309 
310  // Path to input file or list of input files
311  std::string mInputPath;
312 
313  // Filepointer to output file used when mWriteFrameToTimestamp == true
314  CheckpointableFileStream *mTimestampStream = nullptr;
315 
316  // Number of timesteps an input file is displayed before advancing the file list. If <= 0, the
317  // file never changes.
318  int mDisplayPeriod = 0;
319 
320  // When reaching the end of the file list, do we reset to 0 or to start_index?
321  // This parameter is read only if using batchMethod=bySpecified
322  bool mResetToStartOnLoop = false;
323 
324  // Flag to write filenames and batch indices to disk as they are loaded
325  bool mWriteFrameToTimestamp = true;
326 
327  // An array of starting file list indices, one per batch
328  std::vector<int> mStartFrameIndex;
329 
330  // An array indicating how far to advance each index, one per batch
331  std::vector<int> mSkipFrameIndex;
332 
333  // Random number generator for jitter
334  std::mt19937 mRNG;
335  // An array of random shifts in x direction, one per batch
336  std::vector<int> mRandomShiftX;
337  // An array of random shifts in y direction, one per batch
338  std::vector<int> mRandomShiftY;
339  // Same for mirror flips
340  std::vector<bool> mMirrorFlipX;
341  std::vector<bool> mMirrorFlipY;
342 };
343 
344 } // end namespace PV
345 
346 #endif
virtual Buffer< float > retrieveData(int inputIndex)=0
void fitBufferToGlobalLayer(Buffer< float > &buffer, int blockBatchElement)
Definition: InputLayer.cpp:244
int scatterInput(int localBatchIndex, int mpiBatchIndex)
Definition: InputLayer.cpp:159
virtual std::string const & getCurrentFilename(int localBatchElement, int mpiBatchIndex) const
Definition: InputLayer.hpp:216
void retrieveInputAndAdvanceIndex(double timef, double dt)
Definition: InputLayer.cpp:149
virtual double getDeltaUpdateTime() override
Definition: InputLayer.cpp:406
virtual void normalizePixels(int batchElement)
Definition: InputLayer.cpp:279
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: InputLayer.cpp:424
virtual void ioParam_triggerLayerName(enum ParamsIOFlag ioFlag) override
triggerLayerName: Specifies the name of the layer that this layer triggers off of. If set to NULL or the empty string, the layer does not trigger but updates its state on every timestep.
Definition: InputLayer.cpp:758
virtual std::string describeInput(int index)
Definition: InputLayer.hpp:201
virtual void ioParam_InitVType(enum ParamsIOFlag ioFlag) override
initVType: Specifies how to initialize the V buffer.
Definition: InputLayer.cpp:753
virtual int countInputImages()=0
void retrieveInput(double timef, double dt)
Definition: InputLayer.cpp:99