Home | History | Annotate | Download | only in kernel_tests
      1 # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 # ==============================================================================
     15 """Tests for shape_ops."""
     16 
     17 from __future__ import absolute_import
     18 from __future__ import division
     19 from __future__ import print_function
     20 
     21 import numpy as np
     22 
     23 from tensorflow.contrib.signal.python.kernel_tests import test_util
     24 from tensorflow.contrib.signal.python.ops import shape_ops
     25 from tensorflow.python.framework import constant_op
     26 from tensorflow.python.framework import dtypes
     27 from tensorflow.python.framework import ops
     28 from tensorflow.python.ops import array_ops
     29 from tensorflow.python.ops import math_ops
     30 from tensorflow.python.platform import test
     31 
     32 
     33 class FrameTest(test.TestCase):
     34 
     35   def test_mapping_of_indices_without_padding(self):
     36     with self.test_session(use_gpu=True):
     37       tensor = constant_op.constant(np.arange(9152), dtypes.int32)
     38       tensor = array_ops.expand_dims(tensor, 0)
     39 
     40       result = shape_ops.frame(tensor, 512, 180, pad_end=False).eval()
     41 
     42       expected = np.tile(np.arange(512), (49, 1))
     43       expected += np.tile(np.arange(49) * 180, (512, 1)).T
     44 
     45       expected = np.expand_dims(expected, axis=0)
     46       expected = np.array(expected, dtype=np.int32)
     47 
     48       self.assertAllEqual(expected, result)
     49 
     50   def test_mapping_of_indices_with_padding(self):
     51     with self.test_session(use_gpu=True):
     52       tensor = constant_op.constant(np.arange(10000), dtypes.int32)
     53       tensor = array_ops.expand_dims(tensor, 0)
     54 
     55       result = shape_ops.frame(tensor, 512, 192, pad_end=True).eval()
     56 
     57       expected = np.tile(np.arange(512), (53, 1))
     58       expected += np.tile(np.arange(53) * 192, (512, 1)).T
     59 
     60       expected[expected >= 10000] = 0
     61 
     62       expected = np.expand_dims(expected, axis=0)
     63       expected = np.array(expected, dtype=np.int32)
     64 
     65       self.assertAllEqual(expected, result)
     66 
     67   def test_invalid_inputs(self):
     68     # Rank 0 input signal.
     69     with self.assertRaises(ValueError):
     70       shape_ops.frame(1, 1, 1)
     71 
     72     # If the rank is unknown, do not raise an exception.
     73     shape_ops.frame(array_ops.placeholder(dtypes.float32), 1, 1)
     74 
     75     # Non-scalar frame_length.
     76     with self.assertRaises(ValueError):
     77       shape_ops.frame([1], [1], 1)
     78 
     79     # Non-scalar frame_step.
     80     with self.assertRaises(ValueError):
     81       shape_ops.frame([1], 1, [1])
     82 
     83     # Non-scalar pad_value.
     84     with self.assertRaises(ValueError):
     85       shape_ops.frame([1], 1, 1, pad_end=True, pad_value=[1])
     86 
     87   def test_length_zero(self):
     88     signal = constant_op.constant([], dtype=dtypes.float32)
     89     frame_length = 2
     90     frame_step = 1
     91 
     92     with self.test_session(use_gpu=True):
     93       result = shape_ops.frame(signal, frame_length, frame_step,
     94                                pad_end=True, pad_value=99).eval()
     95       self.assertEqual((0, 2), result.shape)
     96 
     97       result = shape_ops.frame(signal, frame_length, frame_step,
     98                                pad_end=False).eval()
     99       self.assertEqual((0, 2), result.shape)
    100 
    101   def test_shape_inference(self):
    102     signal = array_ops.placeholder(dtypes.int32, shape=[1, 1])
    103     frame_length = 2
    104     frame_step = 1
    105     # Shape inference is able to detect the rank and inner-most dimension
    106     # if frame_length is known at graph definition time.
    107     result = shape_ops.frame(signal, frame_length, frame_step,
    108                              pad_end=True, pad_value=99)
    109     self.assertEqual([1, 1, 2], result.shape.as_list())
    110 
    111     result = shape_ops.frame(signal, frame_length, frame_step,
    112                              pad_end=False)
    113     self.assertEqual([1, 0, 2], result.shape.as_list())
    114 
    115     # If frame_length is not known, rank and (known) outer and inner dimensions
    116     # are inferred.
    117     signal = array_ops.placeholder(dtypes.int32, shape=[1, 2, 3, 4])
    118     frame_length = array_ops.placeholder(dtypes.int32, shape=[])
    119     frame_step = 1
    120     result = shape_ops.frame(signal, frame_length, frame_step,
    121                              pad_end=True, pad_value=99, axis=1)
    122     self.assertEqual([1, None, None, 3, 4], result.shape.as_list())
    123 
    124     result = shape_ops.frame(signal, frame_length, frame_step,
    125                              pad_end=False, axis=1)
    126     self.assertEqual([1, None, None, 3, 4], result.shape.as_list())
    127 
    128     # If frame_length and inner-most dimension is known, rank, inner dimensions,
    129     # and known outer dimensions are inferred.
    130     signal = array_ops.placeholder(dtypes.int32,
    131                                    shape=[None, 5, None, 20, 5, 3])
    132     frame_length = 4
    133     frame_step = 3
    134     result = shape_ops.frame(signal, frame_length, frame_step,
    135                              pad_end=True, pad_value=99, axis=3)
    136     self.assertEqual([None, 5, None, 7, 4, 5, 3], result.shape.as_list())
    137 
    138     result = shape_ops.frame(signal, frame_length, frame_step,
    139                              pad_end=False, axis=3)
    140     self.assertEqual([None, 5, None, 6, 4, 5, 3], result.shape.as_list())
    141 
    142     # Test that shape inference is consistent with actual returned shapes for
    143     # small values of signal_length, frame_length, frame_step, and pad_end in
    144     # [True, False].
    145     frame_step = 1
    146     for signal_length in range(2):
    147       signal = [0] * signal_length
    148       for frame_length in range(2):
    149         for pad_end in [False, True]:
    150           op = shape_ops.frame(signal, frame_length, frame_step,
    151                                pad_end=pad_end, pad_value=99)
    152           with self.test_session(use_gpu=True):
    153             result = op.eval()
    154           self.assertEqual(op.shape.as_list(), list(result.shape))
    155 
    156   def test_basic_mono(self):
    157     signal = np.arange(6)
    158     frame_length = 3
    159     frame_step = 2
    160 
    161     with self.test_session(use_gpu=True):
    162       for rank in range(5):
    163         nd_signal = np.reshape(signal, (1,) * rank + signal.shape)
    164 
    165         # With padding, we pad the last frame with pad_value.
    166         result = shape_ops.frame(nd_signal, frame_length, frame_step,
    167                                  pad_end=True, pad_value=99).eval()
    168         expected_inner_frames = np.array([[0, 1, 2], [2, 3, 4], [4, 5, 99]])
    169         expected = np.reshape(
    170             expected_inner_frames, (1,) * rank + expected_inner_frames.shape)
    171         self.assertAllEqual(expected, result)
    172 
    173         # Without padding, we drop the last frame.
    174         expected_inner_frames = np.array([[0, 1, 2], [2, 3, 4]])
    175         expected = np.reshape(
    176             expected_inner_frames, (1,) * rank + expected_inner_frames.shape)
    177         result = shape_ops.frame(nd_signal, frame_length, frame_step,
    178                                  pad_end=False).eval()
    179         self.assertAllEqual(expected, result)
    180 
    181   def test_basic_stereo(self):
    182     signal = np.vstack([np.arange(6),
    183                         np.arange(6) + 10])
    184     frame_length = 3
    185     frame_step = 2
    186 
    187     with self.test_session(use_gpu=True):
    188       for rank in range(5):
    189         nd_signal = np.reshape(signal, (1,) * rank + signal.shape)
    190 
    191         # With padding, we pad the last frame with pad_value.
    192         result = shape_ops.frame(nd_signal, frame_length, frame_step,
    193                                  pad_end=True, pad_value=99).eval()
    194         expected_inner_frames = np.array([
    195             [[0, 1, 2], [2, 3, 4], [4, 5, 99]],
    196             [[10, 11, 12], [12, 13, 14], [14, 15, 99]]])
    197         expected = np.reshape(
    198             expected_inner_frames, (1,) * rank + expected_inner_frames.shape)
    199         self.assertAllEqual(expected, result)
    200 
    201         # Without padding, we drop the last frame.
    202         expected_inner_frames = np.array([[[0, 1, 2], [2, 3, 4]],
    203                                           [[10, 11, 12], [12, 13, 14]]])
    204         expected = np.reshape(
    205             expected_inner_frames, (1,) * rank + expected_inner_frames.shape)
    206         result = shape_ops.frame(nd_signal, frame_length, frame_step,
    207                                  pad_end=False).eval()
    208         self.assertAllEqual(expected, result)
    209 
    210   def test_complex_shape(self):
    211     signal = np.vstack([np.arange(6),
    212                         np.arange(6) + 10,
    213                         np.arange(6) + 20,
    214                         np.arange(6) + 30,
    215                         np.arange(6) + 40,
    216                         np.arange(6) + 50])
    217     signal = np.reshape(signal, (2, 1, 3, 1, 6))
    218     frame_length = 3
    219     frame_step = 2
    220 
    221     with self.test_session(use_gpu=True):
    222       # With padding, we pad the last frame with pad_value.
    223       result = shape_ops.frame(signal, frame_length, frame_step,
    224                                pad_end=True, pad_value=99).eval()
    225       # Resulting shape is (2, 1, 3, 1, 3, 3).
    226       expected = [[[[[[0, 1, 2], [2, 3, 4], [4, 5, 99]]],
    227                     [[[10, 11, 12], [12, 13, 14], [14, 15, 99]]],
    228                     [[[20, 21, 22], [22, 23, 24], [24, 25, 99]]]]],
    229                   [[[[[30, 31, 32], [32, 33, 34], [34, 35, 99]]],
    230                     [[[40, 41, 42], [42, 43, 44], [44, 45, 99]]],
    231                     [[[50, 51, 52], [52, 53, 54], [54, 55, 99]]]]]]
    232       self.assertAllEqual(expected, result)
    233 
    234       result = shape_ops.frame(signal, frame_length, frame_step,
    235                                pad_end=False).eval()
    236       # Resulting shape is (2, 1, 3, 1, 3, 2).
    237       expected = [[[[[[0, 1, 2], [2, 3, 4]]],
    238                     [[[10, 11, 12], [12, 13, 14]]],
    239                     [[[20, 21, 22], [22, 23, 24]]]]],
    240                   [[[[[30, 31, 32], [32, 33, 34]]],
    241                     [[[40, 41, 42], [42, 43, 44]]],
    242                     [[[50, 51, 52], [52, 53, 54]]]]]]
    243       self.assertAllEqual(expected, result)
    244 
    245   def test_axis(self):
    246     signal = np.reshape(np.arange(16), (2, 4, 2))
    247     with self.test_session(use_gpu=True):
    248       result = shape_ops.frame(signal, frame_length=2, frame_step=2,
    249                                pad_end=True, axis=1)
    250       expected = np.reshape(np.arange(16), (2, 2, 2, 2))
    251       self.assertAllEqual(expected, result.eval())
    252 
    253       result = shape_ops.frame(signal, frame_length=2, frame_step=1,
    254                                pad_end=True, axis=1)
    255       expected = [[[[0, 1], [2, 3]],
    256                    [[2, 3], [4, 5]],
    257                    [[4, 5], [6, 7]],
    258                    [[6, 7], [0, 0]]],
    259                   [[[8, 9], [10, 11]],
    260                    [[10, 11], [12, 13]],
    261                    [[12, 13], [14, 15]],
    262                    [[14, 15], [0, 0]]]]
    263       self.assertAllEqual(expected, result.eval())
    264 
    265       result = shape_ops.frame(signal, frame_length=3, frame_step=1,
    266                                pad_end=True, axis=1)
    267       expected = [[[[0, 1], [2, 3], [4, 5]],
    268                    [[2, 3], [4, 5], [6, 7]],
    269                    [[4, 5], [6, 7], [0, 0]],
    270                    [[6, 7], [0, 0], [0, 0]]],
    271                   [[[8, 9], [10, 11], [12, 13]],
    272                    [[10, 11], [12, 13], [14, 15]],
    273                    [[12, 13], [14, 15], [0, 0]],
    274                    [[14, 15], [0, 0], [0, 0]]]]
    275       self.assertAllEqual(expected, result.eval())
    276 
    277   def test_window_larger_than_signal(self):
    278     signal = constant_op.constant([[1, 2], [11, 12]], dtype=dtypes.float32)
    279     frame_length = 4
    280     frame_step = 1
    281 
    282     with self.test_session(use_gpu=True):
    283       result = shape_ops.frame(signal, frame_length, frame_step,
    284                                pad_end=True, pad_value=99).eval()
    285       self.assertAllClose([[[1, 2, 99, 99], [2, 99, 99, 99]],
    286                            [[11, 12, 99, 99], [12, 99, 99, 99]]], result)
    287 
    288       result = shape_ops.frame(signal, frame_length, frame_step,
    289                                pad_end=False).eval()
    290       self.assertEqual((2, 0, 4), result.shape)
    291 
    292       frame_step = 2
    293       result = shape_ops.frame(signal, frame_length, frame_step,
    294                                pad_end=True, pad_value=99).eval()
    295       self.assertAllClose([[[1, 2, 99, 99]], [[11, 12, 99, 99]]], result)
    296 
    297       result = shape_ops.frame(signal, frame_length, frame_step,
    298                                pad_end=False).eval()
    299       self.assertEqual((2, 0, 4), result.shape)
    300 
    301   def test_preserves_type(self):
    302     signal = math_ops.range(10, dtype=dtypes.float64)
    303     frame_length = 2
    304     frame_step = 3
    305 
    306     with self.test_session(use_gpu=True):
    307       result = shape_ops.frame(signal, frame_length, frame_step)
    308       self.assertEqual(result.dtype, signal.dtype)
    309 
    310   def test_dynamic_tensor(self):
    311     # Show that frame works even when the dimensions of its input are
    312     # not known at graph creation time.
    313     input_signal = np.vstack([np.arange(4), np.arange(4) + 10,
    314                               np.arange(4) + 20])
    315     frame_length = 2
    316     frame_step = 2
    317 
    318     with self.test_session(use_gpu=True) as sess:
    319       signal_placeholder = array_ops.placeholder(shape=(None, None),
    320                                                  dtype=dtypes.float32)
    321       result = sess.run(shape_ops.frame(
    322           signal_placeholder, frame_length, frame_step),
    323                         feed_dict={signal_placeholder: input_signal})
    324       self.assertAllEqual([[[0, 1], [2, 3]],
    325                            [[10, 11], [12, 13]],
    326                            [[20, 21], [22, 23]]], result)
    327 
    328   def test_gradient_numerical(self):
    329     with self.test_session(use_gpu=True):
    330       signal_shape = (2, 128)
    331       signal = array_ops.ones(signal_shape)
    332       frame_length = 33
    333       frame_step = 9
    334       frames = shape_ops.frame(signal, frame_length, frame_step)
    335       error = test.compute_gradient_error(
    336           signal, signal_shape, frames, frames.shape.as_list())
    337       self.assertLess(error, 2e-5)
    338 
    339   def test_constant_folding(self):
    340     """frame should be constant foldable for constant inputs."""
    341     for pad_end in [False, True]:
    342       g = ops.Graph()
    343       with g.as_default():
    344         frame_length, frame_step = 32, 16
    345         signal_shape = (2, 128)
    346         signal = array_ops.ones(signal_shape)
    347         frames = shape_ops.frame(signal, frame_length, frame_step,
    348                                  pad_end=pad_end)
    349         rewritten_graph = test_util.grappler_optimize(g, [frames])
    350         self.assertEqual(1, len(rewritten_graph.node))
    351 
    352 
    353 if __name__ == "__main__":
    354   test.main()
    355