// Copyright 2013 Yangqing Jia

package caffe;

message BlobProto {
  optional int32 num = 1 [default = 0];
  optional int32 channels = 2 [default = 0];
  optional int32 height = 3 [default = 0];
  optional int32 width = 4 [default = 0];
  repeated float data = 5 [packed=true];
  repeated float diff = 6 [packed=true];
}

// The BlobProtoVector is simply a way to pass multiple blobproto instances
// around.
message BlobProtoVector {
  repeated BlobProto blobs = 1;
}

message Datum {
  optional int32 channels = 1;
  optional int32 height = 2;
  optional int32 width = 3;
  // the actual image data, in bytes
  optional bytes data = 4;
  optional int32 label = 5;
  // Optionally, the datum could also hold float data.
  repeated float float_data = 6;
}

message FillerParameter {
  // The filler type.
  optional string type = 1 [default = 'constant'];
  optional float value = 2 [default = 0]; // the value in constant filler
  optional float min = 3 [default = 0]; // the min value in uniform filler
  optional float max = 4 [default = 1]; // the max value in uniform filler
  optional float mean = 5 [default = 0]; // the mean value in gaussian filler
  optional float std = 6 [default = 1]; // the std value in gaussian filler
  optional string model_path = 7;
  optional string model_layer_name = 8;
}

message LayerParameter {
  optional string name = 1; // the layer name
  optional string type = 2; // the string to specify the layer type

  // Parameters to specify layers with inner products.
  optional uint32 num_output = 3; // The number of outputs for the layer
  optional bool biasterm = 4 [default = true]; // whether to have bias terms
  optional FillerParameter weight_filler = 5; // The filler for the weight
  optional FillerParameter bias_filler = 6; // The filler for the bias

  optional uint32 pad = 7 [default = 0]; // The padding size
  optional uint32 kernelsize = 8; // The kernel size
  optional uint32 group = 9 [default = 1]; // The group size for group conv
  optional uint32 stride = 10 [default = 1]; // The stride
  enum PoolMethod {
    MAX = 0;
    AVE = 1;
    STOCHASTIC = 2;
  }
  optional PoolMethod pool = 11 [default = MAX]; // The pooling method
  optional float dropout_ratio = 12 [default = 0.5]; // dropout ratio

  // LOCAL RESPONSE NORMALISATION LAYER [Krizhevsky et al., NIPS 2012]
  
  optional uint32 local_size = 13 [default = 5]; 
  
  // in caffe, alpha is normalised by local_size; in cuda-convnet, it's not
  optional float alpha = 14 [default = 1.]; 
  optional float beta = 15 [default = 0.75];
  optional float k = 116 [default = 1];

  // DATA LAYER
  
  // data source
  optional string source = 16;
  
  // root image dir
  optional string root_img_dir = 117;
  
  // For data pre-processing, we can do simple scaling and subtracting the
  // data mean, if provided. Note that the mean subtraction is always carried
  // out before scaling.
  optional float scale = 17 [ default = 1 ];
  
  // if specified, this image is subtracted from the *whole input image* prior to cropping (i.e. all input images must have the same size)
  optional string meanfile = 18;
  
  // if specified, this image is subtracted from *each cropped image*
  optional string crop_meanfile = 119;
  
  // batch size.
  optional uint32 batchsize = 19;
  
  // specify if we would like to randomly crop an image.
  optional uint32 cropsize = 20 [default = 0];
  
  // specify if we want to randomly mirror data.
  optional bool mirror = 21 [default = false];
  
  // image augmentation type
  optional uint32 img_aug_type = 22;
  
  // image sampling type
  optional uint32 img_sampling_type = 23;
  
  // ACCURACY LAYER
  repeated uint32 top_k = 31;
  
  // WEIGHT DATA LAYER
  
  // label to visualise
  optional int32 vis_label = 24;
  
  // number of channels in the input image to be generated
  optional int32 channels = 25;
  optional string save_dir = 26;
  
  // LOSS LAYER
  
  // 0 if GT labels should be used
  optional uint32 label_rank = 30 [default = 0];
  
  // margin for the hinge loss
  optional float margin = 32 [default = 1];
  
  // LEARNING DATA

  // The blobs containing the numeric parameters of the layer
  repeated BlobProto blobs = 50;
  // The ratio that is multiplied on the global learning rate. If you want to set
  // the learning ratio for one blob, you need to set it for all blobs.
  repeated float blobs_lr = 51;
  // The weight decay that is multiplied on the global weight decay.
  repeated float weight_decay = 52;

  // The rand_skip variable is for the data layer to skip a few data points
  // to avoid all asynchronous sgd clients to start at the same point. The skip
  // point would be set as rand_skip * rand(0,1). Note that rand_skip should not
  // be larger than the number of keys in the leveldb.
  optional uint32 rand_skip = 53 [ default = 0 ];
}

// describes a connection between a layer, a set of input blobs, and a set of output blobs
message LayerConnection {
  optional LayerParameter layer = 1; // the layer parameter
  repeated string bottom = 2; // the name of the bottom blobs
  repeated string top = 3; // the name of the top blobs
}

message NetParameter {
  optional string name = 1; // consider giving the network a name
  repeated LayerConnection layers = 2; // a bunch of layers.
  
  // The input blobs to the network.
  repeated string input = 3;
  
  // The dim of the input blobs. For each input blob there should be four
  // values specifying the num, channels, height and width of the input blob.
  // Thus, there should be a total of (4 * #input) numbers.
  repeated int32 input_dim = 4;
  
  // Whether the network will force every layer to carry out backward operation.
  // If set False, then whether to carry out backward is determined
  // automatically according to the net structure and learning rates.
  optional bool force_backward = 5 [ default = false ];
}

message SolverParameter {
  optional string train_net = 1; // The proto file for the training net.
  optional string test_net = 2; // The proto file for the testing net.
  // The number of iterations for each testing phase.
  optional int32 test_iter = 3 [ default = 0 ];
  // The number of iterations between two testing phases.
  optional int32 test_interval = 4 [ default = 0 ];
  optional float base_lr = 5; // The base learning rate
  // the number of iterations between displaying info. If display = 0, no info
  // will be displayed.
  optional int32 display = 6;
  optional int32 max_iter = 7; // the maximum number of iterations
  optional string lr_policy = 8; // The learning rate decay policy.
  optional float gamma = 9; // The parameter to compute the learning rate.
  optional float power = 10; // The parameter to compute the learning rate.
  optional float momentum = 11; // The momentum value.
  optional float weight_decay = 12; // The weight decay.
  optional int32 stepsize = 13; // the stepsize for learning rate policy "step"
  repeated int32 breakpoint = 22; // defines the schedule: iterations when lr is divided by 10
  
  // SNAPSHOT
  optional int32 snapshot = 14 [default = 0]; // The snapshot interval
  optional string snapshot_prefix = 15; // The prefix for the snapshot.
  optional int32 snapshot_history_length = 18 [default = 0]; // the number of then most recent snapshots to keep - everything older is deleted
  
  // whether to snapshot diff in the results or not. Snapshotting diff will help
  // debugging but the final protocol buffer size will be much larger.
  optional bool snapshot_diff = 16 [ default = false];
  
  // solver backend type: 0 for CPU and 1 for CUDA
  optional int32 solver_mode = 17 [default = 1];
  
  // SGD batch size (should be a multiple of the data provider batch size)
  optional int32 batchsize = 19;
  
  optional int32 display_debug = 20 [default = 0]; // the number of iterations between displaying debug info
  
  // true iff momentum etc. should be loaded
  optional bool load_solver_state = 21 [default = true];
}

// message storing performance measures on the validation set at a particular point
message EvalHistoryIter
{
  optional int32 iter = 1; // the current iteration
  repeated float perf = 2; // vector of performance measures  
}

message EvalHistory
{
  repeated EvalHistoryIter measurements = 1; // performance measurements
}

// A message that stores the solver snapshots
message SolverState {
  optional int32 iter = 1; // The current iteration
  optional string learned_net = 2; // The file that stores the learned net.
  repeated BlobProto history = 3; // The history for sgd solvers
  optional EvalHistory val_history = 4; // The history or validation set performance (might not coincide with the snapshots)
}
