PySPOD icon indicating copy to clipboard operation
PySPOD copied to clipboard

Model inference using reference data or predicted values

Open nish-ant opened this issue 8 months ago • 0 comments

Hi

The LSTM has been trained to take a sequence of length _n_seq_in and provide a prediction of length _n_seq_out. As such, the known, initial data of length _n_seq_in would need to be provided to the model, and for the subsequent inference steps, the prediction in the previous inference step is appended to the input sequence. I would expect that for real application, this makes sense as the data in the prediction window is unknown.

However, the inference in the code test_emulation.py calls a function in neural_nets.py where the input data data_in is passed to the model for prediction, instead of using input sequence where the model output output_state is appended:

https://github.com/MathEXLab/PySPOD/blob/9d69ac0724bfffcedaf104b084d050a94100cf65/tests/test_emulation.py#L272

https://github.com/MathEXLab/PySPOD/blob/9d69ac0724bfffcedaf104b084d050a94100cf65/pyspod/emulation/neural_nets.py#L175

I've modified the inference (not tested) to make it use coeffs which is updated with the model output, instead of data_in:

## initialization of variables and vectors
input_batch = np.zeros([1, n_seq_in, n_features])
prediction  = np.zeros([n_seq_out, n_features])
states      = np.zeros([n_seq_in, n_features]     , dtype=complex)
coeffs      = np.zeros([n_features, nt]           , dtype=complex)
idx_x       = np.empty([nt-n_seq_in, n_seq_in]    , int)

## compute real part
name_tmp = 'real'+str(idx)
name_real = os.path.join(self._savedir, name_tmp+'.weights.h5')
self.model.load_weights(name_real)
coeffs[:,:n_seq_in] = data_in[:,:n_seq_in]
cnt = 0
for t in tqdm(range(n_seq_in,nt,n_seq_out), desc='inference_real'):
    idx_x[cnt,...] = np.arange(t-n_seq_in, t)
    states[:,:] = np.transpose(coeffs[:,idx_x[cnt]])
    input_batch[0,:,:] = states[None,:,:].real
    output_state = self.model.predict(input_batch, verbose=0)
    coeffs_tmp = np.reshape(output_state[:], [n_seq_out, n_features])
    lb = (n_seq_out * cnt) + n_seq_in
    ub = (n_seq_out * (cnt + 1)) + n_seq_in
    coeffs[:,lb:ub] = np.transpose(coeffs_tmp)
    cnt = cnt + 1

It would be nice to know which approach has been used in the article Lario et al., 2022. Thanks in advance.

nish-ant avatar Apr 15 '25 13:04 nish-ant