1# Copyright 2016 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 GRU layer.""" 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.eager import context 26from tensorflow.python.framework import test_util as tf_test_util 27from tensorflow.python.keras import keras_parameterized 28from tensorflow.python.keras import testing_utils 29from tensorflow.python.platform import test 30 31 32@keras_parameterized.run_all_keras_modes 33class GRULayerTest(keras_parameterized.TestCase): 34 35 def test_return_sequences_GRU(self): 36 num_samples = 2 37 timesteps = 3 38 embedding_dim = 4 39 units = 2 40 testing_utils.layer_test( 41 keras.layers.GRU, 42 kwargs={'units': units, 43 'return_sequences': True}, 44 input_shape=(num_samples, timesteps, embedding_dim)) 45 46 def test_dynamic_behavior_GRU(self): 47 num_samples = 2 48 timesteps = 3 49 embedding_dim = 4 50 units = 2 51 layer = keras.layers.GRU(units, input_shape=(None, embedding_dim)) 52 model = keras.models.Sequential() 53 model.add(layer) 54 model.compile( 55 'rmsprop', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 56 x = np.random.random((num_samples, timesteps, embedding_dim)) 57 y = np.random.random((num_samples, units)) 58 model.train_on_batch(x, y) 59 60 def test_dropout_GRU(self): 61 num_samples = 2 62 timesteps = 3 63 embedding_dim = 4 64 units = 2 65 testing_utils.layer_test( 66 keras.layers.GRU, 67 kwargs={'units': units, 68 'dropout': 0.1, 69 'recurrent_dropout': 0.1}, 70 input_shape=(num_samples, timesteps, embedding_dim)) 71 72 @parameterized.parameters([0, 1, 2]) 73 def test_implementation_mode_GRU(self, implementation_mode): 74 num_samples = 2 75 timesteps = 3 76 embedding_dim = 4 77 units = 2 78 testing_utils.layer_test( 79 keras.layers.GRU, 80 kwargs={'units': units, 81 'implementation': implementation_mode}, 82 input_shape=(num_samples, timesteps, embedding_dim)) 83 84 def test_reset_after_GRU(self): 85 num_samples = 2 86 timesteps = 3 87 embedding_dim = 4 88 units = 2 89 90 (x_train, y_train), _ = testing_utils.get_test_data( 91 train_samples=num_samples, 92 test_samples=0, 93 input_shape=(timesteps, embedding_dim), 94 num_classes=units) 95 y_train = keras.utils.to_categorical(y_train, units) 96 97 inputs = keras.layers.Input(shape=[timesteps, embedding_dim]) 98 gru_layer = keras.layers.GRU(units, 99 reset_after=True) 100 output = gru_layer(inputs) 101 gru_model = keras.models.Model(inputs, output) 102 gru_model.compile( 103 'rmsprop', 'mse', run_eagerly=testing_utils.should_run_eagerly()) 104 gru_model.fit(x_train, y_train) 105 gru_model.predict(x_train) 106 107 def test_with_masking_layer_GRU(self): 108 layer_class = keras.layers.GRU 109 inputs = np.random.random((2, 3, 4)) 110 targets = np.abs(np.random.random((2, 3, 5))) 111 targets /= targets.sum(axis=-1, keepdims=True) 112 model = keras.models.Sequential() 113 model.add(keras.layers.Masking(input_shape=(3, 4))) 114 model.add(layer_class(units=5, return_sequences=True, unroll=False)) 115 model.compile( 116 loss='categorical_crossentropy', 117 optimizer='rmsprop', 118 run_eagerly=testing_utils.should_run_eagerly()) 119 model.fit(inputs, targets, epochs=1, batch_size=2, verbose=1) 120 121 def test_statefulness_GRU(self): 122 num_samples = 2 123 timesteps = 3 124 embedding_dim = 4 125 units = 2 126 layer_class = keras.layers.GRU 127 128 model = keras.models.Sequential() 129 model.add( 130 keras.layers.Embedding( 131 4, 132 embedding_dim, 133 mask_zero=True, 134 input_length=timesteps, 135 batch_input_shape=(num_samples, timesteps))) 136 layer = layer_class( 137 units, return_sequences=False, stateful=True, weights=None) 138 model.add(layer) 139 model.compile(optimizer='sgd', loss='mse', 140 run_eagerly=testing_utils.should_run_eagerly()) 141 out1 = model.predict(np.ones((num_samples, timesteps))) 142 self.assertEqual(out1.shape, (num_samples, units)) 143 144 # train once so that the states change 145 model.train_on_batch( 146 np.ones((num_samples, timesteps)), np.ones((num_samples, units))) 147 out2 = model.predict(np.ones((num_samples, timesteps))) 148 149 # if the state is not reset, output should be different 150 self.assertNotEqual(out1.max(), out2.max()) 151 152 # check that output changes after states are reset 153 # (even though the model itself didn't change) 154 layer.reset_states() 155 out3 = model.predict(np.ones((num_samples, timesteps))) 156 self.assertNotEqual(out2.max(), out3.max()) 157 158 # check that container-level reset_states() works 159 model.reset_states() 160 out4 = model.predict(np.ones((num_samples, timesteps))) 161 np.testing.assert_allclose(out3, out4, atol=1e-5) 162 163 # check that the call to `predict` updated the states 164 out5 = model.predict(np.ones((num_samples, timesteps))) 165 self.assertNotEqual(out4.max(), out5.max()) 166 167 # Check masking 168 layer.reset_states() 169 170 left_padded_input = np.ones((num_samples, timesteps)) 171 left_padded_input[0, :1] = 0 172 left_padded_input[1, :2] = 0 173 out6 = model.predict(left_padded_input) 174 175 layer.reset_states() 176 177 right_padded_input = np.ones((num_samples, timesteps)) 178 right_padded_input[0, -1:] = 0 179 right_padded_input[1, -2:] = 0 180 out7 = model.predict(right_padded_input) 181 182 np.testing.assert_allclose(out7, out6, atol=1e-5) 183 184 185@tf_test_util.run_all_in_graph_and_eager_modes 186class GRULayerGenericTest(test.TestCase): 187 188 def test_constraints_GRU(self): 189 embedding_dim = 4 190 layer_class = keras.layers.GRU 191 k_constraint = keras.constraints.max_norm(0.01) 192 r_constraint = keras.constraints.max_norm(0.01) 193 b_constraint = keras.constraints.max_norm(0.01) 194 layer = layer_class( 195 5, 196 return_sequences=False, 197 weights=None, 198 input_shape=(None, embedding_dim), 199 kernel_constraint=k_constraint, 200 recurrent_constraint=r_constraint, 201 bias_constraint=b_constraint) 202 layer.build((None, None, embedding_dim)) 203 self.assertEqual(layer.cell.kernel.constraint, k_constraint) 204 self.assertEqual(layer.cell.recurrent_kernel.constraint, r_constraint) 205 self.assertEqual(layer.cell.bias.constraint, b_constraint) 206 207 def test_from_config_GRU(self): 208 layer_class = keras.layers.GRU 209 for stateful in (False, True): 210 l1 = layer_class(units=1, stateful=stateful) 211 l2 = layer_class.from_config(l1.get_config()) 212 assert l1.get_config() == l2.get_config() 213 214 def test_regularizers_GRU(self): 215 embedding_dim = 4 216 layer_class = keras.layers.GRU 217 layer = layer_class( 218 5, 219 return_sequences=False, 220 weights=None, 221 input_shape=(None, embedding_dim), 222 kernel_regularizer=keras.regularizers.l1(0.01), 223 recurrent_regularizer=keras.regularizers.l1(0.01), 224 bias_regularizer='l2', 225 activity_regularizer='l1') 226 layer.build((None, None, 2)) 227 self.assertEqual(len(layer.losses), 3) 228 229 x = keras.backend.variable(np.ones((2, 3, 2))) 230 layer(x) 231 if context.executing_eagerly(): 232 self.assertEqual(len(layer.losses), 4) 233 else: 234 self.assertEqual(len(layer.get_losses_for(x)), 1) 235 236 237if __name__ == '__main__': 238 test.main() 239