-
Notifications
You must be signed in to change notification settings - Fork 334
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/20180428-pad-function' into feature/20180401-fi…
…le-format-converter
- Loading branch information
Showing
7 changed files
with
512 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright (c) 2017 Sony Corporation. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef NBLA_FUNCTION_PAD_HPP | ||
#define NBLA_FUNCTION_PAD_HPP | ||
|
||
#include <nbla/cpu.hpp> | ||
#include <nbla/function.hpp> | ||
#include <nbla/function_registry.hpp> | ||
|
||
namespace nbla { | ||
|
||
NBLA_REGISTER_FUNCTION_HEADER(Pad, const vector<int> &, const string &, float); | ||
|
||
/** Pads given N-D array with specified sizes of dimensions. | ||
The dimensions that get padded begins with the last dimension and moves forward. | ||
Inputs: | ||
- x: N-D array. | ||
- pad_width: n-elem tuple, where n/2 <= input dimensions and n is even. | ||
len(pad_width)/2 represents the padding dimension. (e.g. 1D, 2D, 3D etc.) | ||
(Currently padding upto 3D is supported) | ||
- mode - Padding mode is one of the following. Default: constant. | ||
1)constant : Elements in pad region are filled with constant_value. | ||
2)replicate : Padded elements are filled with the values in nearest | ||
edges. | ||
3)reflect : Padded with the reflection of the vector mirrored on the | ||
first and last values of the vector along each axis. | ||
(Currently only constant mode is supported) | ||
- constant_value - Constant values filled in padded regions if mode is constant. | ||
Default: 0 | ||
Outputs: | ||
- Padded N-D array (e.g. (B, C, H, W) shape) where dimension depends on | ||
pad_width. | ||
ndim() of output N-D array will be same as ndim() of input N-D array. | ||
for 1D padding: | ||
N-D input array with padding of the form (padLeft, padRight) | ||
output N-D array dimension (B, C, H, padLeft + W + padRight) | ||
for 2D padding: | ||
N-D input array with padding of the form (padTop, padBottom, padLeft, | ||
padRight). | ||
output N-D array dimension (B, C, padTop + H + padBottom, padLeft + W + | ||
padRight) | ||
for 3D padding: | ||
N-D input array with padding of the form (pasFront, padBack, padTop, | ||
padBottom, padLeft, padRight). | ||
output N-D array dimension (B, padFront + C + padBack, padTop + H + | ||
padBottom, padLeft + W + padRight) | ||
@tparam T Data type for computation. | ||
\ingroup FunctionImplGrp | ||
*/ | ||
|
||
template <typename T> | ||
class Pad : public BaseFunction<const vector<int> &, const string &, float> { | ||
protected: | ||
const vector<int> pad_width_; | ||
const string mode_; | ||
float constant_value_; | ||
|
||
public: | ||
Pad(const Context &ctx, const vector<int> &pad_width, const string &mode, | ||
float constant_value) | ||
: BaseFunction(ctx, pad_width, mode, constant_value), | ||
pad_width_(pad_width), mode_(mode), constant_value_(constant_value) { | ||
pad_mode_["constant"] = p_constant; | ||
pad_mode_["replicate"] = p_replicate; | ||
pad_mode_["reflect"] = p_reflect; | ||
} | ||
virtual ~Pad() {} | ||
virtual shared_ptr<Function> copy() const { | ||
return create_Pad(ctx_, pad_width_, mode_, constant_value_); | ||
} | ||
virtual int min_inputs() { return 1; } | ||
virtual int min_outputs() { return 1; } | ||
virtual vector<dtypes> in_types() { return vector<dtypes>{get_dtype<T>()}; } | ||
virtual vector<dtypes> out_types() { return vector<dtypes>{get_dtype<T>()}; } | ||
virtual vector<string> allowed_array_classes() { | ||
return SingletonManager::get<Cpu>()->array_classes(); | ||
} | ||
virtual string name() { return "Pad"; } | ||
|
||
typedef enum pad_mode { p_constant, p_replicate, p_reflect } pad_mode; | ||
std::map<std::string, pad_mode> pad_mode_; | ||
|
||
protected: | ||
NBLA_API virtual void setup_impl(const Variables &inputs, | ||
const Variables &outputs); | ||
NBLA_API virtual void forward_impl(const Variables &inputs, | ||
const Variables &outputs); | ||
NBLA_API virtual void backward_impl(const Variables &inputs, | ||
const Variables &outputs, | ||
const vector<bool> &propagate_down, | ||
const vector<bool> &accum); | ||
}; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Copyright (c) 2017 Sony Corporation. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import pytest | ||
|
||
import numpy as np | ||
import nnabla as nn | ||
import nnabla.initializer as I | ||
import nnabla.functions as F | ||
|
||
from function_benchmark import FunctionBenchmark, Inspec | ||
|
||
|
||
@pytest.mark.parametrize("seed", [313]) | ||
def pad_params(): | ||
inspecs = [] | ||
u = I.UniformInitializer((0.5, 1.0)) | ||
inspecs.append([Inspec((2, 2, 2, 2), u)]) | ||
inspecs.append([Inspec((2, 3, 2, 3), u)]) | ||
inspecs.append([Inspec((2, 20, 200, 200), u)]) | ||
return inspecs | ||
|
||
|
||
@pytest.mark.parametrize('inspecs', pad_params()) | ||
def test_pad(inspecs, nnabla_opts): | ||
fb = FunctionBenchmark( | ||
F.pad, inspecs, [(10, 10, 10, 10), 'constant', 0.0], {}, | ||
nnabla_opts.ext, nnabla_opts.ext_kwargs) | ||
fb.benchmark() | ||
fb.write(writer=nnabla_opts.function_benchmark_writer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Copyright (c) 2017 Sony Corporation. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import pytest | ||
import numpy as np | ||
import nnabla as nn | ||
import nnabla.functions as F | ||
from nbla_test_utils import list_context | ||
|
||
ctxs = list_context('Pad') | ||
|
||
|
||
def ref_pad(x, pad_with, mode, constant_value): | ||
pair_len = int(len(pad_with)/2) | ||
pad_list = [(0, 0)] * (len(x.shape)-pair_len) | ||
pad_list.extend([(a, b) for a, b in zip(pad_with[:-1:2], pad_with[1::2])]) | ||
new_pad = tuple(pad_list) | ||
|
||
ret = np.pad(x, new_pad, mode, constant_values=constant_value) | ||
return ret | ||
|
||
|
||
def pad_forward_backward(seed, inshape, pad_with, mode, constant_value, ctx, func_name): | ||
from nbla_test_utils import function_tester | ||
rng = np.random.RandomState(seed) | ||
# Generate ND inputs | ||
i = rng.randn(*inshape).astype(np.float32) | ||
inputs_nd = [i] | ||
|
||
function_tester(rng, F.pad, ref_pad, inputs_nd, func_args=[ | ||
pad_with, mode, constant_value], ctx=ctx, func_name=func_name, dstep=1e-1) | ||
|
||
|
||
@pytest.mark.parametrize("ctx, func_name", ctxs) | ||
@pytest.mark.parametrize("inshape_1d", [(4,), (5,)]) | ||
@pytest.mark.parametrize("pad_with_1d", [(2, 2), (1, 1), (2, 3)]) | ||
@pytest.mark.parametrize("mode, constant_value", [('constant', 0.0), ('constant', 0.2), ('constant', 5.5), ('constant', -0.1)]) | ||
@pytest.mark.parametrize("seed", [313]) | ||
def test_pad_forward_backward_1D(seed, inshape_1d, pad_with_1d, mode, constant_value, ctx, func_name): | ||
pad_forward_backward(seed, inshape_1d, pad_with_1d, | ||
mode, constant_value, ctx, func_name) | ||
|
||
|
||
@pytest.mark.parametrize("ctx, func_name", ctxs) | ||
@pytest.mark.parametrize("inshape_2d", [(4, 4), (5, 5), (2, 3)]) | ||
@pytest.mark.parametrize("pad_with_2d", [(2, 2), (1, 1), (2, 3), (2, 2, 2, 2), (3, 3, 3, 3), (2, 3, 3, 4)]) | ||
@pytest.mark.parametrize("mode, constant_value", [('constant', 0.0), ('constant', 0.2), ('constant', 5.5), ('constant', -0.1)]) | ||
@pytest.mark.parametrize("seed", [313]) | ||
def test_pad_forward_backward_2D(seed, inshape_2d, pad_with_2d, mode, constant_value, ctx, func_name): | ||
pad_forward_backward(seed, inshape_2d, pad_with_2d, | ||
mode, constant_value, ctx, func_name) | ||
|
||
|
||
@pytest.mark.parametrize("ctx, func_name", ctxs) | ||
@pytest.mark.parametrize("inshape_Nd", [(2, 2, 2), (3, 5, 7), (2, 3, 2), (2, 2, 2, 2), (3, 5, 7, 1), (2, 3, 4, 6), (2, 2, 2, 2, 2), (3, 1, 5, 7, 3), (2, 3, 1, 1, 4, 5), (2, 2, 2, 2, 2, 2), (3, 3, 1, 5, 7, 3), (2, 2, 3, 1, 1, 4, 5)]) | ||
@pytest.mark.parametrize("pad_with_3d", [(2, 2), (1, 1), (2, 3), (2, 2, 2, 2), (3, 3, 3, 3), (2, 3, 3, 4), (2, 2, 2, 2, 2, 2), (3, 3, 3, 3, 3, 3), (2, 3, 2, 3, 3, 4)]) | ||
@pytest.mark.parametrize("mode, constant_value", [('constant', 0.0), ('constant', 0.2), ('constant', 5.5), ('constant', -0.1)]) | ||
@pytest.mark.parametrize("seed", [313]) | ||
def test_pad_forward_backward_Nd(seed, inshape_Nd, pad_with_3d, mode, constant_value, ctx, func_name): | ||
pad_forward_backward(seed, inshape_Nd, pad_with_3d, | ||
mode, constant_value, ctx, func_name) |
Oops, something went wrong.