Commit ecd88160 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #1017 from arrybn:unpool_layer_fix

parents 1aeeee00 fd89b574
......@@ -412,7 +412,7 @@ namespace dnn
class CV_EXPORTS_W MaxUnpoolLayer : public Layer
{
public:
static CV_WRAP Ptr<MaxUnpoolLayer> create(Size unpoolSize);
static CV_WRAP Ptr<MaxUnpoolLayer> create(Size poolKernel, Size poolPad, Size poolStride);
};
class CV_EXPORTS_W ScaleLayer : public Layer
......
......@@ -336,9 +336,10 @@ Ptr<Layer> createLayerFromCaffe<ChannelsPReLULayer>(LayerParams& params)
template<> //MaxUnpoolLayer specialization
Ptr<Layer> createLayerFromCaffe<MaxUnpoolLayer>(LayerParams& params)
{
Size outSize(params.get<int>("out_w"),
params.get<int>("out_h"));
Ptr<MaxUnpoolLayer> l = MaxUnpoolLayer::create(outSize);
Size poolKernel(params.get<int>("pool_k_w"), params.get<int>("pool_k_h")),
poolPad(params.get<int>("pool_pad_w"), params.get<int>("pool_pad_h")),
poolStride(params.get<int>("pool_stride_w"), params.get<int>("pool_stride_h"));
Ptr<MaxUnpoolLayer> l = MaxUnpoolLayer::create(poolKernel, poolPad, poolStride);
l->setParamsFrom(params);
return Ptr<Layer>(l);
......
......@@ -16,19 +16,20 @@ namespace cv
namespace dnn
{
MaxUnpoolLayerImpl::MaxUnpoolLayerImpl(Size outSize_):
outSize(outSize_)
MaxUnpoolLayerImpl::MaxUnpoolLayerImpl(Size poolKernel_, Size poolPad_, Size poolStride_):
poolKernel(poolKernel_),
poolPad(poolPad_),
poolStride(poolStride_)
{}
void MaxUnpoolLayerImpl::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
{
CV_Assert(inputs.size() == 2);
CV_Assert(inputs[0]->total() == inputs[1]->total());
BlobShape outShape = inputs[0]->shape();
outShape[2] = outSize.height;
outShape[3] = outSize.width;
CV_Assert(inputs[0]->total() == inputs[1]->total());
outShape[2] = (outShape[2] - 1) * poolStride.height + poolKernel.height - 2 * poolPad.height;
outShape[3] = (outShape[3] - 1) * poolStride.width + poolKernel.width - 2 * poolPad.width;
outputs.resize(1);
outputs[0].create(outShape);
......@@ -63,9 +64,9 @@ void MaxUnpoolLayerImpl::forward(std::vector<Blob*> &inputs, std::vector<Blob> &
}
}
Ptr<MaxUnpoolLayer> MaxUnpoolLayer::create(Size unpoolSize)
Ptr<MaxUnpoolLayer> MaxUnpoolLayer::create(Size poolKernel, Size poolPad, Size poolStride)
{
return Ptr<MaxUnpoolLayer>(new MaxUnpoolLayerImpl(unpoolSize));
return Ptr<MaxUnpoolLayer>(new MaxUnpoolLayerImpl(poolKernel, poolPad, poolStride));
}
}
......
......@@ -22,14 +22,16 @@ namespace dnn
class MaxUnpoolLayerImpl : public MaxUnpoolLayer
{
public:
MaxUnpoolLayerImpl(Size outSize_);
MaxUnpoolLayerImpl(Size poolKernel_, Size poolPad_, Size poolStride_);
void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
private:
Size outSize;
Size poolKernel;
Size poolPad;
Size poolStride;
};
}
......
......@@ -737,14 +737,8 @@ struct TorchImporter : public ::cv::dnn::Importer
else if (nnName == "SpatialMaxUnpooling")
{
readTorchTable(scalarParams, tensorParams);
CV_Assert(scalarParams.has("oheight") &&
scalarParams.has("owidth"));
CV_Assert(tensorParams.count("indices"));
layerParams.set("out_h", static_cast<int>(scalarParams.get<double>("oheight")));
layerParams.set("out_w", static_cast<int>(scalarParams.get<double>("owidth"))/2);
layerParams.set("indices_blob_id", tensorParams["indices"].first);
curModule->modules.push_back(newModule);
}
......@@ -908,13 +902,10 @@ struct TorchImporter : public ::cv::dnn::Importer
return id;
}
else if (module->thName == "SpatialMaxUnpooling") {
String name = generateLayerName("torchMaxUnpooling");
int id = net.addLayer(name, "MaxUnpool", module->params);
net.connect(prevLayerId, 0, id, 0);
CV_Assert(module->params.has("indices_blob_id"));
int indicesBlobId = module->params.get<int>("indices_blob_id");
std::pair<int, Module*> poolingLayer;
poolingLayer.first = -1;
for(int i = 0; i < addedModules.size(); i++)
{
......@@ -922,11 +913,25 @@ struct TorchImporter : public ::cv::dnn::Importer
addedModules[i].second->params.has("indices_blob_id") &&
addedModules[i].second->params.get<int>("indices_blob_id") == indicesBlobId)
{
net.connect(addedModules[i].first, 1, id, 1);
poolingLayer = addedModules[i];
break;
}
}
module->params.set("pool_k_h", poolingLayer.second->params.get<int>("kernel_h"));
module->params.set("pool_k_w", poolingLayer.second->params.get<int>("kernel_w"));
module->params.set("pool_stride_h", poolingLayer.second->params.get<int>("stride_h"));
module->params.set("pool_stride_w", poolingLayer.second->params.get<int>("stride_w"));
module->params.set("pool_pad_h", poolingLayer.second->params.get<int>("pad_h"));
module->params.set("pool_pad_w", poolingLayer.second->params.get<int>("pad_w"));
String name = generateLayerName("torchMaxUnpooling");
int id = net.addLayer(name, "MaxUnpool", module->params);
net.connect(prevLayerId, 0, id, 0);
CV_Assert(poolingLayer.first != -1);
net.connect(poolingLayer.first, 1, id, 1);
return id;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment