cchapmanbird / emri_selection_biases

1 stars 0 forks source link

Getting unphysical SNRs from the SNR network #1

Open AminBoumerdassi opened 7 months ago

AminBoumerdassi commented 7 months ago

Hi Christian,

I'm a PhD student from the University of Auckland researching ML-based methods for detecting EMRI signals. I've been looking for a fast way to calculate EMRI SNRs so as to get EMRI parameters with realistic SNRs. I've been testing out your SNR network as it looks like it's exactly what I need. I loaded up your pre-trained model, and tested it on the example inputs and outputs. See below:

from torch import nn
import numpy as np
from emri_selection_biases.models.training.utils import create_mlp
from few.utils.utility import xI_to_Y

model_weight_path= '/nesi/project/uoa00195/software/emri_selection_biases/models/snr/T10_LR1e-4_10L_5B_128N/model.pth'

input_features= 9#['logM', 'logq', 'a', 'e0', 'Y0', 'thetaS', 'phiS-phiK', 'thetaK', 'tplunge']
output_features= 1#['SNR']
layers= 10
neurons= np.array(np.ones(layers,dtype=np.int32)*128).tolist()
activation= nn.SiLU
# model_name= "T10_LR1e-4_10L_5B_128N"#f'T10_LR1e-4_{layers}L_{n_batches}B_{neurons[0]}N'
model_name = "T10_LR1e-4_10L_5B_128N"

model = create_mlp(input_features=input_features, output_features=output_features, neurons=neurons, layers=layers, activation=activation, model_name=model_name)

model.load_state_dict(torch.load(model_weight_path, map_location=torch.device('cpu')))
model.eval()#this sets the model to evaluation mode

examples_x = np.load("emri_selection_biases/models/snr/T10_LR1e-4_10L_5B_128N/xdata_inputs.npy")
examples_y = np.load("emri_selection_biases/models/snr/T10_LR1e-4_10L_5B_128N/ydata_inputs.npy")

prediction_test = model(torch.Tensor(examples_x[0]))
print("Output of SNR_sqr = ", prediction_test.item())

The input array [6.34704346e+00, -4.47055629e+00, 4.99738489e-01, 3.00986938e-01, -1.30887249e-03, 1.57253552e+00, 3.15107768e+00, 1.56876012e+00, 5.00662640e+00] returns an output SNR of -0.82 while the expected output should be 59.54.

I can't seem to figure out where I've gone wrong on this. Would you be able to assist?

cchapmanbird commented 6 months ago

Hi, thank you for your interest in my work!

Apologies for the confusion, this data release could do with some better documentation. The arrays xdata_inputs.npy and ydata_inputs.npy are not sets of parameters, rather they are mean and standard-deviation vectors used to normalise the input data and un-normalise the output data. For instance, we can estimate an example SNR via

logM = 6
logq = -5
a = 0.3
e0 = 0.3
Y0 = 0.9
thetaS = np.pi/3
deltaphi = np.pi/4
thetaK = np.pi/4
tplunge = 3 # years

x_check = np.array([logM, logq, a, e0, Y0, thetaS, deltaphi, thetaK, tplunge])

x_rescaled = torch.Tensor((x_check - examples_x[0])/(examples_x[1]))

prediction_out = model(torch.Tensor(x_rescaled))

rescaled_prediction = prediction_out * examples_y[1] + examples_y[0]

print("Output of SNR_sqr = ", rescaled_prediction.item())

which returns an SNR of 110.82. Note that this is an SNR at a fiducial distance of 1Gpc.

I would however recommend generating and training your own SNR prediction network - this way you can specify the bounds of the parameter space and have full control of noise or detector response assumptions. You can do this using my package poplar, which will allow you construct a neural network interpolant from a dataset of SNRs you construct.

Let me know if you have any further questions!