-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconvlstm_4gpu_amsre.py
More file actions
192 lines (155 loc) · 9.38 KB
/
Copy pathconvlstm_4gpu_amsre.py
File metadata and controls
192 lines (155 loc) · 9.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#load necessary libraries
import tensorflow as tf
# Enable dynamic GPU memory allocation
for gpu in tf.config.experimental.list_physical_devices('GPU'):
tf.config.experimental.set_memory_growth(gpu, True)
import numpy as np
import pandas as pd
import xarray as xr
from tensorflow.keras.layers import Input, ConvLSTM2D, Reshape, LeakyReLU, SpatialDropout2D, Conv2D, BatchNormalization
from tensorflow.keras.regularizers import l2
from tensorflow.keras.models import Sequential, Model
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from tensorflow.keras.metrics import RootMeanSquaredError
#from global_land_mask import globe
import matplotlib.pyplot as plt
from tensorflow.keras.losses import Huber
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import TensorBoard
import datetime
# Enable mixed precision
from tensorflow.keras.mixed_precision import set_global_policy, LossScaleOptimizer
set_global_policy('mixed_float16')
strategy = tf.distribute.MirroredStrategy()
print('Number of devices: {}'.format(strategy.num_replicas_in_sync))
# Create a log directory with a timestamp to create unique folders for different runs
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=1)
def create_sequences(data, start_date, end_date, lookback_window, days_after, target_variable):
extended_start = pd.to_datetime(start_date) - pd.Timedelta(days=lookback_window)
extended_end = pd.to_datetime(end_date) + pd.Timedelta(days=days_after)
# Slice the data for extended period
sliced_data = data.sel(time=slice(extended_start, extended_end))
X_data=sliced_data[['amsre_smoothed', 'ocean_land_mask', 'day_of_sin', 'day_of_cos']]
X_sequences = []
Y_sequences = []
for i in range(lookback_window, len(sliced_data['time']) - days_after):
start_idx = i - lookback_window
end_idx = i + days_after
# create a sequence from the sliced_data
X_seq_before = X_data.isel(time=slice(start_idx, i)).to_array().transpose('time', 'Latitude', 'Longitude', 'variable')
# Create a sequence for days after the current day
X_seq_after = X_data.isel(time=slice(i + 1, end_idx + 1)).to_array().transpose('time', 'Latitude', 'Longitude', 'variable')
# Concatenate sequences from before and after the current day
X_seq_np = np.concatenate((X_seq_before, X_seq_after), axis=0)
Y_seq = sliced_data[target_variable].isel(time=i).values
# Replace 'target_variable' with your actual target variable
X_sequences.append(X_seq_np)
Y_sequences.append(Y_seq)
return np.array(X_sequences), np.array(Y_sequences)
# Define date ranges and parameters
train_start, train_end = '2009-01-07', '2011-12-28'
validation_start, validation_end = '2007-12-04', '2009-01-03'
test_start, test_end = '2007-01-07', '2007-11-30'
#prediction_start, prediction_end = '2007-01-07', '2023-12-22'
lookback_window = 3
days_after = 3
sequence_length = lookback_window + days_after
channels = 4
target_variable = 'AMSR_predicted'
#loading the datasets
combined_dataset=xr.open_dataset("/p/scratch/share/sivaprasad1/niesel1/EU_DATA/combined_dataset_amsre_2002_2011_20250814.nc")
# amsr = xr.open_dataset("/p/scratch/share/sivaprasad1/niesel1/EU_DATA/AMSRE_A_25_mask_uncert_cor_2002_2011_smoothed_new.nc")
# ascat = xr.open_dataset('/p/scratch/share/sivaprasad1/niesel1/EU_DATA/predictions_2007_2023_new.nc')
# ocean = xr.open_dataset('/p/scratch/share/sivaprasad1/niesel1/EU_DATA/ocean_land_mask_2003_2011_new.nc')
# doy = xr.open_dataset('/p/scratch/share/sivaprasad1/niesel1/EU_DATA/dayofyear_2003_2011.nc')
# combined_dataset = xr.merge([amsr, ascat, ocean, doy])
# #create cyclic encoding of day of year
# combined_dataset['day_of_sin'] = np.sin(2*np.pi*combined_dataset['dayofyear']/365)
# combined_dataset['day_of_cos'] = np.cos(2*np.pi*combined_dataset['dayofyear']/365)
# land_mask = combined_dataset['ocean_land_mask'] == 1
# combined_dataset['amsre_smoothed'] = combined_dataset['amsre_smoothed'].where(land_mask, 0)
# combined_dataset['AMSR_predicted'] = combined_dataset['AMSR_predicted'].where(land_mask, 0)
# combined_dataset['day_of_sin'] = combined_dataset['day_of_sin'].where(land_mask, 0)
# combined_dataset['day_of_cos'] = combined_dataset['day_of_cos'].where(land_mask, 0)
# #combined_dataset['day_of_year'] = combined_dataset['day_of_year'].where(land_mask, 0)
# combined_dataset['amsre_smoothed'] = combined_dataset['amsre_smoothed'].fillna(0)
# combined_dataset['AMSR_predicted'] = combined_dataset['AMSR_predicted'].fillna(0)
# #fill all values above 1 with 0 in amsr2_smoothed
# combined_dataset['amsre_smoothed'] = combined_dataset['amsre_smoothed'].where(combined_dataset['amsre_smoothed'] < 1, 0)
# combined_dataset['day_of_sin'] = combined_dataset['day_of_sin'].fillna(0)
# combined_dataset['day_of_cos'] = combined_dataset['day_of_cos'].fillna(0)
# Get the latitude and longitude dimensions in integer
lats = int(combined_dataset['Latitude'].shape[0])
lons = int(combined_dataset['Longitude'].shape[0])
# Create sequences for training, validation, and test sets
X_train, Y_train = create_sequences(combined_dataset, train_start, train_end, lookback_window, days_after, target_variable)
X_val, Y_val = create_sequences(combined_dataset, validation_start, validation_end, lookback_window, days_after, target_variable)
X_test, Y_test = create_sequences(combined_dataset, test_start, test_end, lookback_window, days_after, target_variable)
#X_pred, _ = create_sequences(combined_dataset, prediction_start, prediction_end, lookback_window, days_after, target_variable)
print("successfully created sequences")
X_train = X_train.astype('float16')
Y_train = Y_train.astype('float16')
X_val = X_val.astype('float16')
Y_val = Y_val.astype('float16')
X_test = X_test.astype('float16')
Y_test = Y_test.astype('float16')
X_train = tf.convert_to_tensor(X_train, dtype=tf.float16)
Y_train = tf.convert_to_tensor(Y_train , dtype=tf.float16)
X_val = tf.convert_to_tensor(X_val, dtype=tf.float16)
Y_val = tf.convert_to_tensor(Y_val, dtype=tf.float16)
X_test = tf.convert_to_tensor(X_test, dtype=tf.float16)
Y_test = tf.convert_to_tensor(Y_test, dtype=tf.float16)
# #convert to tensorflow dataset
# train_dataset = tf.data.Dataset.from_tensor_slices((X_train, Y_train)).batch(4, drop_remainder=True)#.prefetch(tf.data.AUTOTUNE)
# val_dataset = tf.data.Dataset.from_tensor_slices((X_val, Y_val)).batch(4, drop_remainder=True)#.prefetch(tf.data.AUTOTUNE)
# test_dataset = tf.data.Dataset.from_tensor_slices((X_test, Y_test)).batch(4, drop_remainder=True)#.prefetch(tf.data.AUTOTUNE)
print("successfully created datasets")
input_shape = (sequence_length, lats, lons, channels) # (sequence_length, lats, lons, channels)
#strategy = tf.distribute.MirroredStrategy()
#with strategy.scope():
def build_model(pretrained_model):
pretrained_layers = pretrained_model.layers[:4] # Extract the first four layers
new_layers = [
ConvLSTM2D(filters=64, kernel_size=(5, 5), padding='same', return_sequences=True,
dropout=0.2, recurrent_dropout=0.2, name="new_conv_lstm_1"),
BatchNormalization(name="new_batch_norm_1"),
ConvLSTM2D(filters=16, kernel_size=(3, 3), padding='same', return_sequences=False,
dropout=0.2, recurrent_dropout=0.2, name="new_conv_lstm_2"),
BatchNormalization(name="new_batch_norm_2"),
Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same', name="new_conv2d_1"),
#SpatialDropout2D(0.2, name="new_spatial_dropout"),
Conv2D(filters=1, kernel_size=(3, 3), activation='relu', padding='same', name="new_conv2d_2"),
Reshape((lats, lons), name="new_reshape"), # reshape to the original grid
]
model = Sequential(pretrained_layers + new_layers)
return model
with strategy.scope():
pretrained_model = tf.keras.models.load_model('/p/scratch/share/sivaprasad1/visakh/code/convlstm_model_20241106_rev')
pretrained_model.trainable = False
model = build_model(pretrained_model)
#adam_optimizer = Adam()
#optimizer=LossScaleOptimizer(adam_optimizer)
model.compile(optimizer='adam', loss=Huber(), metrics=['mae', RootMeanSquaredError()])
model.summary()
early_stopping = EarlyStopping(monitor='val_loss', patience=20, restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, min_lr=1e-6)
callbacks_list = [early_stopping, reduce_lr]
# set_global_policy('float32')
#save model checkpoint
checkpoint_path = "/p/scratch/share/sivaprasad1/visakh/model_checkpoint_amsre_1"
checkpoint_callback = ModelCheckpoint(checkpoint_path, save_best_only=True)
# #model fitting
history = model.fit(X_train, Y_train, validation_data=(X_val, Y_val), epochs=200, callbacks=[callbacks_list, tensorboard_callback, checkpoint_callback], batch_size=32, verbose=1)
#history = model.fit(train_dataset, validation_data=val_dataset, epochs=50, callbacks=[callbacks_list,tensorboard_callback, checkpoint_callback], verbose=1)
# # set_global_policy('float32')
# #save the model
model.save('convlstm_model_amsre_20241106_rev')
# # #save model weights
model.save_weights('convlstm_model_weights_amsre_20241106')
#model evaluation with test_data
loss, mae, rmse = model.evaluate(X_test, Y_test, verbose=1)
print("Test loss:", loss)
print("Test mae:", mae)
print("Root Mean Squared Error:", rmse)