提交 31663640 编写于 作者: T tensor-tang

add seqpool concat unit test

上级 7923d727
...@@ -29,8 +29,6 @@ void FusionSeqPoolConcatOp::InferShape( ...@@ -29,8 +29,6 @@ void FusionSeqPoolConcatOp::InferShape(
int axis = ctx->Attrs().Get<int>("axis"); int axis = ctx->Attrs().Get<int>("axis");
PADDLE_ENFORCE_EQ(axis, 1, PADDLE_ENFORCE_EQ(axis, 1,
"FusionSeqPoolConcatOp only supports concat axis=1 yet."); "FusionSeqPoolConcatOp only supports concat axis=1 yet.");
PADDLE_ENFORCE_EQ(ctx->Attrs().Get<std::string>("pooltype"), "SUM",
"FusionSeqPoolConcatOp only supports sum pool type yet.");
auto ins_dims = ctx->GetInputsDim("X"); auto ins_dims = ctx->GetInputsDim("X");
const size_t n = ins_dims.size(); const size_t n = ins_dims.size();
...@@ -74,6 +72,7 @@ class FusionSeqPoolConcatKernel : public framework::OpKernel<T> { ...@@ -74,6 +72,7 @@ class FusionSeqPoolConcatKernel : public framework::OpKernel<T> {
void Compute(const framework::ExecutionContext& ctx) const override { void Compute(const framework::ExecutionContext& ctx) const override {
auto ins = ctx.MultiInput<LoDTensor>("X"); auto ins = ctx.MultiInput<LoDTensor>("X");
auto* out = ctx.Output<LoDTensor>("Out"); auto* out = ctx.Output<LoDTensor>("Out");
std::string pooltype = ctx.Attr<std::string>("pooltype");
auto x0_lod = ins[0]->lod(); auto x0_lod = ins[0]->lod();
auto x0_dims = ins[0]->dims(); auto x0_dims = ins[0]->dims();
auto y_dims = out->dims(); auto y_dims = out->dims();
...@@ -92,6 +91,11 @@ class FusionSeqPoolConcatKernel : public framework::OpKernel<T> { ...@@ -92,6 +91,11 @@ class FusionSeqPoolConcatKernel : public framework::OpKernel<T> {
PADDLE_ENFORCE_EQ(y_dims[1] % w, 0, PADDLE_ENFORCE_EQ(y_dims[1] % w, 0,
"The output of dims[1] should be dividable of w"); "The output of dims[1] should be dividable of w");
jit::seq_pool_attr_t attr(w, jit::SeqPoolType::kSum); jit::seq_pool_attr_t attr(w, jit::SeqPoolType::kSum);
if (pooltype == "AVERAGE") {
attr.type = jit::SeqPoolType::kAvg;
} else if (pooltype == "SQRT") {
attr.type = jit::SeqPoolType::kSqrt;
}
auto seqpool = auto seqpool =
jit::Get<jit::kSeqPool, jit::SeqPoolTuples<T>, platform::CPUPlace>( jit::Get<jit::kSeqPool, jit::SeqPoolTuples<T>, platform::CPUPlace>(
attr); attr);
......
# Copyright (c) 2018 PaddlePaddle Authors. 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.
from __future__ import print_function
import unittest
import numpy as np
from op_test import OpTest
from test_reorder_lod_tensor import convert_to_offset
from test_seq_pool import compute_seqpool_sum, compute_seqpool_avg, compute_seqpool_sqrt
class TestFusionSeqPoolConcatOp(OpTest):
def setUp(self):
self.w = 11
self.lods = [[[2, 3, 5]], [[1, 5, 2]]]
self.set_conf()
self.set_pooltype()
self.op_type = 'fusion_seqpool_concat'
self.axis = 1
bs = len(self.lods[0][0])
inputs = []
outs = []
i = 0
for lod in self.lods:
assert bs == len(lod[0]), 'All lod size should be equal'
x = np.random.uniform(0.1, 1,
[sum(lod[0]), self.w]).astype('float32')
offset = convert_to_offset(lod)
out = np.zeros((bs, self.w)).astype('float32')
if self.pooltype == "SUM":
compute_seqpool_sum(x, offset, out)
elif self.pooltype == "AVERAGE":
compute_seqpool_avg(x, offset, out)
elif self.pooltype == "SQRT":
compute_seqpool_sqrt(x, offset, out)
else:
raise Exception("Unsupported pool type!")
inputs.append(('x_{0}'.format(i), (x, lod)))
outs.append(out)
i = i + 1
self.inputs = {'X': inputs}
self.outputs = {'Out': np.concatenate(outs, axis=self.axis)}
self.attrs = {
'pooltype': self.pooltype,
'axis': self.axis,
}
def set_pooltype(self):
self.pooltype = "SUM"
def set_conf(self):
pass
def test_check_output(self):
self.check_output()
class TestFusionSeqPoolConcatOpCase1(TestFusionSeqPoolConcatOp):
def set_conf(self):
self.lods = [[[1]]]
class TestFusionSeqPoolConcatOpCase2(TestFusionSeqPoolConcatOp):
def set_conf(self):
self.lods = [[[1]], [[1]], [[1]]]
class TestFusionSeqPoolConcatOpCase3(TestFusionSeqPoolConcatOp):
def set_conf(self):
self.lods = [[[1, 3, 4, 6]]]
self.w = 10
class TestFusionSeqPoolConcatOpCase4(TestFusionSeqPoolConcatOp):
def set_conf(self):
self.lods = [[[2, 13, 4]], [[1, 1, 1]], [[5, 3, 1]], [[9, 10, 3]]]
self.w = 3
## test avg pool and sqrt
def create_test_avg_sqrt_class(parent):
class TestSeqPoolAvgCase(parent):
def set_pooltype(self):
self.pooltype = "AVERAGE"
class TestSeqPoolSqrtCase(parent):
def set_pooltype(self):
self.pooltype = "SQRT"
cls_name_avg = "{0}_{1}".format(parent.__name__, "avg")
cls_name_sqrt = "{0}_{1}".format(parent.__name__, "sqrt")
TestSeqPoolAvgCase.__name__ = cls_name_avg
TestSeqPoolSqrtCase.__name__ = cls_name_sqrt
globals()[cls_name_avg] = TestSeqPoolAvgCase
globals()[cls_name_sqrt] = TestSeqPoolSqrtCase
create_test_avg_sqrt_class(TestFusionSeqPoolConcatOp)
create_test_avg_sqrt_class(TestFusionSeqPoolConcatOpCase1)
create_test_avg_sqrt_class(TestFusionSeqPoolConcatOpCase2)
create_test_avg_sqrt_class(TestFusionSeqPoolConcatOpCase3)
create_test_avg_sqrt_class(TestFusionSeqPoolConcatOpCase4)
if __name__ == '__main__':
unittest.main()
...@@ -22,6 +22,14 @@ import numpy ...@@ -22,6 +22,14 @@ import numpy
import functools import functools
def convert_to_offset(lod):
offset = [[0] for i in lod]
for i, level in enumerate(lod):
for seq_len in level:
offset[i].append(offset[i][-1] + seq_len)
return offset
class TestReorderLoDTensor(unittest.TestCase): class TestReorderLoDTensor(unittest.TestCase):
num_seq = 5 num_seq = 5
# [name, shape, lod_level] pair indicating data info of source and target # [name, shape, lod_level] pair indicating data info of source and target
...@@ -91,13 +99,6 @@ class TestReorderLoDTensor(unittest.TestCase): ...@@ -91,13 +99,6 @@ class TestReorderLoDTensor(unittest.TestCase):
self.inputs[desc[0]] = tensor self.inputs[desc[0]] = tensor
def reorder(self): def reorder(self):
def convert_to_offset(lod):
offset_lod = [[0] for i in lod]
for i, level in enumerate(lod):
for seq_len in level:
offset_lod[i].append(offset_lod[i][-1] + seq_len)
return offset_lod
level = 0 level = 0
# compute the rank_table according to ref_lod # compute the rank_table according to ref_lod
ref_lod = self.data[self.data_desc[1][0]][1][level] ref_lod = self.data[self.data_desc[1][0]][1][level]
......
...@@ -17,33 +17,43 @@ from __future__ import print_function ...@@ -17,33 +17,43 @@ from __future__ import print_function
import unittest import unittest
import numpy as np import numpy as np
from op_test import OpTest from op_test import OpTest
from test_reorder_lod_tensor import convert_to_offset
class TestSeqAvgPool(OpTest): def compute_seqpool_sum(x, offset, out):
def convert_to_offset(self, lod): for i in range(len(offset[0]) - 1):
offset = [[0] for i in lod] sub_x = x[offset[0][i]:offset[0][i + 1], :]
for i, level in enumerate(lod): out[i] = sub_x.sum(axis=0)
for seq_len in level:
offset[i].append(offset[i][-1] + seq_len)
return offset def compute_seqpool_avg(x, offset, out):
for i in range(len(offset[0]) - 1):
sub_x = x[offset[0][i]:offset[0][i + 1], :]
out[i] = sub_x.mean(axis=0)
def compute_seqpool_sqrt(x, offset, out):
for i in range(len(offset[0]) - 1):
sub_x = x[offset[0][i]:offset[0][i + 1], :]
seq_len = offset[0][i + 1] - offset[0][i]
out[i] = sub_x.sum(axis=0) / np.sqrt(seq_len)
class TestSeqAvgPool(OpTest):
def set_data(self): def set_data(self):
self.op_type = 'sequence_pool' self.op_type = 'sequence_pool'
# one level, batch size is 4 # one level, batch size is 4
x = np.random.uniform(0.1, 1, [11, 23]).astype('float32') x = np.random.uniform(0.1, 1, [11, 23]).astype('float32')
lod = [[11]] lod = [[11]]
self.inputs = {'X': (x, lod)} self.inputs = {'X': (x, lod)}
offset = self.convert_to_offset(lod) offset = convert_to_offset(lod)
out = np.zeros((len(lod[0]), 23)).astype('float32') out = np.zeros((len(lod[0]), 23)).astype('float32')
self.outputs = {'Out': out} self.outputs = {'Out': out}
return x, offset, out return x, offset, out
def compute(self, x, offset, out): def compute(self, x, offset, out):
self.attrs = {'pooltype': "AVERAGE"} self.attrs = {'pooltype': "AVERAGE"}
for i in range(len(offset[0]) - 1): compute_seqpool_avg(x, offset, out)
sub_x = x[offset[0][i]:offset[0][i + 1], :]
out[i] = sub_x.mean(axis=0)
def setUp(self): def setUp(self):
x, offset, out = self.set_data() x, offset, out = self.set_data()
...@@ -62,9 +72,7 @@ class TestSeqAvgPool(OpTest): ...@@ -62,9 +72,7 @@ class TestSeqAvgPool(OpTest):
class TestSeqSumPool(TestSeqAvgPool): class TestSeqSumPool(TestSeqAvgPool):
def compute(self, x, offset, out): def compute(self, x, offset, out):
self.attrs = {'pooltype': "SUM"} self.attrs = {'pooltype': "SUM"}
for i in range(len(offset[0]) - 1): compute_seqpool_sum(x, offset, out)
sub_x = x[offset[0][i]:offset[0][i + 1], :]
out[i] = sub_x.sum(axis=0)
class TestSeqMaxPool(TestSeqAvgPool): class TestSeqMaxPool(TestSeqAvgPool):
...@@ -72,7 +80,7 @@ class TestSeqMaxPool(TestSeqAvgPool): ...@@ -72,7 +80,7 @@ class TestSeqMaxPool(TestSeqAvgPool):
self.op_type = 'sequence_pool' self.op_type = 'sequence_pool'
x = np.random.uniform(0.1, 1, [13, 23]).astype('float32') x = np.random.uniform(0.1, 1, [13, 23]).astype('float32')
lod = [[13]] lod = [[13]]
offset = self.convert_to_offset(lod) offset = convert_to_offset(lod)
for i in range(len(offset[0]) - 1): for i in range(len(offset[0]) - 1):
l = offset[0][i + 1] - offset[0][i] l = offset[0][i + 1] - offset[0][i]
x[offset[0][i] + np.random.randint(l), :] += 2.0 x[offset[0][i] + np.random.randint(l), :] += 2.0
...@@ -93,10 +101,7 @@ class TestSeqMaxPool(TestSeqAvgPool): ...@@ -93,10 +101,7 @@ class TestSeqMaxPool(TestSeqAvgPool):
class TestSeqSqrtPool(TestSeqAvgPool): class TestSeqSqrtPool(TestSeqAvgPool):
def compute(self, x, offset, out): def compute(self, x, offset, out):
self.attrs = {'pooltype': "SQRT"} self.attrs = {'pooltype': "SQRT"}
for i in range(len(offset[0]) - 1): compute_seqpool_sqrt(x, offset, out)
sub_x = x[offset[0][i]:offset[0][i + 1], :]
seq_len = offset[0][i + 1] - offset[0][i]
out[i] = sub_x.sum(axis=0) / np.sqrt(seq_len)
class TestSeqLastPool(TestSeqAvgPool): class TestSeqLastPool(TestSeqAvgPool):
...@@ -122,7 +127,7 @@ class TestSeqAvgPool2D(TestSeqAvgPool): ...@@ -122,7 +127,7 @@ class TestSeqAvgPool2D(TestSeqAvgPool):
x = np.random.uniform(0.1, 1, [13, 3, 17]).astype('float32') x = np.random.uniform(0.1, 1, [13, 3, 17]).astype('float32')
lod = [[4, 1, 3, 5]] lod = [[4, 1, 3, 5]]
self.inputs = {'X': (x, lod)} self.inputs = {'X': (x, lod)}
offset = self.convert_to_offset(lod) offset = convert_to_offset(lod)
out = np.zeros((4, 3, 17)).astype('float32') out = np.zeros((4, 3, 17)).astype('float32')
self.outputs = {'Out': out} self.outputs = {'Out': out}
...@@ -167,7 +172,7 @@ class TestSeqMaxPool2D(TestSeqAvgPool2D): ...@@ -167,7 +172,7 @@ class TestSeqMaxPool2D(TestSeqAvgPool2D):
x = np.random.uniform(0.1, 1, [13, 3, 11]).astype('float32') x = np.random.uniform(0.1, 1, [13, 3, 11]).astype('float32')
lod = [[4, 1, 3, 5]] lod = [[4, 1, 3, 5]]
self.inputs = {'X': (x, lod)} self.inputs = {'X': (x, lod)}
offset = self.convert_to_offset(lod) offset = convert_to_offset(lod)
for i in range(len(offset[0]) - 1): for i in range(len(offset[0]) - 1):
l = offset[0][i + 1] - offset[0][i] l = offset[0][i + 1] - offset[0][i]
x[offset[0][i] + np.random.randint(l), :] += 1.0 x[offset[0][i] + np.random.randint(l), :] += 1.0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册