Add global pool flags

This commit is contained in:
Liubov Batanina 2020-01-20 15:03:17 +03:00
parent bb91e6999b
commit 08ba63da02
3 changed files with 101 additions and 39 deletions

View File

@ -157,27 +157,86 @@ void getPoolingKernelParams(const LayerParams &params, std::vector<size_t>& kern
if (params.has("global_pooling_w"))
globalPooling[2] = params.get<bool>("global_pooling_w");
if (is_global)
{
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode);
if(params.has("kernel_h") || params.has("kernel_w") || params.has("kernel_size"))
{
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, kernel_size (or kernel_h and kernel_w) cannot be specified");
}
for (int i = 0; i < pads_begin.size(); i++) {
if (pads_begin[i] != 0 || pads_end[i] != 0)
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, pads must be = 0");
}
for (int i = 0; i < strides.size(); i++) {
if (strides[i] != 1)
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, strides must be = 1");
}
}
else
is_global = globalPooling[0] || globalPooling[1] || globalPooling[2];
if (!is_global)
{
util::getKernelSize(params, kernel);
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode, kernel.size());
}
else
{
if ((globalPooling[0] && params.has("kernel_d")) ||
(globalPooling[1] && params.has("kernel_h")) ||
(globalPooling[2] && params.has("kernel_w")) ||
params.has("kernel_size")) {
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, kernel_size (or kernel_h and kernel_w) cannot be specified");
}
kernel.resize(3, 1);
pads_begin.resize(3, 0);
pads_end.resize(3, 0);
strides.resize(3, 1);
if (params.has("kernel_d"))
kernel[0] = params.get<int>("kernel_d");
if (params.has("kernel_h"))
kernel[1] = params.get<int>("kernel_h");
if (params.has("kernel_w"))
kernel[2] = params.get<int>("kernel_w");
if (params.has("pad_t"))
pads_begin[1] = params.get<int>("pad_t");
if (params.has("pad_l"))
pads_begin[2] = params.get<int>("pad_l");
if (params.has("pad_b"))
pads_end[1] = params.get<int>("pad_b");
if (params.has("pad_r"))
pads_end[2] = params.get<int>("pad_r");
if (params.has("pad_h")) {
pads_begin[1] = params.get<int>("pad_h");
pads_end[1] = params.get<int>("pad_h");
}
if (params.has("pad_w")) {
pads_begin[2] = params.get<int>("pad_w");
pads_end[2] = params.get<int>("pad_w");
}
if (params.has("pad")) {
DictValue param = params.get("pad");
if (param.size() == 1) {
std::fill(pads_begin.begin(), pads_begin.end(), param.get<int>(0));
pads_end = pads_begin;
} else if (param.size() <= pads_begin.size()) {
for (int i = param.size() - 1, j = pads_begin.size() - 1; i >= 0; i--, j--) {
pads_begin[j] = param.get<int>(i);
}
pads_end = pads_begin;
} else {
for (int i = param.size() - 1, j = pads_begin.size() - 1; i >= param.size() / 2; i--, j--) {
pads_begin[j] = param.get<int>(i);
}
for (int i = param.size() / 2 - 1, j = pads_end.size() / 2 - 1; i >= 0; i--, j--) {
pads_end[j] = param.get<int>(i);
}
}
}
if (params.has("stride_h"))
strides[1] = params.get<int>("stride_h");
if (params.has("stride_w"))
strides[2] = params.get<int>("stride_w");
if (params.has("stride")) {
DictValue param = params.get("stride");
for (int i = param.size() - 1, j = strides.size() - 1; i >= 0; i--, j--) {
strides[j] = param.get<int>(i);
}
if (param.size() == 1)
std::fill(strides.begin() + 1, strides.end(), strides[0]);
}
for (int i = 0; i < pads_begin.size(); i++) {
if ((pads_begin[i] != 0 || pads_end[i] != 0 || strides[i] != 1) && globalPooling[i])
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, pads must be = 0 and strides must be = 1");
}
}
}
void getConvolutionKernelParams(const LayerParams &params, std::vector<size_t>& kernel, std::vector<size_t>& pads_begin,

View File

@ -148,17 +148,24 @@ public:
inp.push_back(inputs[0].size[i]);
out.push_back(outputs[0].size[i]);
}
kernel_size.resize(out.size());
for (int i = 0; i < kernel_size.size(); i++)
{
int pool_idx = isGlobalPooling.size() - 1 - i;
int kernel_idx = kernel_size.size() - 1 - i;
if (isGlobalPooling[pool_idx])
kernel_size[kernel_idx] = inp[kernel_idx];
}
kernel = Size(kernel_size[1], kernel_size[0]);
if (kernel_size.size() > inp.size()) {
kernel_size.erase(kernel_size.begin());
strides.erase(strides.begin());
pads_begin.erase(pads_begin.begin());
pads_end.erase(pads_end.begin());
}
kernel_size.resize(out.size());
for (int i = 0; i < inp.size(); i++)
{
int idx = isGlobalPooling.size() - inp.size() + i;
if (isGlobalPooling[idx])
kernel_size[i] = inp[i];
}
kernel = Size(kernel_size.back(), kernel_size[kernel_size.size() - 2]);
getConvPoolPaddings(inp, kernel_size, strides, padMode, pads_begin, pads_end);
if (pads_begin.size() == 2) {
pad_t = pads_begin[0];
pad_l = pads_begin[1];
@ -1005,15 +1012,11 @@ virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inp
std::vector<size_t> local_kernel = kernel_size.empty() ?
std::vector<size_t>(inpShape.begin(), inpShape.end()) : kernel_size;
for (int i = 0; i < local_kernel.size(); i++)
{
int pool_idx = isGlobalPooling.size() - 1 - i;
int kernel_idx = local_kernel.size() - 1 - i;
if (isGlobalPooling[pool_idx])
local_kernel[kernel_idx] = inpShape[kernel_idx];
for (int i = 0, j = local_kernel.size() - inpShape.size(); i < inpShape.size(); i++, j++) {
if (isGlobalPooling[j])
local_kernel[j] = inpShape[i];
}
if (type == ROI || type == PSROI)
{
outShape.push_back(pooledSize.height);
@ -1021,17 +1024,17 @@ virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inp
}
else if (padMode.empty())
{
for (int i = 0; i < local_kernel.size(); i++) {
float dst = (float)(inpShape[i] + pads_begin[i] + pads_end[i] - local_kernel[i]) / strides[i];
for (int i = 0, j = local_kernel.size() - inpShape.size(); i < inpShape.size(); i++, j++) {
float dst = (float)(inpShape[i] + pads_begin[j] + pads_end[j] - local_kernel[j]) / strides[j];
outShape.push_back(1 + (ceilMode ? ceil(dst) : floor(dst)));
}
// If we have padding, ensure that the last pooling starts strictly
// inside the image (instead of at the padding); otherwise clip the last.
for (int i = 0; i < pads_end.size(); i++) {
if (pads_end[i] && (outShape[2 + i] - 1) * strides[i] >= inpShape[i] + pads_end[i]) {
for (int i = 0, j = local_kernel.size() - inpShape.size(); i < inpShape.size(); i++, j++) {
if (pads_end[j] && (outShape[2 + i] - 1) * strides[j] >= inpShape[i] + pads_end[j]) {
--outShape[2 + i];
CV_Assert((outShape[2 + i] - 1) * strides[i] < inpShape[i] + pads_end[i]);
CV_Assert((outShape[2 + i] - 1) * strides[j] < inpShape[i] + pads_end[j]);
}
}
}

View File

@ -1982,7 +1982,7 @@ void TFImporter::populateNet(Net dstNet)
avgLp.set("pool", "ave");
// pooling kernel H x 1
avgLp.set("global_pooling_h", true);
avgLp.set("kernel_size", 1);
avgLp.set("kernel_w", 1);
int avgId = dstNet.addLayer(avgName, "Pooling", avgLp);
layer_id[avgName] = avgId;
connect(layer_id, dstNet, Pin(reshapeName), avgId, 0);