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 ...@@ -412,7 +412,7 @@ namespace dnn
class CV_EXPORTS_W MaxUnpoolLayer : public Layer class CV_EXPORTS_W MaxUnpoolLayer : public Layer
{ {
public: 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 class CV_EXPORTS_W ScaleLayer : public Layer
......
...@@ -336,9 +336,10 @@ Ptr<Layer> createLayerFromCaffe<ChannelsPReLULayer>(LayerParams& params) ...@@ -336,9 +336,10 @@ Ptr<Layer> createLayerFromCaffe<ChannelsPReLULayer>(LayerParams& params)
template<> //MaxUnpoolLayer specialization template<> //MaxUnpoolLayer specialization
Ptr<Layer> createLayerFromCaffe<MaxUnpoolLayer>(LayerParams& params) Ptr<Layer> createLayerFromCaffe<MaxUnpoolLayer>(LayerParams& params)
{ {
Size outSize(params.get<int>("out_w"), Size poolKernel(params.get<int>("pool_k_w"), params.get<int>("pool_k_h")),
params.get<int>("out_h")); poolPad(params.get<int>("pool_pad_w"), params.get<int>("pool_pad_h")),
Ptr<MaxUnpoolLayer> l = MaxUnpoolLayer::create(outSize); poolStride(params.get<int>("pool_stride_w"), params.get<int>("pool_stride_h"));
Ptr<MaxUnpoolLayer> l = MaxUnpoolLayer::create(poolKernel, poolPad, poolStride);
l->setParamsFrom(params); l->setParamsFrom(params);
return Ptr<Layer>(l); return Ptr<Layer>(l);
......
...@@ -16,19 +16,20 @@ namespace cv ...@@ -16,19 +16,20 @@ namespace cv
namespace dnn namespace dnn
{ {
MaxUnpoolLayerImpl::MaxUnpoolLayerImpl(Size outSize_): MaxUnpoolLayerImpl::MaxUnpoolLayerImpl(Size poolKernel_, Size poolPad_, Size poolStride_):
outSize(outSize_) poolKernel(poolKernel_),
poolPad(poolPad_),
poolStride(poolStride_)
{} {}
void MaxUnpoolLayerImpl::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs) void MaxUnpoolLayerImpl::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
{ {
CV_Assert(inputs.size() == 2); CV_Assert(inputs.size() == 2);
CV_Assert(inputs[0]->total() == inputs[1]->total());
BlobShape outShape = inputs[0]->shape(); BlobShape outShape = inputs[0]->shape();
outShape[2] = outSize.height; outShape[2] = (outShape[2] - 1) * poolStride.height + poolKernel.height - 2 * poolPad.height;
outShape[3] = outSize.width; outShape[3] = (outShape[3] - 1) * poolStride.width + poolKernel.width - 2 * poolPad.width;
CV_Assert(inputs[0]->total() == inputs[1]->total());
outputs.resize(1); outputs.resize(1);
outputs[0].create(outShape); outputs[0].create(outShape);
...@@ -63,9 +64,9 @@ void MaxUnpoolLayerImpl::forward(std::vector<Blob*> &inputs, std::vector<Blob> & ...@@ -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 ...@@ -22,14 +22,16 @@ namespace dnn
class MaxUnpoolLayerImpl : public MaxUnpoolLayer class MaxUnpoolLayerImpl : public MaxUnpoolLayer
{ {
public: public:
MaxUnpoolLayerImpl(Size outSize_); MaxUnpoolLayerImpl(Size poolKernel_, Size poolPad_, Size poolStride_);
void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs); void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs); void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
private: private:
Size outSize; Size poolKernel;
Size poolPad;
Size poolStride;
}; };
} }
......
...@@ -737,14 +737,8 @@ struct TorchImporter : public ::cv::dnn::Importer ...@@ -737,14 +737,8 @@ struct TorchImporter : public ::cv::dnn::Importer
else if (nnName == "SpatialMaxUnpooling") else if (nnName == "SpatialMaxUnpooling")
{ {
readTorchTable(scalarParams, tensorParams); readTorchTable(scalarParams, tensorParams);
CV_Assert(scalarParams.has("oheight") &&
scalarParams.has("owidth"));
CV_Assert(tensorParams.count("indices")); 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); layerParams.set("indices_blob_id", tensorParams["indices"].first);
curModule->modules.push_back(newModule); curModule->modules.push_back(newModule);
} }
...@@ -908,13 +902,10 @@ struct TorchImporter : public ::cv::dnn::Importer ...@@ -908,13 +902,10 @@ struct TorchImporter : public ::cv::dnn::Importer
return id; return id;
} }
else if (module->thName == "SpatialMaxUnpooling") { 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")); CV_Assert(module->params.has("indices_blob_id"));
int indicesBlobId = module->params.get<int>("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++) for(int i = 0; i < addedModules.size(); i++)
{ {
...@@ -922,11 +913,25 @@ struct TorchImporter : public ::cv::dnn::Importer ...@@ -922,11 +913,25 @@ struct TorchImporter : public ::cv::dnn::Importer
addedModules[i].second->params.has("indices_blob_id") && addedModules[i].second->params.has("indices_blob_id") &&
addedModules[i].second->params.get<int>("indices_blob_id") == indicesBlobId) addedModules[i].second->params.get<int>("indices_blob_id") == indicesBlobId)
{ {
net.connect(addedModules[i].first, 1, id, 1); poolingLayer = addedModules[i];
break; 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; 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