void Net::InitLayers(const mxArray *mx_layers) { //mexPrintMsg("Start layers initialization..."); std::srand((unsigned) std::time(0)); size_t layers_num = mexGetNumel(mx_layers); mexAssert(layers_num >= 2, "The net must contain at least 2 layers"); const mxArray *mx_layer = mexGetCell(mx_layers, 0); std::string layer_type = mexGetString(mexGetField(mx_layer, "type")); mexAssert(layer_type == "i", "The first layer must be the type of 'i'"); layers_.resize(layers_num); layers_[0] = new LayerInput(); //mexPrintMsg("Initializing layer of type", layer_type); layers_.front()->Init(mx_layer, NULL); for (size_t i = 1; i < layers_num; ++i) { Layer *prev_layer = layers_[i-1]; mx_layer = mexGetCell(mx_layers, i); layer_type = mexGetString(mexGetField(mx_layer, "type")); if (layer_type == "c") { layers_[i] = new LayerConv(); } else if (layer_type == "s") { layers_[i] = new LayerScal(); } else if (layer_type == "f") { layers_[i] = new LayerFull(); } else { mexAssert(false, layer_type + " - unknown type of the layer"); } //mexPrintMsg("Initializing layer of type", layer_type); layers_[i]->Init(mx_layer, prev_layer); } mexAssert(layer_type == "f", "The last layer must be the type of 'f'"); //mexPrintMsg("Layers initialization finished"); }
void LayerFull::Init(const mxArray *mx_layer, Layer *prev_layer) { mexAssert(mexIsField(mx_layer, "length"), "The 'f' type layer must contain the 'length' field"); ftype length = mexGetScalar(mexGetField(mx_layer, "length")); mexAssert(1 <= length, "Length on the 'f' layer must be greater or equal to 1"); length_ = (size_t) length; mapsize_.assign(prev_layer->numdim_, 0); length_prev_ = prev_layer->length_; if (mexIsField(mx_layer, "function")) { function_ = mexGetString(mexGetField(mx_layer, "function")); mexAssert(function_ == "soft" || function_ == "sigm" || function_ == "relu", "Unknown function for the 'f' layer"); } if (mexIsField(mx_layer, "dropout")) { dropout_ = mexGetScalar(mexGetField(mx_layer, "dropout")); mexAssert(0 <= dropout_ && dropout_ < 1, "Dropout must be in the range [0, 1)"); } if (mexIsField(mx_layer, "initstd")) { init_std_ = mexGetScalar(mexGetField(mx_layer, "initstd")); mexAssert(0 <= init_std_, "initstd must be non-negative"); } if (mexIsField(mx_layer, "biascoef")) { bias_coef_ = mexGetScalar(mexGetField(mx_layer, "biascoef")); mexAssert(0 <= bias_coef_, "biascoef must be non-negative"); } }
void LayerScal::Init(const mxArray *mx_layer, Layer *prev_layer) { mexAssert(prev_layer->type_ != "f", "The 's' type layer cannot be after 'f' type layer"); mexAssert(mexIsField(mx_layer, "scale"), "The 's' type layer must contain the 'scale' field"); mapsize_.resize(prev_layer->mapsize_.size()); std::vector<double> scale = mexGetVector(mexGetField(mx_layer, "scale")); mexAssert(scale.size() == mapsize_.size(), "Length of scale vector and maps dimensionality must coincide"); scale_.resize(scale.size()); for (size_t i = 0; i < mapsize_.size(); ++i) { scale_[i] = (size_t) scale[i]; mexAssert(1 <= scale_[i], "Scale size on the 's' layer must be greater or equal to 1"); mapsize_[i] = ceil((double) prev_layer->mapsize_[i] / scale_[i]); } outputmaps_ = prev_layer->outputmaps_; if (!mexIsField(mx_layer, "function")) { function_ = "mean"; } else { function_ = mexGetString(mexGetField(mx_layer, "function")); } std::string errmsg = function_ + " - unknown function for the layer"; mexAssert(function_ == "max" || function_ == "mean", errmsg); activ_.resize(outputmaps_); deriv_.resize(outputmaps_); }
void Net::InitLayers(const mxArray *mx_layers) { //mexPrintMsg("Start layers initialization..."); size_t layers_num = mexGetNumel(mx_layers); mexAssert(layers_num >= 2, "The net must contain at least 2 layers"); const mxArray *mx_layer = mexGetCell(mx_layers, 0); std::string layer_type = mexGetString(mexGetField(mx_layer, "type")); mexAssert(layer_type == "i", "The first layer must be the type of 'i'"); layers_.resize(layers_num); layers_[0] = new LayerInput(); //mexPrintMsg("Initializing layer of type", layer_type); layers_[0]->Init(mx_layer, NULL); for (size_t i = 1; i < layers_num; ++i) { Layer *prev_layer = layers_[i-1]; mx_layer = mexGetCell(mx_layers, i); layer_type = mexGetString(mexGetField(mx_layer, "type")); if (layer_type == "j") { layers_[i] = new LayerJitt(); } else if (layer_type == "n") { layers_[i] = new LayerNorm(); } else if (layer_type == "c") { layers_[i] = new LayerConv(); } else if (layer_type == "s") { layers_[i] = new LayerScal(); } else if (layer_type == "t") { layers_[i] = new LayerTrim(); } else if (layer_type == "f") { layers_[i] = new LayerFull(); } else { mexAssert(false, layer_type + " - unknown type of the layer"); } //mexPrintMsg("Initializing layer of type", layer_type); layers_[i]->Init(mx_layer, prev_layer); } mexAssert(layer_type == "f", "The last layer must be the type of 'f'"); mexAssert(layers_.back()->function_ == "soft" || layers_.back()->function_ == "sigm" || layers_.back()->function_ == "SVM", "The last layer function must be 'soft', 'sigm' or 'SVM'"); //mexPrintMsg("Layers initialization finished"); }
void Net::InitLayers(const mxArray *mx_layers) { //mexPrintMsg("Start layers initialization..."); size_t layers_num = mexGetNumel(mx_layers); mexAssert(layers_num >= 2, "The net must contain at least 2 layers"); const mxArray *mx_layer = mexGetCell(mx_layers, 0); std::string layer_type = mexGetString(mexGetField(mx_layer, "type")); mexAssert(layer_type == "i", "The first layer must be the type of 'i'"); layers_.resize(layers_num); layers_[0] = new LayerInput(); //mexPrintMsg("Initializing layer of type", layer_type); layers_[0]->Init(mx_layer, NULL); for (size_t i = 1; i < layers_num; ++i) { Layer *prev_layer = layers_[i-1]; mx_layer = mexGetCell(mx_layers, i); layer_type = mexGetString(mexGetField(mx_layer, "type")); if (layer_type == "j") { layers_[i] = new LayerJitt(); } else if (layer_type == "c") { layers_[i] = new LayerConv(); } else if (layer_type == "s") { layers_[i] = new LayerScal(); } else if (layer_type == "f") { layers_[i] = new LayerFull(); } else { mexAssert(false, layer_type + " - unknown type of the layer"); } //mexPrintMsg("Initializing layer of type", layer_type); layers_[i]->Init(mx_layer, prev_layer); mexAssert(layers_[i]->function_ != "soft" || i == layers_num - 1, "Softmax function may be only on the last layer"); } mexAssert(layer_type == "f", "The last layer must be the type of 'f'"); LayerFull *lastlayer = static_cast<LayerFull*>(layers_.back()); mexAssert(lastlayer->function_ == "soft" || lastlayer->function_ == "sigm", "The last layer function must be either 'soft' or 'sigm'"); mexAssert(lastlayer->dropout_ == 0, "The last layer dropout must be 0"); //mexPrintMsg("Layers initialization finished"); }
void LayerConv::Init(const mxArray *mx_layer, Layer *prev_layer) { mexAssert(prev_layer->type_ != "f", "The 'c' type layer cannot be after 'f' type layer"); numdim_ = prev_layer->numdim_; length_prev_ = prev_layer->outputmaps_; mexAssert(mexIsField(mx_layer, "outputmaps"), "The 'c' type layer must contain the 'outputmaps' field"); ftype outputmaps = mexGetScalar(mexGetField(mx_layer, "outputmaps")); mexAssert(1 <= outputmaps, "Outputmaps on the 'i' layer must be greater or equal to 1"); outputmaps_ = (size_t) outputmaps; if (mexIsField(mx_layer, "function")) { function_ = mexGetString(mexGetField(mx_layer, "function")); mexAssert(function_ == "relu" || function_ == "sigm", "Unknown function for the 'c' layer"); } mexAssert(mexIsField(mx_layer, "filtersize"), "The 'c' type layer must contain the 'filtersize' field"); std::vector<ftype> filtersize = mexGetVector(mexGetField(mx_layer, "filtersize")); mexAssert(filtersize.size() == numdim_, "Filters and maps must be the same dimensionality"); filtersize_.resize(numdim_); for (size_t i = 0; i < numdim_; ++i) { mexAssert(1 <= filtersize[i], "Filtersize on the 'c' layer must be positive"); filtersize_[i] = (size_t) filtersize[i]; } #if COMP_REGIME == 2 // GPU mexAssert(filtersize_[0] == filtersize_[1], "In the GPU version the filtersize should be squared on all layers"); #endif padding_.assign(numdim_, 0); if (mexIsField(mx_layer, "padding")) { std::vector<ftype> padding = mexGetVector(mexGetField(mx_layer, "padding")); mexAssert(padding.size() == numdim_, "Padding vector has the wrong length"); for (size_t i = 0; i < numdim_; ++i) { mexAssert(0 <= padding[i] && padding[i] <= filtersize_[i] - 1, "Padding on the 'c' layer must be in the range [0, filtersize-1]"); padding_[i] = (size_t) padding[i]; } #if COMP_REGIME == 2 // GPU mexAssert(padding_[0] == padding_[1], "In the GPU version the padding should be squared on all layers"); #endif } mapsize_.resize(numdim_); length_ = outputmaps_; size_t minsize_ = prev_layer->mapsize_[0] + 2*padding_[0] - filtersize_[0] + 1; for (size_t i = 0; i < numdim_; ++i) { mapsize_[i] = prev_layer->mapsize_[i] + 2*padding_[i] - filtersize_[i] + 1; mexAssert(1 <= mapsize_[i], "Mapsize on the 'c' layer must be greater than 1"); if (mapsize_[i] < minsize_) minsize_ = mapsize_[i]; length_ *= mapsize_[i]; } if (mexIsField(mx_layer, "sumwidth")) { ftype sum_width = mexGetScalar(mexGetField(mx_layer, "sumwidth")); mexAssert(1 <= sum_width && sum_width <= minsize_, "Sumwidth must be in the range [0, min(mapsize)]"); sum_width_ = (size_t) sum_width; } else { if (sum_width_ > minsize_) sum_width_ = minsize_; } if (mexIsField(mx_layer, "initstd")) { init_std_ = mexGetScalar(mexGetField(mx_layer, "initstd")); mexAssert(0 <= init_std_, "initstd must be non-negative"); } if (mexIsField(mx_layer, "biascoef")) { bias_coef_ = mexGetScalar(mexGetField(mx_layer, "biascoef")); mexAssert(0 <= bias_coef_, "biascoef must be non-negative"); } if (mexIsField(mx_layer, "unshared")) { unshared_ = (mexGetScalar(mexGetField(mx_layer, "unshared")) > 0); if (unshared_) sum_width_ = 1; } }
void Layer::InitGeneral(const mxArray *mx_layer) { type_ = mexGetString(mexGetField(mx_layer, "type")); if (mexIsField(mx_layer, "function")) { function_ = mexGetString(mexGetField(mx_layer, "function")); mexAssertMsg(function_ == "relu" || function_ == "sigm" || function_ == "soft" || function_ == "none", "Unknown function code"); } if (mexIsField(mx_layer, "add_bias")) { // actual value if defined add_bias_ = (mexGetScalar(mexGetField(mx_layer, "add_bias")) > 0); } if (mexIsField(mx_layer, "mapsize")) { std::vector<ftype> mapsize = mexGetVector(mexGetField(mx_layer, "mapsize")); mexAssertMsg(mapsize.size() == 2, "Input mapsize length must be 2"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(1 <= mapsize[i] && mapsize[i] < INT_MAX, "Mapsize must be >= 1"); dims_[i+2] = (int) mapsize[i]; } } if (mexIsField(mx_layer, "channels")) { ftype channels = mexGetScalar(mexGetField(mx_layer, "channels")); mexAssertMsg(1 <= channels && channels < INT_MAX, "Channels num must be >= 1"); dims_[1] = (int) channels; filters_.dims(0) = dims_[1]; if (add_bias_) { // using actual value here biases_.dims() = {1, dims_[1], 1, 1}; } } if (mexIsField(mx_layer, "filtersize")) { std::vector<ftype> filtersize = mexGetVector(mexGetField(mx_layer, "filtersize")); mexAssertMsg(filtersize.size() == 2, "Filtersize must contain 2 values"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(1 <= filtersize[i] && filtersize[i] < INT_MAX, "Filtersize must be >= 1"); filters_.dims(i+2) = (int) filtersize[i]; } } if (mexIsField(mx_layer, "padding")) { std::vector<ftype> padding = mexGetVector(mexGetField(mx_layer, "padding")); mexAssertMsg(padding.size() == 2, "Padding vector must have 2 values"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(0 <= padding[i] && padding[i] < INT_MAX, "Padding must be non-negative"); padding_[i] = (int) padding[i]; } } if (mexIsField(mx_layer, "stride")) { std::vector<ftype> stride = mexGetVector(mexGetField(mx_layer, "stride")); mexAssertMsg(stride.size() == 2, "Stride vector has the wrong length"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(1 <= stride[i] && stride[i] < INT_MAX, "Stride must be >= 1"); stride_[i] = (int) stride[i]; } } if (mexIsField(mx_layer, "init_std")) { init_std_ = mexGetScalar(mexGetField(mx_layer, "init_std")); mexAssertMsg(0 <= init_std_, "init_std must be non-negative"); } if (mexIsField(mx_layer, "bias_coef")) { bias_coef_ = mexGetScalar(mexGetField(mx_layer, "bias_coef")); mexAssertMsg(0 <= bias_coef_, "bias_coef must be non-negative"); } if (mexIsField(mx_layer, "lr_coef")) { lr_coef_ = mexGetScalar(mexGetField(mx_layer, "lr_coef")); mexAssertMsg(0 <= lr_coef_, "lr_coef must be non-negative"); } if (mexIsField(mx_layer, "dropout")) { dropout_ = mexGetScalar(mexGetField(mx_layer, "dropout")); mexAssertMsg(0 <= dropout_ && dropout_ < 1, "dropout must be in the range [0, 1)"); } }