void convertProtoToLua(void** handle, const char* lua_name, const char* cuda_package) { std::locale::global(std::locale()); const caffe::NetParameter netparam = *(const caffe::NetParameter*)handle[1]; if (netparam.layers_size() > 0) convertProtoToLuaV1(netparam, lua_name, cuda_package); else convertProtoToLuaV2(netparam, lua_name, cuda_package); }
void extractBinaryLayerParms(const caffe::LayerParameter& layer, LayerParams& layerParams) { const std::string &name = layer.name(); int li; for (li = 0; li != netBinary.layer_size(); li++) { if (netBinary.layer(li).name() == name) break; } if (li == netBinary.layer_size() || netBinary.layer(li).blobs_size() == 0) return; const caffe::LayerParameter &binLayer = netBinary.layer(li); layerParams.blobs.resize(binLayer.blobs_size()); for (int bi = 0; bi < binLayer.blobs_size(); bi++) { blobFromProto(binLayer.blobs(bi), layerParams.blobs[bi]); } }
Waifu2x::eWaifu2xError cNet::SetParameter(caffe::NetParameter ¶m, const std::string &process) const { param.mutable_state()->set_phase(caffe::TEST); { auto input_layer = param.mutable_layer(0); auto mid = input_layer->mutable_input_param()->mutable_shape(); if (mid->size() != 1 || mid->Mutable(0)->dim_size() != 4) return Waifu2x::eWaifu2xError_FailedParseModelFile; } for (int i = 0; i < param.layer_size(); i++) { caffe::LayerParameter *layer_param = param.mutable_layer(i); const std::string& type = layer_param->type(); if (type == "Convolution") { if (process == "cudnn") layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CUDNN); else layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CAFFE); } else if (type == "Deconvolution") { if (process == "cudnn") layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CUDNN); else layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CAFFE); } else if (type == "ReLU") { if (process == "cudnn") layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CUDNN); else layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CAFFE); } } return Waifu2x::eWaifu2xError_OK; }
void populateNet(Net dstNet) { CV_TRACE_FUNCTION(); int layersSize = net.layer_size(); layerCounter.clear(); addedBlobs.clear(); addedBlobs.reserve(layersSize + 1); //setup input layer names std::vector<String> netInputs(net.input_size()); { for (int inNum = 0; inNum < net.input_size(); inNum++) { addedBlobs.push_back(BlobNote(net.input(inNum), 0, inNum)); netInputs[inNum] = net.input(inNum); } } for (int li = 0; li < layersSize; li++) { const caffe::LayerParameter &layer = net.layer(li); String name = layer.name(); String type = layer.type(); LayerParams layerParams; extractLayerParams(layer, layerParams); extractBinaryLayerParms(layer, layerParams); int repetitions = layerCounter[name]++; if (repetitions) name += String("_") + toString(repetitions); if (type == "Input") { for (int outNum = 0; outNum < layer.top_size(); outNum++) { addOutput(layer, 0, outNum); addedBlobs.back().outNum = netInputs.size(); netInputs.push_back(addedBlobs.back().name); } continue; } int id = dstNet.addLayer(name, type, layerParams); for (int inNum = 0; inNum < layer.bottom_size(); inNum++) addInput(layer.bottom(inNum), id, inNum, dstNet); for (int outNum = 0; outNum < layer.top_size(); outNum++) addOutput(layer, id, outNum); } dstNet.setInputsNames(netInputs); addedBlobs.clear(); }
void convertProtoToLua(void** handle, const char* lua_name, const char* cuda_package) { const caffe::NetParameter netparam = *(const caffe::NetParameter*)handle[1]; std::ofstream ofs (lua_name); ofs << "require '" << cuda_package << "'\n"; ofs << "require 'cunn'\n"; ofs << "model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; int num_output = netparam.input_dim_size(); for (int i=0; i<netparam.layers_size(); ++i) { std::vector<std::pair<std::string, std::string>> lines; auto& layer = netparam.layers(i); switch(layer.type()) { case caffe::LayerParameter::CONVOLUTION: { auto ¶m = layer.convolution_param(); int groups = param.group() == 0 ? 1 : param.group(); int nInputPlane = layer.blobs(0).channels()*groups; int nOutputPlane = param.num_output(); num_output = nOutputPlane; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } int pad_w = param.pad_w(); int pad_h = param.pad_h(); if(pad_w==0 || pad_h==0) { pad_w = param.pad(); pad_h = pad_w; } if(std::string(cuda_package) == "ccn2") { if(kW != kH || dW != dH || pad_w != pad_h) { std::cout << "ccn2 only supports square images!\n"; break; } char buf[1024]; sprintf(buf, "ccn2.SpatialConvolution(%d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, dW, pad_w, groups); lines.emplace_back(layer.name(), buf); } else { char buf[1024]; const char* mm_or_not = std::string(cuda_package)=="nn" ? "MM" : ""; sprintf(buf, "%s.SpatialConvolution%s(%d, %d, %d, %d, %d, %d, %d, %d)", cuda_package, mm_or_not, nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h); lines.emplace_back(layer.name(), buf); } break; } case caffe::LayerParameter::POOLING: { auto ¶m = layer.pooling_param(); std::string ptype = param.pool() == caffe::PoolingParameter::MAX ? "Max" : "Avg"; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } if(std::string(cuda_package) == "ccn2") { char buf[1024]; sprintf(buf, "ccn2.Spatial%sPooling(%d, %d)", ptype.c_str(), kW, dW); lines.emplace_back(layer.name(), buf); } else if(std::string(cuda_package) == "cudnn") { char buf[1024]; sprintf(buf, "%s.Spatial%sPooling(%d, %d, %d, %d):ceil()", cuda_package, ptype=="Avg" ? "Average" : "Max", kW, kH, dW, dH); lines.emplace_back(layer.name(), buf); } break; } case caffe::LayerParameter::RELU: { lines.emplace_back(layer.name(), "nn.ReLU()"); break; } case caffe::LayerParameter::LRN: { if(std::string(cuda_package) == "ccn2") { auto ¶m = layer.lrn_param(); int local_size = param.local_size(); float alpha = param.alpha(); float beta = param.beta(); char buf[1024]; sprintf(buf, "ccn2.SpatialCrossResponseNormalization(%d, %.6f, %.4f)", local_size, alpha, beta); lines.emplace_back(layer.name(), buf); } break; } case caffe::LayerParameter::INNER_PRODUCT: { auto ¶m = layer.inner_product_param(); int nInputPlane = layer.blobs(0).width(); int nOutputPlane = param.num_output(); char buf[1024]; sprintf(buf, "nn.Linear(%d, %d)", nInputPlane, nOutputPlane); if(num_output != nInputPlane) { if(std::string(cuda_package) == "ccn2") lines.emplace_back("torch_transpose_bdwh", "nn.Transpose({4,1},{4,2},{4,3})"); lines.emplace_back("torch_view", "nn.View(-1):setNumInputDims(3)"); } lines.emplace_back(layer.name(), buf); num_output = nOutputPlane; break; } case caffe::LayerParameter::DROPOUT: { char buf[1024]; sprintf(buf, "nn.Dropout(%f)", netparam.layers(i).dropout_param().dropout_ratio()); lines.emplace_back(layer.name(), buf); break; } case caffe::LayerParameter::SOFTMAX_LOSS: { lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } case caffe::LayerParameter::SOFTMAX: { lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } default: { std::cout << "MODULE " << netparam.layers(i).name() << " UNDEFINED\n"; break; } } if(!lines.empty()) for(auto& it: lines) ofs << "table.insert(model, {'" << it.first << "', " << it.second << "})\n"; else ofs << "-- module '" << layer.name() << "' not found\n"; } }
void populateNet(Net dstNet) { CV_TRACE_FUNCTION(); int layersSize = net.layer_size(); layerCounter.clear(); addedBlobs.clear(); addedBlobs.reserve(layersSize + 1); //setup input layer names std::vector<String> netInputs(net.input_size()); { for (int inNum = 0; inNum < net.input_size(); inNum++) { addedBlobs.push_back(BlobNote(net.input(inNum), 0, inNum)); netInputs[inNum] = net.input(inNum); } } for (int li = 0; li < layersSize; li++) { const caffe::LayerParameter &layer = net.layer(li); String name = layer.name(); String type = layer.type(); LayerParams layerParams; extractLayerParams(layer, layerParams); extractBinaryLayerParams(layer, layerParams); int repetitions = layerCounter[name]++; if (repetitions) name += String("_") + toString(repetitions); if (type == "Input") { for (int outNum = 0; outNum < layer.top_size(); outNum++) { addOutput(layer, 0, outNum); addedBlobs.back().outNum = netInputs.size(); netInputs.push_back(addedBlobs.back().name); } continue; } else if (type == "BatchNorm") { if (!layerParams.get<bool>("use_global_stats", true)) { CV_Assert_N(layer.bottom_size() == 1, layer.top_size() == 1); LayerParams mvnParams; mvnParams.set("eps", layerParams.get<float>("eps", 1e-5)); std::string mvnName = name + "/mvn"; int repetitions = layerCounter[mvnName]++; if (repetitions) mvnName += String("_") + toString(repetitions); int mvnId = dstNet.addLayer(mvnName, "MVN", mvnParams); addInput(layer.bottom(0), mvnId, 0, dstNet); addOutput(layer, mvnId, 0); net.mutable_layer(li)->set_bottom(0, layer.top(0)); layerParams.blobs[0].setTo(0); // mean layerParams.blobs[1].setTo(1); // std } } else if ("ConvolutionDepthwise" == type) { type = "Convolution"; } int id = dstNet.addLayer(name, type, layerParams); for (int inNum = 0; inNum < layer.bottom_size(); inNum++) addInput(layer.bottom(inNum), id, inNum, dstNet); for (int outNum = 0; outNum < layer.top_size(); outNum++) addOutput(layer, id, outNum); } dstNet.setInputsNames(netInputs); addedBlobs.clear(); }
void convertProtoToLuaV1(const caffe::NetParameter &netparam, const char* lua_name, const char* cuda_package) { PACKAGE_TYPE cuda_package_type = CCN2; if(std::string(cuda_package) == "ccn2") cuda_package_type = CCN2; else if(std::string(cuda_package) == "nn") cuda_package_type = NN; else if(std::string(cuda_package) == "cudnn") cuda_package_type = CUDNN; std::ofstream ofs (lua_name); ofs << "require '" << cuda_package << "'\n"; ofs << "require 'cunn'\n"; ofs << "local model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; else if(std::string(cuda_package)=="nn" || std::string(cuda_package)=="cudnn") ofs<< "require 'inn'\n"; int num_output = netparam.input_dim_size(); for (int i=0; i<netparam.layers_size(); ++i) { std::vector<std::pair<std::string, std::string>> lines; auto& layer = netparam.layers(i); switch(layer.type()) { case caffe::V1LayerParameter::CONVOLUTION: { auto ¶m = layer.convolution_param(); int groups = param.group() == 0 ? 1 : param.group(); int nInputPlane = layer.blobs(0).channels()*groups; int nOutputPlane = layer.blobs(0).num(); //int nOutputPlane = param.num_output(); num_output = nOutputPlane; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } int pad_w = param.pad_w(); int pad_h = param.pad_h(); if(pad_w==0 || pad_h==0) { pad_w = param.pad(); pad_h = pad_w; } if(cuda_package_type == CCN2) { if(kW != kH || dW != dH || pad_w != pad_h) { std::cout << "ccn2 only supports square images!\n"; break; } char buf[1024]; sprintf(buf, "ccn2.SpatialConvolution(%d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, dW, pad_w, groups); lines.emplace_back(layer.name(), buf); } else if(cuda_package_type == NN) { if(groups != 1) { std::cout << "nn supports no groups!\n"; break; } char buf[1024]; sprintf(buf, "nn.SpatialConvolutionMM(%d, %d, %d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h); lines.emplace_back(layer.name(), buf); } else { char buf[1024]; sprintf(buf, "cudnn.SpatialConvolution(%d, %d, %d, %d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h, groups); lines.emplace_back(layer.name(), buf); } break; } case caffe::V1LayerParameter::POOLING: { auto ¶m = layer.pooling_param(); int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); int padW = param.pad_w(); int padH = param.pad_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } char buf[1024]; switch(cuda_package_type) { case CCN2: // ceil mode by default if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "ccn2.SpatialMaxPooling(%d, %d)", kW, dW); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "ccn2.SpatialAvgPooling(%d, %d)", kW, dW); else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) THError("Stochastic pooling is not implemented in DHWB format"); break; case CUDNN: if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "cudnn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "cudnn.SpatialAveragePooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break; case NN: if(param.pool() == caffe::PoolingParameter::MAX) //sprintf(buf, "nn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); sprintf(buf, "nn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d)", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "inn.SpatialAveragePooling(%d, %d, %d, %d)", kW, kH, dW, dH); // padding is not supported yet else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break; } lines.emplace_back(layer.name(), buf); break; } case caffe::V1LayerParameter::RELU: { switch(cuda_package_type) { case CUDNN: lines.emplace_back(layer.name(), "cudnn.ReLU(true)"); break; default: lines.emplace_back(layer.name(), "nn.ReLU(true)"); break; } break; } case caffe::V1LayerParameter::TANH: { switch(cuda_package_type) { case CUDNN: lines.emplace_back(layer.name(), "cudnn.Tanh(true)"); break; default: lines.emplace_back(layer.name(), "nn.Tanh()"); break; } break; } case caffe::V1LayerParameter::SIGMOID: { switch(cuda_package_type) { case CUDNN: lines.emplace_back(layer.name(), "cudnn.Sigmoid(true)"); break; default: lines.emplace_back(layer.name(), "nn.Sigmoid()"); break; } break; } case caffe::V1LayerParameter::LRN: { auto ¶m = layer.lrn_param(); int local_size = param.local_size(); float alpha = param.alpha(); float beta = param.beta(); float k = param.k(); char buf[1024]; if(std::string(cuda_package) == "ccn2") sprintf(buf, "ccn2.SpatialCrossResponseNormalization(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); else sprintf(buf, "inn.SpatialCrossResponseNormalization(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); lines.emplace_back(layer.name(), buf); break; } case caffe::V1LayerParameter::INNER_PRODUCT: { auto ¶m = layer.inner_product_param(); int nInputPlane = layer.blobs(0).width(); int nOutputPlane = param.num_output(); char buf[1024]; sprintf(buf, "nn.Linear(%d, %d)", nInputPlane, nOutputPlane); if(num_output != nInputPlane) { if(std::string(cuda_package) == "ccn2") lines.emplace_back("torch_transpose_bdwh", "nn.Transpose({4,1},{4,2},{4,3})"); lines.emplace_back("torch_view", "nn.View(-1):setNumInputDims(3)"); } lines.emplace_back(layer.name(), buf); num_output = nOutputPlane; break; } case caffe::V1LayerParameter::DROPOUT: { char buf[1024]; sprintf(buf, "nn.Dropout(%f)", layer.dropout_param().dropout_ratio()); lines.emplace_back(layer.name(), buf); break; } case caffe::V1LayerParameter::SOFTMAX_LOSS: { lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } case caffe::V1LayerParameter::SOFTMAX: { lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } default: { std::cout << "MODULE " << layer.name() << " UNDEFINED\n"; break; } } if(!lines.empty()) for(auto& it: lines) ofs << "table.insert(model, {'" << it.first << "', " << it.second << "})\n"; else { ofs << "-- warning: module '" << layer.name() << "' not found\n"; std::cout << "warning: module '" << layer.name() << "' not found\n"; } } ofs << "return model"; }
void convertProtoToLuaV2(const caffe::NetParameter &netparam, const char* lua_name, const char* cuda_package) { PACKAGE_TYPE cuda_package_type = CCN2; if(std::string(cuda_package) == "ccn2") cuda_package_type = CCN2; else if(std::string(cuda_package) == "nn") cuda_package_type = NN; else if(std::string(cuda_package) == "cudnn") cuda_package_type = CUDNN; std::ofstream ofs (lua_name); ofs << "require '" << cuda_package << "'\n"; ofs << "require 'cunn'\n"; ofs << "local model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; else if(std::string(cuda_package)=="nn" || std::string(cuda_package)=="cudnn") ofs<< "require 'inn'\n"; int num_output = netparam.input_shape_size() * 4; for (int i=0; i<netparam.layer_size(); ++i) { std::vector<std::pair<std::string, std::string>> lines; auto& layer = netparam.layer(i); if(layer.type() == "Convolution") { auto ¶m = layer.convolution_param(); int groups = param.group() == 0 ? 1 : param.group(); int nInputPlane = layer.blobs(0).shape().dim(1)*groups; int nOutputPlane = layer.blobs(0).shape().dim(0); //int nOutputPlane = param.num_output(); num_output = nOutputPlane; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } int pad_w = param.pad_w(); int pad_h = param.pad_h(); if(pad_w==0 || pad_h==0) { pad_w = param.pad(); pad_h = pad_w; } if(cuda_package_type == CCN2) { if(kW != kH || dW != dH || pad_w != pad_h) { std::cout << "ccn2 only supports square images!\n"; break; } char buf[1024]; sprintf(buf, "ccn2.SpatialConvolution(%d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, dW, pad_w, groups); lines.emplace_back(layer.name(), buf); } else { char buf[1024]; const char* mm_or_not = std::string(cuda_package)=="nn" ? "MM" : ""; sprintf(buf, "%s.SpatialConvolution%s(%d, %d, %d, %d, %d, %d, %d, %d, %d)", cuda_package, mm_or_not, nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h, groups); lines.emplace_back(layer.name(), buf); } } if(layer.type() == "Pooling") { auto ¶m = layer.pooling_param(); std::string ptype = param.pool() == caffe::PoolingParameter::MAX ? "Max" : "Avg"; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } char buf[1024]; switch(cuda_package_type) { case CCN2: sprintf(buf, "ccn2.Spatial%sPooling(%d, %d)", ptype.c_str(), kW, dW); break; case CUDNN: sprintf(buf, "%s.Spatial%sPooling(%d, %d, %d, %d):ceil()", cuda_package, ptype=="Avg" ? "Average" : "Max", kW, kH, dW, dH); break; case NN: sprintf(buf, "inn.Spatial%sPooling(%d, %d, %d, %d)", ptype=="Avg" ? "Average" : "Max", kW, kH, dW, dH); break; } lines.emplace_back(layer.name(), buf); } if(layer.type() == "ReLU") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.ReLU(true)"); else lines.emplace_back(layer.name(), "nn.ReLU(true)"); } if(layer.type() == "Sigmoid") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.Sigmoid(true)"); else lines.emplace_back(layer.name(), "nn.Sigmoid()"); } if(layer.type() == "Tanh") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.Tanh(true)"); else lines.emplace_back(layer.name(), "nn.Tanh()"); } if(layer.type() == "LRN") { auto ¶m = layer.lrn_param(); int local_size = param.local_size(); float alpha = param.alpha(); float beta = param.beta(); float k = param.k(); char buf[1024]; if(std::string(cuda_package) == "ccn2") sprintf(buf, "ccn2.SpatialCrossResponseNormalization(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); else sprintf(buf, "inn.SpatialCrossResponseNormalization(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); lines.emplace_back(layer.name(), buf); } if(layer.type() == "InnerProduct") { auto ¶m = layer.inner_product_param(); int nInputPlane = layer.blobs(0).shape().dim(1); int nOutputPlane = param.num_output(); char buf[1024]; sprintf(buf, "nn.Linear(%d, %d)", nInputPlane, nOutputPlane); if(num_output != nInputPlane) { if(std::string(cuda_package) == "ccn2") lines.emplace_back("torch_transpose_bdwh", "nn.Transpose({4,1},{4,2},{4,3})"); lines.emplace_back("torch_view", "nn.View(-1):setNumInputDims(3)"); } lines.emplace_back(layer.name(), buf); num_output = nOutputPlane; } if(layer.type() == "Dropout") { char buf[1024]; sprintf(buf, "nn.Dropout(%f)", layer.dropout_param().dropout_ratio()); lines.emplace_back(layer.name(), buf); } if(layer.type()=="SoftmaxWithLoss") { lines.emplace_back(layer.name(), "nn.SoftMax()"); } if(layer.type()=="Softmax") { lines.emplace_back(layer.name(), "nn.SoftMax()"); } if(!lines.empty()) for(auto& it: lines) ofs << "table.insert(model, {'" << it.first << "', " << it.second << "})\n"; else { ofs << "-- module '" << layer.name() << "' not found\n"; std::cout << "module '" << layer.name() << "' not found\n"; } } ofs << "return model"; }
void convertProtoToLuaV2(const caffe::NetParameter &netparam, const char* lua_name, const char* cuda_package) { PACKAGE_TYPE cuda_package_type = CCN2; if(std::string(cuda_package) == "ccn2") cuda_package_type = CCN2; else if(std::string(cuda_package) == "nn") cuda_package_type = NN; else if(std::string(cuda_package) == "cudnn") cuda_package_type = CUDNN; std::ofstream ofs (lua_name); ofs << "require '" << cuda_package << "'\n"; ofs << "local model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; int num_output = netparam.input_shape_size() * 4; for (int i=0; i<netparam.layer_size(); ++i) { std::vector<std::pair<std::string, std::string>> lines; auto& layer = netparam.layer(i); if(layer.type() == "Convolution") { auto ¶m = layer.convolution_param(); int groups = param.group() == 0 ? 1 : param.group(); auto &wB = layer.blobs(0); int nInputPlane = (wB.has_shape() ? wB.shape().dim(1) : wB.channels())*groups; int nOutputPlane = wB.has_shape() ? wB.shape().dim(0) : wB.num(); //int nOutputPlane = param.num_output(); num_output = nOutputPlane; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } int pad_w = param.pad_w(); int pad_h = param.pad_h(); if(pad_w==0 || pad_h==0) { pad_w = param.pad(); pad_h = pad_w; } if(cuda_package_type == CCN2) { if(kW != kH || dW != dH || pad_w != pad_h) { std::cout << "ccn2 only supports square images!\n"; break; } char buf[1024]; sprintf(buf, "ccn2.SpatialConvolution(%d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, dW, pad_w, groups); lines.emplace_back(layer.name(), buf); } else if(cuda_package_type == NN) { if(groups != 1) { std::cout << "nn supports no groups!\n"; break; } char buf[1024]; sprintf(buf, "nn.SpatialConvolution(%d, %d, %d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h); lines.emplace_back(layer.name(), buf); } else { char buf[1024]; sprintf(buf, "cudnn.SpatialConvolution(%d, %d, %d, %d, %d, %d, %d, %d, %d)", nInputPlane, nOutputPlane, kW, kH, dW, dH, pad_w, pad_h, groups); lines.emplace_back(layer.name(), buf); } } if(layer.type() == "Pooling") { auto ¶m = layer.pooling_param(); std::string ptype = param.pool() == caffe::PoolingParameter::MAX ? "Max" : "Avg"; int kW = param.kernel_w(); int kH = param.kernel_h(); int dW = param.stride_w(); int dH = param.stride_h(); int padW = param.pad_w(); int padH = param.pad_h(); if(kW==0 || kH==0) { kW = param.kernel_size(); kH = kW; } if(dW==0 || dH==0) { dW = param.stride(); dH = dW; } if(padW==0 && padH==0) { padW = param.pad(); padH = padW; } char buf[1024]; switch(cuda_package_type) { case CCN2: // ceil mode by default if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "ccn2.SpatialMaxPooling(%d, %d)", kW, dW); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "ccn2.SpatialAvgPooling(%d, %d)", kW, dW); else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) THError("Stochastic pooling is not implemented in DHWB format"); break; case CUDNN: if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "cudnn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "cudnn.SpatialAveragePooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break; case NN: if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "nn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "nn.SpatialAveragePooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break; } lines.emplace_back(layer.name(), buf); } if(layer.type() == "ReLU") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.ReLU(true)"); else lines.emplace_back(layer.name(), "nn.ReLU(true)"); } //new layers if(layer.type() == "Concat") { char buf[1024]; auto ¶m = layer.concat_param(); sprintf(buf, "nn.JoinTable(%d)", param.axis() + 1); lines.emplace_back(layer.name(), buf); break; } if(layer.type() == "Split") { lines.emplace_back(layer.name(), "nn.ConcatTable()"); break; } //end if(layer.type() == "Sigmoid") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.Sigmoid(true)"); else lines.emplace_back(layer.name(), "nn.Sigmoid()"); } if(layer.type() == "Tanh") { if(cuda_package_type == CUDNN) lines.emplace_back(layer.name(), "cudnn.Tanh(true)"); else lines.emplace_back(layer.name(), "nn.Tanh()"); } if(layer.type() == "LRN") { auto ¶m = layer.lrn_param(); int local_size = param.local_size(); float alpha = param.alpha(); float beta = param.beta(); float k = param.k(); char buf[1024]; if(std::string(cuda_package) == "ccn2") sprintf(buf, "ccn2.SpatialCrossResponseNormalization(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); else if(std::string(cuda_package) == "nn") sprintf(buf, "nn.SpatialCrossMapLRN(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); else if(std::string(cuda_package) == "cudnn") sprintf(buf, "cudnn.SpatialCrossMapLRN(%d, %.6f, %.4f, %f)", local_size, alpha, beta, k); lines.emplace_back(layer.name(), buf); } if(layer.type() == "InnerProduct") { auto ¶m = layer.inner_product_param(); auto &wB = layer.blobs(0); int nInputPlane = wB.has_shape() ? wB.shape().dim(1) : wB.width(); int nOutputPlane = param.num_output(); char buf[1024]; sprintf(buf, "nn.Linear(%d, %d)", nInputPlane, nOutputPlane); if(num_output != nInputPlane) { if(std::string(cuda_package) == "ccn2") lines.emplace_back("torch_transpose_bdwh", "nn.Transpose({4,1},{4,2},{4,3})"); lines.emplace_back("torch_view", "nn.View(-1):setNumInputDims(3)"); } lines.emplace_back(layer.name(), buf); num_output = nOutputPlane; } if(layer.type() == "Dropout") { char buf[1024]; sprintf(buf, "nn.Dropout(%f)", layer.dropout_param().dropout_ratio()); lines.emplace_back(layer.name(), buf); } if(layer.type()=="SoftmaxWithLoss") { if(std::string(cuda_package) == "cudnn") lines.emplace_back(layer.name(), "cudnn.SoftMax()"); else lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } if(layer.type()=="Softmax") { if(std::string(cuda_package) == "cudnn") lines.emplace_back(layer.name(), "cudnn.SoftMax()"); else lines.emplace_back(layer.name(), "nn.SoftMax()"); break; } if(!lines.empty()) for(auto& it: lines) ofs << "table.insert(model, {'" << it.first << "', " << it.second << "})\n"; else { ofs << "-- warning: module '" << layer.name() << " [type " << layer.type() << "]" << "' not found\n"; std::cout << "warning: module '" << layer.name() << " [type " << layer.type() << "]" << "' not found\n"; } } ofs << "return model"; }