1+ import os
2+ import torch
3+ import numpy as np
4+
5+ import sys
6+ sys .path .append ('..' )
7+
8+ from hydroDL .master .master import loadModel
9+ from hydroDL .model .crit import RmseLoss
10+ from hydroDL .model .rnn import CudnnLstmModel as LSTM
11+ from hydroDL .model .rnn import CpuLstmModel as LSTM_CPU
12+ from hydroDL .model .train import trainModel
13+ from hydroDL .model .test import testModel
14+ from hydroDL .post .stat import statError as cal_metric
15+ from hydroDL .data .load_csv import LoadCSV
16+ from hydroDL .utils .norm import re_folder , trans_norm
17+ from hydroDL .utils .norm import fix_seed
18+
19+ # set configuration
20+ fix_seed (42 )
21+ output_s = "./output/quick_start/" # output path
22+ csv_path_s = "./demo_data/" # demo data path
23+ all_date_list = ["2015-04-01" , "2017-03-31" ] # demo data time period
24+ train_date_list = ["2015-04-01" , "2016-03-31" ] # training period
25+ # time series variables list
26+ var_time_series = ["VGRD_10_FORA" , "DLWRF_FORA" , "UGRD_10_FORA" , "DSWRF_FORA" , "TMP_2_FORA" , "SPFH_2_FORA" , "APCP_FORA" , ]
27+ # constant variables list
28+ var_constant = ["flag_extraOrd" , "Clay" , "Bulk" , "Sand" , "flag_roughness" , "flag_landcover" , "flag_vegDense" , "Silt" , "NDVI" ,
29+ "flag_albedo" , "flag_waterbody" , "Capa" , ]
30+ # target variable list
31+ target = ["SMAP_AM" ]
32+
33+ # generate output folder
34+ re_folder (output_s )
35+
36+ # hyperparameter
37+ EPOCH = 20
38+ BATCH_SIZE = 50
39+ RHO = 30
40+ HIDDEN_SIZE = 256
41+ WARM_UP_DAY = 10
42+ # WARM_UP_DAY = None
43+
44+ # load your datasets
45+ """
46+ You can change it with your data. The data structure is as follows:
47+ x_train (forcing data, e.g. precipitation, temperature ...): [pixels, time, features]
48+ c_train (constant data, e.g. soil properties, land cover ...): [pixels, features]
49+ target (e.g. soil moisture, streamflow ...): [pixels, time, 1]
50+
51+ Data type: numpy.float
52+ """
53+ train_csv = LoadCSV (csv_path_s , train_date_list , all_date_list )
54+ x_train = train_csv .load_time_series (var_time_series ) # data size: [pixels, time, features]
55+ c_train = train_csv .load_constant (var_constant , convert_time_series = False ) # [pixels, features]
56+ y_train = train_csv .load_time_series (target , remove_nan = False ) # [pixels, time, 1]
57+
58+ # define model and loss function
59+ loss_fn = RmseLoss () # loss function
60+ # select model: GPU or CPU
61+ if torch .cuda .is_available ():
62+ LSTM = LSTM
63+ else :
64+ LSTM = LSTM_CPU
65+ model = LSTM (nx = len (var_time_series ) + len (var_constant ), ny = len (target ), hiddenSize = HIDDEN_SIZE , warmUpDay = WARM_UP_DAY )
66+
67+ # training the model
68+ last_model = trainModel (
69+ model ,
70+ x_train ,
71+ y_train ,
72+ c_train ,
73+ loss_fn ,
74+ nEpoch = EPOCH ,
75+ miniBatch = [BATCH_SIZE , RHO ],
76+ saveEpoch = 1 ,
77+ saveFolder = output_s ,
78+ )
79+
80+ # validation the result
81+ # load validation datasets
82+ val_date_list = ["2016-04-01" , "2017-03-31" ] # validation period
83+ # load your data. same as training data
84+ val_csv = LoadCSV (csv_path_s , val_date_list , all_date_list )
85+ x_val = val_csv .load_time_series (var_time_series )
86+ c_val = val_csv .load_constant (var_constant , convert_time_series = False )
87+ y_val = val_csv .load_time_series (target , remove_nan = False )
88+
89+ val_epoch = EPOCH # Select the epoch for testing
90+
91+ # load the model
92+ test_model = loadModel (output_s , epoch = val_epoch )
93+
94+ # set the path to save result
95+ save_csv = os .path .join (output_s , "predict.csv" )
96+
97+ # validation
98+ pred_val = testModel (test_model , x_val , c_val , batchSize = len (x_train ), filePathLst = [save_csv ],)
99+
100+ # select the metrics
101+ metrics_list = ["Bias" , "RMSE" , "ubRMSE" , "Corr" ]
102+ pred_val = pred_val .numpy ()
103+ # denormalization
104+ pred_val = trans_norm (pred_val , csv_path_s , var_s = target [0 ], from_raw = False )
105+ y_val = trans_norm (y_val , csv_path_s , var_s = target [0 ], from_raw = False )
106+ pred_val , y_val = np .squeeze (pred_val ), np .squeeze (y_val )
107+ metrics_dict = cal_metric (pred_val , y_val ) # calculate the metrics
108+ metrics = ["Median {}: {:.4f}" .format (x , np .nanmedian (metrics_dict [x ])) for x in metrics_list ]
109+ print ("Epoch {}: {}" .format (val_epoch , metrics ))
0 commit comments