예제 #1
0
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);
}
예제 #2
0
    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 &param, 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;
}
예제 #4
0
    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();
    }
예제 #5
0
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 &param = 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 &param = 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 &param = 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 &param = 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";
  }
}
예제 #6
0
    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();
    }
예제 #7
0
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 &param = 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 &param = 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 &param = 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 &param = 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";
}
예제 #8
0
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 &param = 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 &param = 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 &param = 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 &param = 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";
}
예제 #9
0
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 &param = 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 &param = 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 &param = 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 &param = 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 &param = 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";
}