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 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 Params::Init(const mxArray *mx_params) { if (mexIsField(mx_params, "batchsize")) { batchsize_ = (size_t) mexGetScalar(mexGetField(mx_params, "batchsize")); mexAssert(batchsize_ > 0, "Batchsize must be positive"); } if (mexIsField(mx_params, "numepochs")) { numepochs_ = (size_t) mexGetScalar(mexGetField(mx_params, "numepochs")); mexAssert(numepochs_ > 0, "Numepochs must be positive"); } if (mexIsField(mx_params, "alpha")) { alpha_ = mexGetVector(mexGetField(mx_params, "alpha")); mexAssert(alpha_.size() == 1 || alpha_.size() == numepochs_, "Wrong length of the alpha vector"); for (size_t i = 0; i < alpha_.size(); ++i) { mexAssert(alpha_[i] >= 0, "alpha must be nonnegative"); } } if (mexIsField(mx_params, "momentum")) { momentum_ = mexGetVector(mexGetField(mx_params, "momentum")); mexAssert(momentum_.size() == 1 || momentum_.size() == numepochs_, "Wrong length of the momentum vector"); for (size_t i = 0; i < momentum_.size(); ++i) { mexAssert(0 <= momentum_[i] && momentum_[i] < 1, "Momentum is out of range [0, 1)"); } } if (mexIsField(mx_params, "adjustrate")) { adjustrate_ = mexGetScalar(mexGetField(mx_params, "adjustrate")); mexAssert(0 <= adjustrate_, "Adjustrate must be non-negative"); } if (mexIsField(mx_params, "maxcoef")) { maxcoef_ = mexGetScalar(mexGetField(mx_params, "maxcoef")); mexAssert(1 <= maxcoef_ , "Maxcoef must be larger or equal to 1"); mincoef_ = 1 / maxcoef_; } if (mexIsField(mx_params, "balance")) { balance_ = (bool) mexGetScalar(mexGetField(mx_params, "balance")); } if (mexIsField(mx_params, "shuffle")) { shuffle_ = (bool) mexGetScalar(mexGetField(mx_params, "shuffle")); } if (mexIsField(mx_params, "verbose")) { verbose_ = (size_t) mexGetScalar(mexGetField(mx_params, "verbose")); } if (mexIsField(mx_params, "seed")) { seed_ = (size_t) mexGetScalar(mexGetField(mx_params, "seed")); } }
void LayerTrim::Init(const mxArray *mx_layer, Layer *prev_layer) { mexAssert(prev_layer->type_ != "f", "The 't' type layer cannot be after 'f' type layer"); numdim_ = prev_layer->numdim_; outputmaps_ = prev_layer->outputmaps_; length_prev_ = prev_layer->outputmaps_; mexAssert(mexIsField(mx_layer, "mapsize"), "The 't' type layer must contain the 'mapsize' field"); std::vector<ftype> mapsize = mexGetVector(mexGetField(mx_layer, "mapsize")); mexAssert(mapsize.size() == numdim_, "Length of the trim vector and maps dimensionality must coincide"); mapsize_.resize(numdim_); length_ = outputmaps_; for (size_t i = 0; i < numdim_; ++i) { mexAssert(mapsize[i] <= prev_layer->mapsize_[i], "In 't' layer new mapsize cannot be larger than the old one"); mapsize_[i] = (size_t) mapsize[i]; length_ *= mapsize_[i]; } }
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 LayerJitt::Init(const mxArray *mx_layer, Layer *prev_layer) { //mexAssert(prev_layer->type_ == "i", "The 'j' type layer must be after the input one"); numdim_ = prev_layer->numdim_; outputmaps_ = prev_layer->outputmaps_; length_prev_ = prev_layer->length_prev_; mexAssert(mexIsField(mx_layer, "mapsize"), "The 'j' type layer must contain the 'mapsize' field"); std::vector<ftype> mapsize = mexGetVector(mexGetField(mx_layer, "mapsize")); mexAssert(mapsize.size() == numdim_, "Length of jitter mapsize vector and maps dimensionality must coincide"); mapsize_.resize(numdim_); length_ = outputmaps_; for (size_t i = 0; i < numdim_; ++i) { mexAssert(1 <= mapsize[i], "In 'j' layer mapsize must be positive"); mapsize_[i] = (size_t) mapsize[i]; length_ *= mapsize_[i]; } shift_.assign(numdim_, 0); if (mexIsField(mx_layer, "shift")) { shift_ = mexGetVector(mexGetField(mx_layer, "shift")); mexAssert(shift_.size() == numdim_, "Length of jitter shift vector and maps dimensionality must coincide"); for (size_t i = 0; i < numdim_; ++i) { mexAssert(0 <= shift_[i] && shift_[i] < mapsize_[i], "Shift in 'j' layer is out of range"); } } scale_.assign(numdim_, 1); if (mexIsField(mx_layer, "scale")) { scale_ = mexGetVector(mexGetField(mx_layer, "scale")); mexAssert(scale_.size() == numdim_, "Length of jitter scale vector and maps dimensionality must coincide"); for (size_t i = 0; i < numdim_; ++i) { mexAssert(1 <= scale_[i] && scale_[i] < mapsize_[i], "Scale in 'j' layer is out of range"); } } mirror_.assign(numdim_, false); if (mexIsField(mx_layer, "mirror")) { std::vector<ftype> mirror = mexGetVector(mexGetField(mx_layer, "mirror")); mexAssert(mirror.size() == numdim_, "Length of jitter scale vector and maps dimensionality must coincide"); for (size_t i = 0; i < numdim_; ++i) { mirror_[i] = (mirror[i] > 0); } } angle_ = 0; if (mexIsField(mx_layer, "angle")) { angle_ = mexGetScalar(mexGetField(mx_layer, "angle")); mexAssert(0 <= angle_ && angle_ <= 1, "Angle in 'j' layer must be between 0 and 1"); } defval_ = 0; if (mexIsField(mx_layer, "defval")) { defval_ = mexGetScalar(mexGetField(mx_layer, "defval")); } else { // check that the transformed image is always inside the original one std::vector<ftype> maxsize(numdim_, 0); for (size_t i = 0; i < numdim_; ++i) { maxsize[i] = (ftype) (mapsize_[i] - 1) * scale_[i]; } if (angle_ > 0) { ftype angle_inn = atan2((ftype) mapsize_[0], (ftype) mapsize_[1]) / kPi; ftype maxsin = 1; if (angle_inn + angle_ < 0.5) { maxsin = sin(kPi * (angle_inn + angle_)); } ftype maxcos = 1; if (angle_inn > angle_) { maxcos = cos(kPi * (angle_inn - angle_)); } ftype maxrad = sqrt(maxsize[0]*maxsize[0] + maxsize[1]*maxsize[1]); maxsize[0] = maxrad * maxsin; maxsize[1] = maxrad * maxcos; } std::vector<ftype> oldmapsize(numdim_, 0); for (size_t i = 0; i < numdim_; ++i) { oldmapsize[i] = (ftype) prev_layer->mapsize_[i]; } ftype min0 = (oldmapsize[0]/2 - 0.5) - maxsize[0]/2 - shift_[0]; ftype max0 = (oldmapsize[0]/2 - 0.5) + maxsize[0]/2 + shift_[0]; ftype min1 = (oldmapsize[1]/2 - 0.5) - maxsize[1]/2 - shift_[1]; ftype max1 = (oldmapsize[1]/2 - 0.5) + maxsize[1]/2 + shift_[1]; if (!(0 <= min0 && max0 < oldmapsize[0] && 0 <= min1 && max1 < oldmapsize[1])) { mexPrintMsg("min1", min0); mexPrintMsg("max1", max0); mexPrintMsg("min2", min1); mexPrintMsg("max2", max1); mexAssert(false, "For these jitter parameters the new image is out of the original image"); } } }
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)"); } }
void LayerFull::Init(const mxArray *mx_layer, const Layer *prev_layer) { mexAssertMsg(mexIsField(mx_layer, "channels"), "The 'full' type layer must contain the 'channels' field"); filters_.dims(1) = prev_layer->length(); }
void LayerJitt::Init(const mxArray *mx_layer, const Layer *prev_layer) { dims_[1] = prev_layer->dims_[1]; std::vector<ftype> shift(2); shift[0] = 0; shift[1] = 0; if (mexIsField(mx_layer, "shift")) { shift = mexGetVector(mexGetField(mx_layer, "shift")); mexAssertMsg(shift.size() == 2, "Length of jitter shift vector and maps dimensionality must coincide"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(0 <= shift[i] && shift[i] < dims_[i+2], "Shift in 'jitt' layer is out of range"); } MatCPU shift_cpu(1, 2); shift_cpu.assign(shift); shift_ = shift_cpu; } std::vector<ftype> scale(2); scale[0] = 1; scale[1] = 1; if (mexIsField(mx_layer, "scale")) { scale = mexGetVector(mexGetField(mx_layer, "scale")); mexAssertMsg(scale.size() == 2, "Length of jitter scale vector and maps dimensionality must coincide"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(1 <= scale[i] && scale[i] < dims_[i+2], "Scale in 'j' layer is out of range"); } MatCPU scale_cpu(1, 2); scale_cpu.assign(scale); scale_ = scale_cpu; scale_.Log(); } if (mexIsField(mx_layer, "mirror")) { std::vector<ftype> mirror = mexGetVector(mexGetField(mx_layer, "mirror")); mexAssertMsg(mirror.size() == 2, "Length of jitter scale vector and maps dimensionality must coincide"); for (size_t i = 0; i < 2; ++i) { mexAssertMsg(mirror[i] == 0 || mirror[i] == 1, "Mirror must be either 0 or 1"); } MatCPU mirror_cpu(1, 2); mirror_cpu.assign(mirror); mirror_ = mirror_cpu; } if (mexIsField(mx_layer, "angle")) { angle_ = mexGetScalar(mexGetField(mx_layer, "angle")); mexAssertMsg(0 <= angle_ && angle_ <= 1, "Angle in 'j' layer must be between 0 and 1"); } if (mexIsField(mx_layer, "defval")) { defval_ = mexGetScalar(mexGetField(mx_layer, "defval")); } else { // check that the transformed image is always inside the original one std::vector<ftype> maxsize(2, 0); for (size_t i = 0; i < 2; ++i) { maxsize[i] = (ftype) (dims_[i+2] - 1) * scale[i]; } if (angle_ > 0) { ftype angle_inn = atan2((ftype) dims_[2], (ftype) dims_[3]) / kPi; ftype maxsin = 1; if (angle_inn + angle_ < 0.5) { maxsin = sin(kPi * (angle_inn + angle_)); } ftype maxcos = 1; if (angle_inn > angle_) { maxcos = cos(kPi * (angle_inn - angle_)); } ftype maxrad = (ftype) sqrt((double) (maxsize[0]*maxsize[0] + maxsize[1]*maxsize[1])); maxsize[0] = maxrad * maxsin; maxsize[1] = maxrad * maxcos; } std::vector<ftype> oldmapsize(2, 0); for (size_t i = 0; i < 2; ++i) { oldmapsize[i] = (ftype) prev_layer->dims_[i+2]; } ftype min0 = ((ftype) oldmapsize[0] / 2 - (ftype) 0.5) - (ftype) maxsize[0] / 2 - shift[0]; ftype max0 = ((ftype) oldmapsize[0] / 2 - (ftype) 0.5) + (ftype) maxsize[0] / 2 + shift[0]; ftype min1 = ((ftype) oldmapsize[1] / 2 - (ftype) 0.5) - (ftype) maxsize[1] / 2 - shift[1]; ftype max1 = ((ftype) oldmapsize[1] / 2 - (ftype) 0.5) + (ftype) maxsize[1] / 2 + shift[1]; if (!(0 <= min0 && max0 < oldmapsize[0] && 0 <= min1 && max1 < oldmapsize[1])) { mexPrintMsg("min1", min0); mexPrintMsg("max1", max0); mexPrintMsg("min2", min1); mexPrintMsg("max2", max1); mexAssertMsg(false, "For these jitter parameters the new image is out of the original image"); } } if (mexIsField(mx_layer, "eigenvectors")) { const mxArray* mx_ev = mexGetField(mx_layer, "eigenvectors"); std::vector<size_t> ev_dim = mexGetDimensions(mx_ev); mexAssertMsg(ev_dim.size() == 2, "The eigenvectors array must have 2 dimensions"); mexAssertMsg(ev_dim[0] == dims_[1] && ev_dim[1] == dims_[1], "The eigenvector matrix size is wrong"); MatCPU ev_cpu(dims_[1], dims_[1]); mexGetMatrix(mx_ev, ev_cpu); eigenvectors_.resize(dims_[1], dims_[1]); eigenvectors_ = ev_cpu; if (mexIsField(mx_layer, "noise_std")) { noise_std_ = mexGetScalar(mexGetField(mx_layer, "noise_std")); mexAssertMsg(noise_std_ >= 0, "noise_std must be nonnegative"); } else { mexAssertMsg(false, "noise_std is required with eigenvalues"); } } if (mexIsField(mx_layer, "randtest")) { randtest_ = (mexGetScalar(mexGetField(mx_layer, "randtest")) > 0); } }