1# Copyright 2018 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 separable convolutional layers.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21from absl.testing import parameterized 22import numpy as np 23 24from tensorflow.python import keras 25from tensorflow.python.keras import keras_parameterized 26from tensorflow.python.keras import testing_utils 27from tensorflow.python.platform import test 28 29 30@keras_parameterized.run_all_keras_modes 31class SeparableConv1DTest(keras_parameterized.TestCase): 32 33 def _run_test(self, kwargs): 34 num_samples = 2 35 stack_size = 3 36 length = 7 37 38 with self.cached_session(use_gpu=True): 39 testing_utils.layer_test( 40 keras.layers.SeparableConv1D, 41 kwargs=kwargs, 42 input_shape=(num_samples, length, stack_size)) 43 44 @parameterized.named_parameters( 45 ('padding_valid', {'padding': 'valid'}), 46 ('padding_same', {'padding': 'same'}), 47 ('padding_same_dilation_2', {'padding': 'same', 'dilation_rate': 2}), 48 ('padding_causal', {'padding': 'causal'}), 49 ('strides', {'strides': 2}), 50 ('dilation_rate', {'dilation_rate': 2}), 51 ('depth_multiplier', {'depth_multiplier': 2}), 52 ) 53 def test_separable_conv1d(self, kwargs): 54 kwargs['filters'] = 2 55 kwargs['kernel_size'] = 3 56 self._run_test(kwargs) 57 58 def test_separable_conv1d_regularizers(self): 59 kwargs = { 60 'filters': 3, 61 'kernel_size': 3, 62 'padding': 'valid', 63 'depthwise_regularizer': 'l2', 64 'pointwise_regularizer': 'l2', 65 'bias_regularizer': 'l2', 66 'activity_regularizer': 'l2', 67 'strides': 1 68 } 69 with self.cached_session(use_gpu=True): 70 layer = keras.layers.SeparableConv1D(**kwargs) 71 layer.build((None, 5, 2)) 72 self.assertEqual(len(layer.losses), 3) 73 layer(keras.backend.variable(np.ones((1, 5, 2)))) 74 self.assertEqual(len(layer.losses), 4) 75 76 def test_separable_conv1d_constraints(self): 77 d_constraint = lambda x: x 78 p_constraint = lambda x: x 79 b_constraint = lambda x: x 80 81 kwargs = { 82 'filters': 3, 83 'kernel_size': 3, 84 'padding': 'valid', 85 'pointwise_constraint': p_constraint, 86 'depthwise_constraint': d_constraint, 87 'bias_constraint': b_constraint, 88 'strides': 1 89 } 90 with self.cached_session(use_gpu=True): 91 layer = keras.layers.SeparableConv1D(**kwargs) 92 layer.build((None, 5, 2)) 93 self.assertEqual(layer.depthwise_kernel.constraint, d_constraint) 94 self.assertEqual(layer.pointwise_kernel.constraint, p_constraint) 95 self.assertEqual(layer.bias.constraint, b_constraint) 96 97 98@keras_parameterized.run_all_keras_modes 99class SeparableConv2DTest(keras_parameterized.TestCase): 100 101 def _run_test(self, kwargs): 102 num_samples = 2 103 stack_size = 3 104 num_row = 7 105 num_col = 6 106 107 with self.cached_session(use_gpu=True): 108 testing_utils.layer_test( 109 keras.layers.SeparableConv2D, 110 kwargs=kwargs, 111 input_shape=(num_samples, num_row, num_col, stack_size)) 112 113 @parameterized.named_parameters( 114 ('padding_valid', {'padding': 'valid'}), 115 ('padding_same', {'padding': 'same'}), 116 ('padding_same_dilation_2', {'padding': 'same', 'dilation_rate': 2}), 117 ('strides', {'strides': 2}), 118 # Only runs on GPU with CUDA, channels_first is not supported on CPU. 119 # TODO(b/62340061): Support channels_first on CPU. 120 ('data_format', {'data_format': 'channels_first'}), 121 ('dilation_rate', {'dilation_rate': 2}), 122 ('depth_multiplier', {'depth_multiplier': 2}), 123 ) 124 def test_separable_conv2d(self, kwargs): 125 kwargs['filters'] = 2 126 kwargs['kernel_size'] = 3 127 if 'data_format' not in kwargs or test.is_gpu_available(cuda_only=True): 128 self._run_test(kwargs) 129 130 def test_separable_conv2d_regularizers(self): 131 kwargs = { 132 'filters': 3, 133 'kernel_size': 3, 134 'padding': 'valid', 135 'depthwise_regularizer': 'l2', 136 'pointwise_regularizer': 'l2', 137 'bias_regularizer': 'l2', 138 'activity_regularizer': 'l2', 139 'strides': 1 140 } 141 with self.cached_session(use_gpu=True): 142 layer = keras.layers.SeparableConv2D(**kwargs) 143 layer.build((None, 5, 5, 2)) 144 self.assertEqual(len(layer.losses), 3) 145 layer(keras.backend.variable(np.ones((1, 5, 5, 2)))) 146 self.assertEqual(len(layer.losses), 4) 147 148 def test_separable_conv2d_constraints(self): 149 d_constraint = lambda x: x 150 p_constraint = lambda x: x 151 b_constraint = lambda x: x 152 153 kwargs = { 154 'filters': 3, 155 'kernel_size': 3, 156 'padding': 'valid', 157 'pointwise_constraint': p_constraint, 158 'depthwise_constraint': d_constraint, 159 'bias_constraint': b_constraint, 160 'strides': 1 161 } 162 with self.cached_session(use_gpu=True): 163 layer = keras.layers.SeparableConv2D(**kwargs) 164 layer.build((None, 5, 5, 2)) 165 self.assertEqual(layer.depthwise_kernel.constraint, d_constraint) 166 self.assertEqual(layer.pointwise_kernel.constraint, p_constraint) 167 self.assertEqual(layer.bias.constraint, b_constraint) 168