test_seq_pool.py 7.6 KB
Newer Older
1
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
D
dzhwinter 已提交
2
#
D
dzhwinter 已提交
3 4 5
# 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
D
dzhwinter 已提交
6
#
D
dzhwinter 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
D
dzhwinter 已提交
8
#
D
dzhwinter 已提交
9 10 11 12 13 14
# 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.

15 16
from __future__ import print_function

17 18
import unittest
import numpy as np
19
from op_test import OpTest
T
tensor-tang 已提交
20
from test_reorder_lod_tensor import convert_to_offset
21 22


T
tensor-tang 已提交
23 24 25 26 27 28 29 30 31 32 33
def compute_seqpool_sum(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.sum(axis=0)


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)

34

T
tensor-tang 已提交
35 36 37 38 39 40 41 42
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):
43 44
    def set_data(self):
        self.op_type = 'sequence_pool'
45
        # one level, batch size is 4
46
        x = np.random.uniform(0.1, 1, [11, 23]).astype('float32')
C
chengduoZH 已提交
47
        lod = [[11]]
48
        self.inputs = {'X': (x, lod)}
T
tensor-tang 已提交
49
        offset = convert_to_offset(lod)
C
chengduoZH 已提交
50
        out = np.zeros((len(lod[0]), 23)).astype('float32')
51
        self.outputs = {'Out': out}
52
        return x, offset, out
53

54
    def compute(self, x, offset, out):
D
dzhwinter 已提交
55
        self.attrs = {'pooltype': "AVERAGE"}
T
tensor-tang 已提交
56
        compute_seqpool_avg(x, offset, out)
57

58
    def setUp(self):
59 60
        x, offset, out = self.set_data()
        self.compute(x, offset, out)
61 62 63 64 65

    def test_check_output(self):
        self.check_output()

    def test_check_grad(self):
66 67 68
        # Remove MaxIndex after check_grad is refined.
        self.outputs['MaxIndex'] = \
            np.zeros(self.outputs['Out'].shape).astype('int32')
69 70 71
        self.check_grad(["X"], "Out")


D
dzhwinter 已提交
72
class TestSeqSumPool(TestSeqAvgPool):
73
    def compute(self, x, offset, out):
D
dzhwinter 已提交
74
        self.attrs = {'pooltype': "SUM"}
T
tensor-tang 已提交
75
        compute_seqpool_sum(x, offset, out)
D
dzhwinter 已提交
76 77 78 79 80 81


class TestSeqMaxPool(TestSeqAvgPool):
    def set_data(self):
        self.op_type = 'sequence_pool'
        x = np.random.uniform(0.1, 1, [13, 23]).astype('float32')
C
chengduoZH 已提交
82
        lod = [[13]]
T
tensor-tang 已提交
83
        offset = convert_to_offset(lod)
84 85 86
        for i in range(len(offset[0]) - 1):
            l = offset[0][i + 1] - offset[0][i]
            x[offset[0][i] + np.random.randint(l), :] += 2.0
D
dzhwinter 已提交
87 88 89

        self.inputs = {'X': (x, lod)}

C
chengduoZH 已提交
90
        out = np.zeros((1, 23)).astype('float32')
D
dzhwinter 已提交
91
        self.outputs = {'Out': out}
92
        return x, offset, out
D
dzhwinter 已提交
93

94
    def compute(self, x, offset, out):
D
dzhwinter 已提交
95
        self.attrs = {'pooltype': "MAX"}
96 97
        for i in range(len(offset[0]) - 1):
            sub_x = x[offset[0][i]:offset[0][i + 1], :]
D
dzhwinter 已提交
98 99 100 101
            out[i] = np.amax(sub_x, axis=0)


class TestSeqSqrtPool(TestSeqAvgPool):
102
    def compute(self, x, offset, out):
D
dzhwinter 已提交
103
        self.attrs = {'pooltype': "SQRT"}
T
tensor-tang 已提交
104
        compute_seqpool_sqrt(x, offset, out)
D
dzhwinter 已提交
105 106 107


class TestSeqLastPool(TestSeqAvgPool):
108
    def compute(self, x, offset, out):
D
dzhwinter 已提交
109
        self.attrs = {'pooltype': "LAST"}
110 111
        for i in range(len(offset[0]) - 1):
            sub_x = x[offset[0][i]:offset[0][i + 1], :]
D
dzhwinter 已提交
112 113 114 115
            out[i] = sub_x[-1, :]


class TestSeqFirstPool(TestSeqAvgPool):
116
    def compute(self, x, offset, out):
D
dzhwinter 已提交
117
        self.attrs = {'pooltype': "FIRST"}
118 119
        for i in range(len(offset[0]) - 1):
            sub_x = x[offset[0][i]:offset[0][i + 1], :]
D
dzhwinter 已提交
120 121 122
            out[i] = sub_x[0, :]


123 124 125
class TestSeqAvgPool2D(TestSeqAvgPool):
    def set_data(self):
        self.op_type = 'sequence_pool'
126 127
        # one level, batch size is 4
        x = np.random.uniform(0.1, 1, [13, 3, 17]).astype('float32')
128
        lod = [[4, 1, 3, 5]]
129
        self.inputs = {'X': (x, lod)}
T
tensor-tang 已提交
130
        offset = convert_to_offset(lod)
131 132

        out = np.zeros((4, 3, 17)).astype('float32')
133
        self.outputs = {'Out': out}
134
        return x, offset, out
135

136
    def compute(self, x, offset, out):
D
dzhwinter 已提交
137
        self.attrs = {'pooltype': "AVERAGE"}
138 139 140
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 17))
141 142 143
            out[i] = np.reshape(sub_x.mean(axis=0), (3, 17))


144
class TestSeqSumPool2D(TestSeqAvgPool2D):
145
    def compute(self, x, offset, out):
D
dzhwinter 已提交
146
        self.attrs = {'pooltype': "SUM"}
147 148 149
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 17))
150
            out[i] = np.reshape(sub_x.sum(axis=0), (3, 17))
151 152


L
Luo Tao 已提交
153
class TestSeqSqrtPool2D(TestSeqAvgPool2D):
154
    def compute(self, x, offset, out):
D
dzhwinter 已提交
155
        self.attrs = {'pooltype': "SQRT"}
156 157 158 159 160
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 17))
            seq_len = offset[0][i + 1] - offset[0][i]
            out[i] = np.reshape(sub_x.sum(axis=0) / np.sqrt(seq_len), (3, 17))
L
Luo Tao 已提交
161 162

    def test_check_grad(self):
163 164 165
        # Remove MaxIndex after check_grad is refined.
        self.outputs['MaxIndex'] = \
            np.zeros(self.outputs['Out'].shape).astype('int32')
L
Luo Tao 已提交
166 167 168
        self.check_grad(["X"], "Out", max_relative_error=0.06)


L
Luo Tao 已提交
169
class TestSeqMaxPool2D(TestSeqAvgPool2D):
170 171 172
    def set_data(self):
        self.op_type = 'sequence_pool'
        x = np.random.uniform(0.1, 1, [13, 3, 11]).astype('float32')
173
        lod = [[4, 1, 3, 5]]
174
        self.inputs = {'X': (x, lod)}
T
tensor-tang 已提交
175
        offset = convert_to_offset(lod)
176 177 178
        for i in range(len(offset[0]) - 1):
            l = offset[0][i + 1] - offset[0][i]
            x[offset[0][i] + np.random.randint(l), :] += 1.0
179 180 181

        out = np.zeros((4, 3, 11)).astype('float32')
        self.outputs = {'Out': out}
182
        return x, offset, out
183

184
    def compute(self, x, offset, out):
D
dzhwinter 已提交
185
        self.attrs = {'pooltype': "MAX"}
186 187 188
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 11))
189
            out[i] = np.reshape(np.amax(sub_x, axis=0), (3, 11))
L
Luo Tao 已提交
190 191


J
Jacek Czaja 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204 205
class TestSeqMaxPool2DInference(TestSeqMaxPool2D):
    def compute(self, x, offset, out):
        self.attrs = {'pooltype': "MAX", 'is_test': True}
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 11))
            out[i] = np.reshape(np.amax(sub_x, axis=0), (3, 11))

    def test_check_grad(self):
        """Grad computation does not apply to Sequence MAX 
            Pool executed when is_test is true """
        return


L
Luo Tao 已提交
206
class TestSeqLastPool2D(TestSeqAvgPool2D):
207
    def compute(self, x, offset, out):
D
dzhwinter 已提交
208
        self.attrs = {'pooltype': "LAST"}
209 210 211
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 17))
L
Luo Tao 已提交
212 213 214 215
            out[i] = np.reshape(sub_x[-1, :], (3, 17))


class TestSeqFirstPool2D(TestSeqAvgPool2D):
216
    def compute(self, x, offset, out):
D
dzhwinter 已提交
217
        self.attrs = {'pooltype': "FIRST"}
218 219 220
        for i in range(len(offset[0]) - 1):
            sub_x = np.reshape(x[offset[0][i]:offset[0][i + 1], :],
                               (-1, 3 * 17))
L
Luo Tao 已提交
221 222 223
            out[i] = np.reshape(sub_x[0, :], (3, 17))


224 225
if __name__ == '__main__':
    unittest.main()