nanduriprudhvi commited on
Commit
fd6f594
·
verified ·
1 Parent(s): b639d03

Update trjgru.py

Browse files
Files changed (1) hide show
  1. trjgru.py +301 -301
trjgru.py CHANGED
@@ -1,302 +1,302 @@
1
- import tensorflow as tf
2
- from tensorflow.keras import layers, models # type: ignore
3
- import numpy as np
4
-
5
-
6
- class TrajectoryGRU2D(layers.Layer):
7
- def __init__(self, filters, kernel_size, return_sequences=True, **kwargs):
8
- super().__init__(**kwargs)
9
- self.filters = filters
10
- self.kernel_size = kernel_size
11
- self.return_sequences = return_sequences
12
-
13
- # Projection layer to match GRU feature space
14
- self.input_projection = layers.Conv2D(filters, (1, 1), padding="same")
15
-
16
- # GRU Gates
17
- self.conv_z = layers.Conv2D(filters, kernel_size, padding="same", activation="sigmoid")
18
- self.conv_r = layers.Conv2D(filters, kernel_size, padding="same", activation="sigmoid")
19
- self.conv_h = layers.Conv2D(filters, kernel_size, padding="same", activation="tanh")
20
-
21
- # Motion-based trajectory update
22
- self.motion_conv = layers.Conv2D(filters, kernel_size, padding="same", activation="tanh")
23
-
24
- def build(self, input_shape):
25
- # Ensures input_projection is built with the correct input shape
26
- self.input_projection.build(input_shape[1:]) # Ignore batch dimension
27
- super().build(input_shape)
28
-
29
- def call(self, inputs):
30
- # inputs shape: (batch_size, time_steps, height, width, channels)
31
- batch_size, time_steps, height, width, channels = tf.unstack(tf.shape(inputs))
32
- time_steps = inputs.shape[1]
33
-
34
- # Initialize hidden state
35
- h_t = tf.zeros((batch_size, height, width, self.filters))
36
-
37
- # List to store outputs at each time step
38
- outputs = []
39
-
40
- # Iterate over time steps
41
- for t in range(time_steps):
42
- # Get the input at time step t
43
- x_t = inputs[:, t, :, :, :]
44
-
45
- # Project input to match GRU feature dimension
46
- x_projected = self.input_projection(x_t)
47
-
48
- # Compute motion-based trajectory update
49
- motion_update = self.motion_conv(x_projected)
50
-
51
- # Concatenate projected input, previous hidden state, and motion update
52
- combined = tf.concat([x_projected, h_t, motion_update], axis=-1)
53
-
54
- # Compute GRU gates
55
- z = self.conv_z(combined) # Update gate
56
- r = self.conv_r(combined) # Reset gate
57
-
58
- # Compute candidate hidden state
59
- h_tilde = self.conv_h(tf.concat([x_projected, r * h_t], axis=-1))
60
-
61
- # Update hidden state with motion-based trajectory
62
- h_t = (1 - z) * h_t + z * h_tilde + motion_update # Add motion update
63
-
64
- # Store the output if return_sequences is True
65
- if self.return_sequences:
66
- outputs.append(h_t)
67
-
68
- # Stack outputs along the time dimension if return_sequences is True
69
- if self.return_sequences:
70
- outputs = tf.stack(outputs, axis=1)
71
- else:
72
- outputs = h_t
73
-
74
- return outputs
75
-
76
- def compute_output_shape(self, input_shape):
77
- if self.return_sequences:
78
- return (input_shape[0], input_shape[1], input_shape[2], input_shape[3], self.filters)
79
- else:
80
- return (input_shape[0], input_shape[2], input_shape[3], self.filters)
81
-
82
-
83
- def build_tgru_model(input_shape=(8, 95, 95, 2)): # (time_steps, height, width, channels)
84
- input_tensor = layers.Input(shape=input_shape)
85
-
86
- # Apply TGRU Layers
87
- x = TrajectoryGRU2D(filters=32, kernel_size=(3, 3), return_sequences=True)(input_tensor)
88
- x = layers.Conv3D(filters=32, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
89
- x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
90
-
91
- x = TrajectoryGRU2D(filters=64, kernel_size=(3, 3), return_sequences=True)(x)
92
- x = layers.Conv3D(filters=64, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
93
- x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
94
-
95
- x = TrajectoryGRU2D(filters=128, kernel_size=(3, 3), return_sequences=True)(x)
96
- x = layers.Conv3D(filters=128, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
97
- x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
98
-
99
- # Flatten before Fully Connected Layer
100
- x = layers.Flatten()(x)
101
- # x = layers.Dense(1, activation='sigmoid')(x)
102
-
103
- model = models.Model(inputs=input_tensor, outputs=x)
104
- return model
105
-
106
- def radial_structure_subnet(input_shape):
107
- """
108
- Creates the subnet for extracting TC radial structure features using a five-branch CNN design with 2D convolutions.
109
-
110
- Parameters:
111
- - input_shape: tuple, shape of the input data (e.g., (95, 95, 3))
112
-
113
- Returns:
114
- - model: tf.keras.Model, the radial structure subnet model
115
- """
116
-
117
- input_tensor = layers.Input(shape=input_shape)
118
-
119
- # Divide input data into four quadrants (NW, NE, SW, SE)
120
- # Assuming the input shape is (batch_size, height, width, channels)
121
-
122
- # Quadrant extraction - using slicing to separate quadrants
123
- nw_quadrant = input_tensor[:, :input_shape[0]//2, :input_shape[1]//2, :]
124
- ne_quadrant = input_tensor[:, :input_shape[0]//2, input_shape[1]//2:, :]
125
- sw_quadrant = input_tensor[:, input_shape[0]//2:, :input_shape[1]//2, :]
126
- se_quadrant = input_tensor[:, input_shape[0]//2:, input_shape[1]//2:, :]
127
-
128
-
129
- target_height = max(input_shape[0]//2, input_shape[0] - input_shape[0]//2) # 48
130
- target_width = max(input_shape[1]//2, input_shape[1] - input_shape[1]//2) # 48
131
-
132
- # Padding the quadrants to match the target size (48, 48)
133
- nw_quadrant = layers.ZeroPadding2D(padding=((0, target_height - nw_quadrant.shape[1]),
134
- (0, target_width - nw_quadrant.shape[2])))(nw_quadrant)
135
- ne_quadrant = layers.ZeroPadding2D(padding=((0, target_height - ne_quadrant.shape[1]),
136
- (0, target_width - ne_quadrant.shape[2])))(ne_quadrant)
137
- sw_quadrant = layers.ZeroPadding2D(padding=((0, target_height - sw_quadrant.shape[1]),
138
- (0, target_width - sw_quadrant.shape[2])))(sw_quadrant)
139
- se_quadrant = layers.ZeroPadding2D(padding=((0, target_height - se_quadrant.shape[1]),
140
- (0, target_width - se_quadrant.shape[2])))(se_quadrant)
141
-
142
- print(nw_quadrant.shape)
143
- print(ne_quadrant.shape)
144
- print(sw_quadrant.shape)
145
- print(se_quadrant.shape)
146
- # Main branch (processing the entire structure)
147
- main_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(input_tensor)
148
- y=layers.MaxPool2D()(main_branch)
149
-
150
- y = layers.ZeroPadding2D(padding=((0, target_height - y.shape[1]),
151
- (0, target_width - y.shape[2])))(y)
152
- # Side branches (processing the individual quadrants)
153
- nw_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(nw_quadrant)
154
- ne_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(ne_quadrant)
155
- sw_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(sw_quadrant)
156
- se_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(se_quadrant)
157
-
158
- # Apply padding to the side branches to match the dimensions of the main branch
159
- # nw_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(nw_branch)
160
- # ne_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(ne_branch)
161
- # sw_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(sw_branch)
162
- # se_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(se_branch)
163
-
164
- # Fusion operations (concatenate the outputs from the main branch and side branches)
165
- fusion = layers.concatenate([y, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
166
-
167
- # Additional convolution layer to combine the fused features
168
- x = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(fusion)
169
- x=layers.MaxPool2D(pool_size=(2, 2))(x)
170
- # Final dense layer for further processing
171
- nw_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(nw_branch)
172
-
173
- ne_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(ne_branch)
174
- sw_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(sw_branch)
175
- se_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(se_branch)
176
- nw_branch = layers.MaxPool2D(pool_size=(2, 2))(nw_branch)
177
- ne_branch = layers.MaxPool2D(pool_size=(2, 2))(ne_branch)
178
- sw_branch = layers.MaxPool2D(pool_size=(2, 2))(sw_branch)
179
- se_branch = layers.MaxPool2D(pool_size=(2, 2))(se_branch)
180
-
181
- fusion = layers.concatenate([x, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
182
- x = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(fusion)
183
- x=layers.MaxPool2D(pool_size=(2, 2))(x)
184
-
185
- nw_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(nw_branch)
186
-
187
- ne_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(ne_branch)
188
- sw_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(sw_branch)
189
- se_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(se_branch)
190
- nw_branch = layers.MaxPool2D(pool_size=(2, 2))(nw_branch)
191
- ne_branch = layers.MaxPool2D(pool_size=(2, 2))(ne_branch)
192
- sw_branch = layers.MaxPool2D(pool_size=(2, 2))(sw_branch)
193
- se_branch = layers.MaxPool2D(pool_size=(2, 2))(se_branch)
194
-
195
- fusion = layers.concatenate([x, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
196
- x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu')(fusion)
197
- x=layers.Conv2D(filters=32, kernel_size=(3, 3), activation=None)(x)
198
- # Create and return the model
199
- x=layers.Flatten()(x)
200
- model = models.Model(inputs=input_tensor, outputs=x)
201
- return model
202
-
203
- # Define input shape (batch_size, height, width, channels)
204
- # input_shape = (95, 95, 8) # Example input shape (95x95 spatial resolution, 3 channels)
205
-
206
- # # Build the model
207
- # model = radial_structure_subnet(input_shape)
208
-
209
- # # Model summary
210
- # model.summary()
211
-
212
- def build_cnn_model(input_shape=(8, 8, 1)):
213
- # Define the input layer
214
- input_tensor = layers.Input(shape=input_shape)
215
-
216
- # Convolutional layer
217
- x = layers.Conv2D(64, (3, 3), padding='same')(input_tensor)
218
- x = layers.BatchNormalization()(x)
219
- x = layers.ReLU()(x)
220
-
221
- # Flatten layer
222
- x = layers.Flatten()(x)
223
-
224
- # Create the model
225
- model = models.Model(inputs=input_tensor, outputs=x)
226
-
227
- return model
228
-
229
- from tensorflow.keras import layers, models, Input # type: ignore
230
-
231
- def build_combined_model():
232
- # Define input shapes
233
- input_shape_3d = (8, 95, 95, 2)
234
- input_shape_radial = (95, 95, 8)
235
- input_shape_cnn = (8, 8, 1)
236
-
237
- input_shape_latitude = (8,)
238
- input_shape_longitude = (8,)
239
- input_shape_other = (9,)
240
-
241
- # Build individual models
242
- model_3d = build_tgru_model(input_shape=input_shape_3d)
243
- model_radial = radial_structure_subnet(input_shape=input_shape_radial)
244
- model_cnn = build_cnn_model(input_shape=input_shape_cnn)
245
-
246
- # Define new inputs
247
- input_latitude = Input(shape=input_shape_latitude ,name="latitude_input")
248
- input_longitude = Input(shape=input_shape_longitude, name="longitude_input")
249
- input_other = Input(shape=input_shape_other, name="other_input")
250
-
251
- # Flatten the additional inputs
252
- flat_latitude = layers.Dense(32,activation='relu')(input_latitude)
253
- flat_longitude = layers.Dense(32,activation='relu')(input_longitude)
254
- flat_other = layers.Dense(64,activation='relu')(input_other)
255
-
256
- # Combine all outputs
257
- combined = layers.concatenate([
258
- model_3d.output,
259
- model_radial.output,
260
- model_cnn.output,
261
- flat_latitude,
262
- flat_longitude,
263
- flat_other
264
- ])
265
-
266
- # Add dense layers for final processing
267
- x = layers.Dense(128, activation='relu')(combined)
268
- x = layers.Dense(1, activation=None)(x)
269
-
270
- # Create the final model
271
- final_model = models.Model(
272
- inputs=[model_3d.input, model_radial.input, model_cnn.input,
273
- input_latitude, input_longitude, input_other ],
274
- outputs=x
275
- )
276
-
277
- return final_model
278
-
279
- import h5py
280
- with h5py.File(r"E:\1MAIN PROJECT\tf_env\Trj_GRU.h5", 'r') as f:
281
- print(f.attrs.get('keras_version'))
282
- print(f.attrs.get('backend'))
283
-
284
- print("Model layers:", list(f['model_weights'].keys()))
285
-
286
- model = build_combined_model() # Your original model building function
287
- # Rebuild the model architecture
288
- model = build_tgru_model(input_shape=(8, 95, 95, 2))
289
-
290
- # Build the model by calling it once (to initialize all weights)
291
- dummy_input = tf.random.normal((1, 8, 95, 95, 2)) # batch_size=1
292
- _ = model(dummy_input) # Forward pass to build all layers
293
-
294
- # Now load the saved weights
295
- # model.load_weights("Trj_GRU.weights.h5")
296
-
297
- model.load_weights(r"E:\1MAIN PROJECT\tf_env\Trj_GRU.weights.h5")
298
-
299
-
300
- def predict_trajgru(reduced_images_test,hov_m_test,test_vmax_3d,lat_test,lon_test,int_diff_test):
301
- y=model.predict([reduced_images_test,hov_m_test,test_vmax_3d,lat_test,lon_test,int_diff_test ])
302
  return y
 
1
+ import tensorflow as tf
2
+ from tensorflow.keras import layers, models # type: ignore
3
+ import numpy as np
4
+
5
+
6
+ class TrajectoryGRU2D(layers.Layer):
7
+ def __init__(self, filters, kernel_size, return_sequences=True, **kwargs):
8
+ super().__init__(**kwargs)
9
+ self.filters = filters
10
+ self.kernel_size = kernel_size
11
+ self.return_sequences = return_sequences
12
+
13
+ # Projection layer to match GRU feature space
14
+ self.input_projection = layers.Conv2D(filters, (1, 1), padding="same")
15
+
16
+ # GRU Gates
17
+ self.conv_z = layers.Conv2D(filters, kernel_size, padding="same", activation="sigmoid")
18
+ self.conv_r = layers.Conv2D(filters, kernel_size, padding="same", activation="sigmoid")
19
+ self.conv_h = layers.Conv2D(filters, kernel_size, padding="same", activation="tanh")
20
+
21
+ # Motion-based trajectory update
22
+ self.motion_conv = layers.Conv2D(filters, kernel_size, padding="same", activation="tanh")
23
+
24
+ def build(self, input_shape):
25
+ # Ensures input_projection is built with the correct input shape
26
+ self.input_projection.build(input_shape[1:]) # Ignore batch dimension
27
+ super().build(input_shape)
28
+
29
+ def call(self, inputs):
30
+ # inputs shape: (batch_size, time_steps, height, width, channels)
31
+ batch_size, time_steps, height, width, channels = tf.unstack(tf.shape(inputs))
32
+ time_steps = inputs.shape[1]
33
+
34
+ # Initialize hidden state
35
+ h_t = tf.zeros((batch_size, height, width, self.filters))
36
+
37
+ # List to store outputs at each time step
38
+ outputs = []
39
+
40
+ # Iterate over time steps
41
+ for t in range(time_steps):
42
+ # Get the input at time step t
43
+ x_t = inputs[:, t, :, :, :]
44
+
45
+ # Project input to match GRU feature dimension
46
+ x_projected = self.input_projection(x_t)
47
+
48
+ # Compute motion-based trajectory update
49
+ motion_update = self.motion_conv(x_projected)
50
+
51
+ # Concatenate projected input, previous hidden state, and motion update
52
+ combined = tf.concat([x_projected, h_t, motion_update], axis=-1)
53
+
54
+ # Compute GRU gates
55
+ z = self.conv_z(combined) # Update gate
56
+ r = self.conv_r(combined) # Reset gate
57
+
58
+ # Compute candidate hidden state
59
+ h_tilde = self.conv_h(tf.concat([x_projected, r * h_t], axis=-1))
60
+
61
+ # Update hidden state with motion-based trajectory
62
+ h_t = (1 - z) * h_t + z * h_tilde + motion_update # Add motion update
63
+
64
+ # Store the output if return_sequences is True
65
+ if self.return_sequences:
66
+ outputs.append(h_t)
67
+
68
+ # Stack outputs along the time dimension if return_sequences is True
69
+ if self.return_sequences:
70
+ outputs = tf.stack(outputs, axis=1)
71
+ else:
72
+ outputs = h_t
73
+
74
+ return outputs
75
+
76
+ def compute_output_shape(self, input_shape):
77
+ if self.return_sequences:
78
+ return (input_shape[0], input_shape[1], input_shape[2], input_shape[3], self.filters)
79
+ else:
80
+ return (input_shape[0], input_shape[2], input_shape[3], self.filters)
81
+
82
+
83
+ def build_tgru_model(input_shape=(8, 95, 95, 2)): # (time_steps, height, width, channels)
84
+ input_tensor = layers.Input(shape=input_shape)
85
+
86
+ # Apply TGRU Layers
87
+ x = TrajectoryGRU2D(filters=32, kernel_size=(3, 3), return_sequences=True)(input_tensor)
88
+ x = layers.Conv3D(filters=32, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
89
+ x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
90
+
91
+ x = TrajectoryGRU2D(filters=64, kernel_size=(3, 3), return_sequences=True)(x)
92
+ x = layers.Conv3D(filters=64, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
93
+ x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
94
+
95
+ x = TrajectoryGRU2D(filters=128, kernel_size=(3, 3), return_sequences=True)(x)
96
+ x = layers.Conv3D(filters=128, kernel_size=(3, 3, 3), padding='same', activation='relu')(x)
97
+ x = layers.MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='same')(x)
98
+
99
+ # Flatten before Fully Connected Layer
100
+ x = layers.Flatten()(x)
101
+ # x = layers.Dense(1, activation='sigmoid')(x)
102
+
103
+ model = models.Model(inputs=input_tensor, outputs=x)
104
+ return model
105
+
106
+ def radial_structure_subnet(input_shape):
107
+ """
108
+ Creates the subnet for extracting TC radial structure features using a five-branch CNN design with 2D convolutions.
109
+
110
+ Parameters:
111
+ - input_shape: tuple, shape of the input data (e.g., (95, 95, 3))
112
+
113
+ Returns:
114
+ - model: tf.keras.Model, the radial structure subnet model
115
+ """
116
+
117
+ input_tensor = layers.Input(shape=input_shape)
118
+
119
+ # Divide input data into four quadrants (NW, NE, SW, SE)
120
+ # Assuming the input shape is (batch_size, height, width, channels)
121
+
122
+ # Quadrant extraction - using slicing to separate quadrants
123
+ nw_quadrant = input_tensor[:, :input_shape[0]//2, :input_shape[1]//2, :]
124
+ ne_quadrant = input_tensor[:, :input_shape[0]//2, input_shape[1]//2:, :]
125
+ sw_quadrant = input_tensor[:, input_shape[0]//2:, :input_shape[1]//2, :]
126
+ se_quadrant = input_tensor[:, input_shape[0]//2:, input_shape[1]//2:, :]
127
+
128
+
129
+ target_height = max(input_shape[0]//2, input_shape[0] - input_shape[0]//2) # 48
130
+ target_width = max(input_shape[1]//2, input_shape[1] - input_shape[1]//2) # 48
131
+
132
+ # Padding the quadrants to match the target size (48, 48)
133
+ nw_quadrant = layers.ZeroPadding2D(padding=((0, target_height - nw_quadrant.shape[1]),
134
+ (0, target_width - nw_quadrant.shape[2])))(nw_quadrant)
135
+ ne_quadrant = layers.ZeroPadding2D(padding=((0, target_height - ne_quadrant.shape[1]),
136
+ (0, target_width - ne_quadrant.shape[2])))(ne_quadrant)
137
+ sw_quadrant = layers.ZeroPadding2D(padding=((0, target_height - sw_quadrant.shape[1]),
138
+ (0, target_width - sw_quadrant.shape[2])))(sw_quadrant)
139
+ se_quadrant = layers.ZeroPadding2D(padding=((0, target_height - se_quadrant.shape[1]),
140
+ (0, target_width - se_quadrant.shape[2])))(se_quadrant)
141
+
142
+ print(nw_quadrant.shape)
143
+ print(ne_quadrant.shape)
144
+ print(sw_quadrant.shape)
145
+ print(se_quadrant.shape)
146
+ # Main branch (processing the entire structure)
147
+ main_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(input_tensor)
148
+ y=layers.MaxPool2D()(main_branch)
149
+
150
+ y = layers.ZeroPadding2D(padding=((0, target_height - y.shape[1]),
151
+ (0, target_width - y.shape[2])))(y)
152
+ # Side branches (processing the individual quadrants)
153
+ nw_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(nw_quadrant)
154
+ ne_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(ne_quadrant)
155
+ sw_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(sw_quadrant)
156
+ se_branch = layers.Conv2D(filters=8, kernel_size=(3, 3), padding='same', activation='relu')(se_quadrant)
157
+
158
+ # Apply padding to the side branches to match the dimensions of the main branch
159
+ # nw_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(nw_branch)
160
+ # ne_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(ne_branch)
161
+ # sw_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(sw_branch)
162
+ # se_branch = layers.UpSampling2D(size=(2, 2), interpolation='nearest')(se_branch)
163
+
164
+ # Fusion operations (concatenate the outputs from the main branch and side branches)
165
+ fusion = layers.concatenate([y, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
166
+
167
+ # Additional convolution layer to combine the fused features
168
+ x = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(fusion)
169
+ x=layers.MaxPool2D(pool_size=(2, 2))(x)
170
+ # Final dense layer for further processing
171
+ nw_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(nw_branch)
172
+
173
+ ne_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(ne_branch)
174
+ sw_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(sw_branch)
175
+ se_branch = layers.Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu')(se_branch)
176
+ nw_branch = layers.MaxPool2D(pool_size=(2, 2))(nw_branch)
177
+ ne_branch = layers.MaxPool2D(pool_size=(2, 2))(ne_branch)
178
+ sw_branch = layers.MaxPool2D(pool_size=(2, 2))(sw_branch)
179
+ se_branch = layers.MaxPool2D(pool_size=(2, 2))(se_branch)
180
+
181
+ fusion = layers.concatenate([x, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
182
+ x = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(fusion)
183
+ x=layers.MaxPool2D(pool_size=(2, 2))(x)
184
+
185
+ nw_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(nw_branch)
186
+
187
+ ne_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(ne_branch)
188
+ sw_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(sw_branch)
189
+ se_branch = layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same', activation='relu')(se_branch)
190
+ nw_branch = layers.MaxPool2D(pool_size=(2, 2))(nw_branch)
191
+ ne_branch = layers.MaxPool2D(pool_size=(2, 2))(ne_branch)
192
+ sw_branch = layers.MaxPool2D(pool_size=(2, 2))(sw_branch)
193
+ se_branch = layers.MaxPool2D(pool_size=(2, 2))(se_branch)
194
+
195
+ fusion = layers.concatenate([x, nw_branch, ne_branch, sw_branch, se_branch], axis=-1)
196
+ x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu')(fusion)
197
+ x=layers.Conv2D(filters=32, kernel_size=(3, 3), activation=None)(x)
198
+ # Create and return the model
199
+ x=layers.Flatten()(x)
200
+ model = models.Model(inputs=input_tensor, outputs=x)
201
+ return model
202
+
203
+ # Define input shape (batch_size, height, width, channels)
204
+ # input_shape = (95, 95, 8) # Example input shape (95x95 spatial resolution, 3 channels)
205
+
206
+ # # Build the model
207
+ # model = radial_structure_subnet(input_shape)
208
+
209
+ # # Model summary
210
+ # model.summary()
211
+
212
+ def build_cnn_model(input_shape=(8, 8, 1)):
213
+ # Define the input layer
214
+ input_tensor = layers.Input(shape=input_shape)
215
+
216
+ # Convolutional layer
217
+ x = layers.Conv2D(64, (3, 3), padding='same')(input_tensor)
218
+ x = layers.BatchNormalization()(x)
219
+ x = layers.ReLU()(x)
220
+
221
+ # Flatten layer
222
+ x = layers.Flatten()(x)
223
+
224
+ # Create the model
225
+ model = models.Model(inputs=input_tensor, outputs=x)
226
+
227
+ return model
228
+
229
+ from tensorflow.keras import layers, models, Input # type: ignore
230
+
231
+ def build_combined_model():
232
+ # Define input shapes
233
+ input_shape_3d = (8, 95, 95, 2)
234
+ input_shape_radial = (95, 95, 8)
235
+ input_shape_cnn = (8, 8, 1)
236
+
237
+ input_shape_latitude = (8,)
238
+ input_shape_longitude = (8,)
239
+ input_shape_other = (9,)
240
+
241
+ # Build individual models
242
+ model_3d = build_tgru_model(input_shape=input_shape_3d)
243
+ model_radial = radial_structure_subnet(input_shape=input_shape_radial)
244
+ model_cnn = build_cnn_model(input_shape=input_shape_cnn)
245
+
246
+ # Define new inputs
247
+ input_latitude = Input(shape=input_shape_latitude ,name="latitude_input")
248
+ input_longitude = Input(shape=input_shape_longitude, name="longitude_input")
249
+ input_other = Input(shape=input_shape_other, name="other_input")
250
+
251
+ # Flatten the additional inputs
252
+ flat_latitude = layers.Dense(32,activation='relu')(input_latitude)
253
+ flat_longitude = layers.Dense(32,activation='relu')(input_longitude)
254
+ flat_other = layers.Dense(64,activation='relu')(input_other)
255
+
256
+ # Combine all outputs
257
+ combined = layers.concatenate([
258
+ model_3d.output,
259
+ model_radial.output,
260
+ model_cnn.output,
261
+ flat_latitude,
262
+ flat_longitude,
263
+ flat_other
264
+ ])
265
+
266
+ # Add dense layers for final processing
267
+ x = layers.Dense(128, activation='relu')(combined)
268
+ x = layers.Dense(1, activation=None)(x)
269
+
270
+ # Create the final model
271
+ final_model = models.Model(
272
+ inputs=[model_3d.input, model_radial.input, model_cnn.input,
273
+ input_latitude, input_longitude, input_other ],
274
+ outputs=x
275
+ )
276
+
277
+ return final_model
278
+
279
+ import h5py
280
+ # with h5py.File(r"Trj_GRU.h5", 'r') as f:
281
+ # print(f.attrs.get('keras_version'))
282
+ # print(f.attrs.get('backend'))
283
+
284
+ # print("Model layers:", list(f['model_weights'].keys()))
285
+
286
+ model = build_combined_model() # Your original model building function
287
+ # Rebuild the model architecture
288
+ model = build_tgru_model(input_shape=(8, 95, 95, 2))
289
+
290
+ # Build the model by calling it once (to initialize all weights)
291
+ dummy_input = tf.random.normal((1, 8, 95, 95, 2)) # batch_size=1
292
+ _ = model(dummy_input) # Forward pass to build all layers
293
+
294
+ # Now load the saved weights
295
+ # model.load_weights("Trj_GRU.weights.h5")
296
+
297
+ model.load_weights(r"Trj_GRU.weights.h5")
298
+
299
+
300
+ def predict_trajgru(reduced_images_test,hov_m_test,test_vmax_3d,lat_test,lon_test,int_diff_test):
301
+ y=model.predict([reduced_images_test,hov_m_test,test_vmax_3d,lat_test,lon_test,int_diff_test ])
302
  return y