@@ -826,13 +826,12 @@ def get_test_model_sequential() -> Model:
826826
827827
828828def get_test_model_recurrent () -> Model :
829- """Returns a test model exercising LSTM, GRU, SimpleRNN, Bidirectional, and other newer layers."""
829+ """Returns a test model exercising recurrent layers (LSTM, GRU, SimpleRNN,
830+ Bidirectional, RNN with cells, ConvLSTM, Masking)."""
830831 seq_len = 5
831832 n_features = 4
832833
833834 inputs = Input (shape = (seq_len , n_features ))
834- inputs_2d = Input (shape = (7 , 8 , 4 ))
835- inputs_3d = Input (shape = (5 , 6 , 7 , 4 ))
836835
837836 lstm_seq = LSTM (6 , return_sequences = True )(inputs )
838837 lstm_last = LSTM (7 )(lstm_seq )
@@ -857,6 +856,79 @@ def get_test_model_recurrent() -> Model:
857856 bidi_gru_ave = Bidirectional (GRU (4 ), merge_mode = 'ave' )(inputs )
858857 bidi_rnn_concat = Bidirectional (SimpleRNN (3 , return_sequences = True ))(inputs )
859858
859+ masked = Masking (mask_value = 0.0 )(inputs )
860+
861+ rnn_lstm = RNN (LSTMCell (4 ))(inputs )
862+ rnn_gru = RNN (GRUCell (5 ), return_sequences = True )(inputs )
863+ rnn_simple = RNN (SimpleRNNCell (3 ))(inputs )
864+ rnn_stacked = RNN (StackedRNNCells ([LSTMCell (6 ), GRUCell (4 ), SimpleRNNCell (3 )]))(inputs )
865+ rnn_stacked_seq = RNN (StackedRNNCells ([LSTMCell (5 ), GRUCell (3 )]),
866+ return_sequences = True )(inputs )
867+
868+ inputs_clstm1d = Input (shape = (4 , 6 , 3 ))
869+ inputs_clstm2d = Input (shape = (3 , 5 , 5 , 3 ))
870+ inputs_clstm3d = Input (shape = (2 , 3 , 4 , 4 , 3 ))
871+ clstm1d = ConvLSTM1D (filters = 2 , kernel_size = 3 , padding = 'same' )(inputs_clstm1d )
872+ clstm1d_valid = ConvLSTM1D (filters = 2 , kernel_size = 2 , padding = 'valid' ,
873+ return_sequences = True )(inputs_clstm1d )
874+ clstm1d_dilated = ConvLSTM1D (filters = 2 , kernel_size = 2 , padding = 'same' ,
875+ dilation_rate = 2 )(inputs_clstm1d )
876+ clstm2d = ConvLSTM2D (filters = 2 , kernel_size = (3 , 3 ), padding = 'same' ,
877+ return_sequences = True )(inputs_clstm2d )
878+ clstm2d_valid_no_bias = ConvLSTM2D (filters = 3 , kernel_size = (2 , 2 ), padding = 'valid' ,
879+ use_bias = False , activation = 'relu' )(inputs_clstm2d )
880+ # Two ConvLSTM2Ds chained: validates state handoff between successive temporal layers.
881+ clstm2d_chained = ConvLSTM2D (filters = 2 , kernel_size = (2 , 2 ), padding = 'same' )(
882+ ConvLSTM2D (filters = 3 , kernel_size = (3 , 3 ), padding = 'same' ,
883+ return_sequences = True )(inputs_clstm2d ))
884+ clstm3d = ConvLSTM3D (filters = 2 , kernel_size = (2 , 2 , 2 ), padding = 'same' )(inputs_clstm3d )
885+ clstm3d_valid = ConvLSTM3D (filters = 2 , kernel_size = (1 , 2 , 2 ), padding = 'valid' ,
886+ return_sequences = True )(inputs_clstm3d )
887+
888+ outputs = [
889+ lstm_last , lstm_no_bias , lstm_relu , lstm_no_unit_forget ,
890+ lstm_state_out , lstm_state_h , lstm_state_c ,
891+ gru_last , gru_no_bias ,
892+ rnn_last , rnn_relu_no_bias ,
893+ bidi_lstm_last_concat ,
894+ bidi_lstm_sum ,
895+ bidi_gru_mul ,
896+ bidi_gru_ave ,
897+ bidi_rnn_concat ,
898+ masked ,
899+ rnn_lstm , rnn_gru , rnn_simple ,
900+ rnn_stacked , rnn_stacked_seq ,
901+ clstm1d , clstm1d_valid , clstm1d_dilated ,
902+ clstm2d , clstm2d_valid_no_bias , clstm2d_chained ,
903+ clstm3d , clstm3d_valid ,
904+ ]
905+
906+ model = Model (inputs = [inputs , inputs_clstm1d , inputs_clstm2d , inputs_clstm3d ],
907+ outputs = outputs , name = 'test_model_recurrent' )
908+ model .compile (loss = 'mse' , optimizer = 'adam' )
909+
910+ training_data_size = 2
911+ data_in = generate_input_data (training_data_size ,
912+ [(seq_len , n_features ), (4 , 6 , 3 ), (3 , 5 , 5 , 3 ), (2 , 3 , 4 , 4 , 3 )])
913+ initial_data_out = model .predict (data_in )
914+ data_out = generate_output_data (training_data_size , initial_data_out )
915+ model .fit (data_in , data_out , epochs = 1 )
916+ return model
917+
918+
919+ def get_test_model_extended () -> Model :
920+ """Returns a test model exercising recently-added non-recurrent layers
921+ (DepthwiseConv1D, EinsumDense, RMSNormalization, GroupNormalization,
922+ AdaptiveAvg/MaxPooling, GroupedQueryAttention, Discretization, and a
923+ handful of training-only Random* augmentation passthroughs)."""
924+ seq_len = 5
925+ n_features = 4
926+
927+ inputs = Input (shape = (seq_len , n_features ))
928+ inputs_2d = Input (shape = (7 , 8 , 4 ))
929+ inputs_3d = Input (shape = (5 , 6 , 7 , 4 ))
930+ inputs_kv = Input (shape = (8 , n_features ))
931+
860932 dwc1d_same = DepthwiseConv1D (kernel_size = 3 , padding = 'same' )(inputs )
861933 dwc1d_valid = DepthwiseConv1D (kernel_size = 2 , padding = 'valid' , strides = 2 )(inputs )
862934 dwc1d_no_bias = DepthwiseConv1D (kernel_size = 3 , padding = 'same' , use_bias = False )(inputs )
@@ -893,53 +965,15 @@ def get_test_model_recurrent() -> Model:
893965 gqa_eq_heads = GroupQueryAttention (head_dim = 4 , num_query_heads = 4 , num_key_value_heads = 4 )(
894966 inputs , inputs , inputs )
895967 # distinct sequence lengths for query vs key/value.
896- inputs_kv = Input (shape = (8 , n_features ))
897968 gqa_kv_diff = GroupQueryAttention (head_dim = 3 , num_query_heads = 4 , num_key_value_heads = 2 )(
898969 inputs , inputs_kv , inputs_kv )
899970
900971 discretized = Discretization (bin_boundaries = [- 0.5 , 0.0 , 0.5 , 1.0 ])(inputs )
901- masked = Masking (mask_value = 0.0 )(inputs )
902972 rand_brightness = RandomBrightness (factor = 0.1 )(inputs_2d )
903973 rand_flip = RandomFlip (mode = 'horizontal' )(inputs_2d )
904974 rand_crop = RandomCrop (height = 7 , width = 8 )(inputs_2d )
905975
906- rnn_lstm = RNN (LSTMCell (4 ))(inputs )
907- rnn_gru = RNN (GRUCell (5 ), return_sequences = True )(inputs )
908- rnn_simple = RNN (SimpleRNNCell (3 ))(inputs )
909- rnn_stacked = RNN (StackedRNNCells ([LSTMCell (6 ), GRUCell (4 ), SimpleRNNCell (3 )]))(inputs )
910- rnn_stacked_seq = RNN (StackedRNNCells ([LSTMCell (5 ), GRUCell (3 )]),
911- return_sequences = True )(inputs )
912-
913- inputs_clstm1d = Input (shape = (4 , 6 , 3 ))
914- inputs_clstm2d = Input (shape = (3 , 5 , 5 , 3 ))
915- inputs_clstm3d = Input (shape = (2 , 3 , 4 , 4 , 3 ))
916- clstm1d = ConvLSTM1D (filters = 2 , kernel_size = 3 , padding = 'same' )(inputs_clstm1d )
917- clstm1d_valid = ConvLSTM1D (filters = 2 , kernel_size = 2 , padding = 'valid' ,
918- return_sequences = True )(inputs_clstm1d )
919- clstm1d_dilated = ConvLSTM1D (filters = 2 , kernel_size = 2 , padding = 'same' ,
920- dilation_rate = 2 )(inputs_clstm1d )
921- clstm2d = ConvLSTM2D (filters = 2 , kernel_size = (3 , 3 ), padding = 'same' ,
922- return_sequences = True )(inputs_clstm2d )
923- clstm2d_valid_no_bias = ConvLSTM2D (filters = 3 , kernel_size = (2 , 2 ), padding = 'valid' ,
924- use_bias = False , activation = 'relu' )(inputs_clstm2d )
925- # Two ConvLSTM2Ds chained: validates state handoff between successive temporal layers.
926- clstm2d_chained = ConvLSTM2D (filters = 2 , kernel_size = (2 , 2 ), padding = 'same' )(
927- ConvLSTM2D (filters = 3 , kernel_size = (3 , 3 ), padding = 'same' ,
928- return_sequences = True )(inputs_clstm2d ))
929- clstm3d = ConvLSTM3D (filters = 2 , kernel_size = (2 , 2 , 2 ), padding = 'same' )(inputs_clstm3d )
930- clstm3d_valid = ConvLSTM3D (filters = 2 , kernel_size = (1 , 2 , 2 ), padding = 'valid' ,
931- return_sequences = True )(inputs_clstm3d )
932-
933976 outputs = [
934- lstm_last , lstm_no_bias , lstm_relu , lstm_no_unit_forget ,
935- lstm_state_out , lstm_state_h , lstm_state_c ,
936- gru_last , gru_no_bias ,
937- rnn_last , rnn_relu_no_bias ,
938- bidi_lstm_last_concat ,
939- bidi_lstm_sum ,
940- bidi_gru_mul ,
941- bidi_gru_ave ,
942- bidi_rnn_concat ,
943977 dwc1d_same , dwc1d_valid , dwc1d_no_bias ,
944978 rms , rms_eps ,
945979 gn , gn_no_scale , gn_no_center , gn_one , gn_per_channel ,
@@ -948,24 +982,17 @@ def get_test_model_recurrent() -> Model:
948982 ap2d_a , ap2d_m , ap2d_uneven ,
949983 ap3d_a , ap3d_m , ap3d_uneven ,
950984 gqa , gqa_gated , gqa_eq_heads , gqa_kv_diff ,
951- rnn_lstm , rnn_gru , rnn_simple ,
952- rnn_stacked , rnn_stacked_seq ,
953- clstm1d , clstm1d_valid , clstm1d_dilated ,
954- clstm2d , clstm2d_valid_no_bias , clstm2d_chained ,
955- clstm3d , clstm3d_valid ,
956- discretized , masked ,
985+ discretized ,
957986 rand_brightness , rand_flip , rand_crop ,
958987 ]
959988
960- model = Model (inputs = [inputs , inputs_2d , inputs_3d ,
961- inputs_clstm1d , inputs_clstm2d , inputs_clstm3d , inputs_kv ],
962- outputs = outputs , name = 'test_model_recurrent' )
989+ model = Model (inputs = [inputs , inputs_2d , inputs_3d , inputs_kv ],
990+ outputs = outputs , name = 'test_model_extended' )
963991 model .compile (loss = 'mse' , optimizer = 'adam' )
964992
965993 training_data_size = 2
966994 data_in = generate_input_data (training_data_size ,
967- [(seq_len , n_features ), (7 , 8 , 4 ), (5 , 6 , 7 , 4 ),
968- (4 , 6 , 3 ), (3 , 5 , 5 , 3 ), (2 , 3 , 4 , 4 , 3 ), (8 , n_features )])
995+ [(seq_len , n_features ), (7 , 8 , 4 ), (5 , 6 , 7 , 4 ), (8 , n_features )])
969996 initial_data_out = model .predict (data_in )
970997 data_out = generate_output_data (training_data_size , initial_data_out )
971998 model .fit (data_in , data_out , epochs = 1 )
@@ -988,6 +1015,7 @@ def main() -> None:
9881015 'autoencoder' : get_test_model_autoencoder ,
9891016 'sequential' : get_test_model_sequential ,
9901017 'recurrent' : get_test_model_recurrent ,
1018+ 'extended' : get_test_model_extended ,
9911019 }
9921020
9931021 if not model_name in get_model_functions :
0 commit comments