2024-06-21 16:41:34 +08:00
# TODO: inherent from the benchmark base class
import torch
2024-07-03 17:42:07 +08:00
2024-07-05 17:42:00 +08:00
from rdagent.components.coder.model_coder.model import ModelImplementation
2024-06-21 16:41:34 +08:00
def get_data_conf ( init_val ):
# TODO: design this step in the workflow
in_dim = 1000
in_channels = 128
exec_config = { "model_eval_param_init" : init_val }
node_feature = torch . randn ( in_dim , in_channels )
edge_index = torch . randint ( 0 , in_dim , ( 2 , 2000 ))
return ( node_feature , edge_index ), exec_config
class ModelImpValEval :
"""
2024-07-03 17:42:07 +08:00
Evaluate the similarity of the model structure by changing the input and observe the output.
2024-06-21 16:41:34 +08:00
Assumption:
- If the model structure is similar, the output will change in similar way when we change the input.
2024-06-27 18:15:31 +08:00
Challenge:
2024-07-10 15:45:43 +08:00
- The key difference between it and implementing models is that we have parameters in the layers (Model operators often have no parameters or are given parameters).
2024-06-27 18:15:31 +08:00
- we try to initialize the model param in similar value. So only the model structure is different.
Comparing the correlation of following sequences
- modelA[init1](input1).hidden_out1, modelA[init1](input2).hidden_out1, ...
- modelB[init1](input1).hidden_out1, modelB[init1](input2).hidden_out1, ...
2024-06-28 11:45:23 +08:00
2024-06-27 18:15:31 +08:00
For each hidden output, we can calculate a correlation. The average correlation will be the metrics.
2024-06-21 16:41:34 +08:00
"""
2024-07-03 17:42:07 +08:00
def evaluate ( self , gt : ModelImplementation , gen : ModelImplementation ):
2024-06-21 16:41:34 +08:00
round_n = 10
eval_pairs : list [ tuple ] = []
# run different input value
for _ in range ( round_n ):
# run different model initial parameters.
for init_val in [ - 0.2 , - 0.1 , 0.1 , 0.2 ]:
2024-07-10 15:45:43 +08:00
_ , gt_res = gt . execute ( input_value = init_val , param_init_value = init_val )
_ , res = gen . execute ( input_value = init_val , param_init_value = init_val )
2024-06-21 16:41:34 +08:00
eval_pairs . append (( res , gt_res ))
# flat and concat the output
res_batch , gt_res_batch = [], []
for res , gt_res in eval_pairs :
res_batch . append ( res . reshape ( - 1 ))
gt_res_batch . append ( gt_res . reshape ( - 1 ))
res_batch = torch . stack ( res_batch )
gt_res_batch = torch . stack ( gt_res_batch )
res_batch = res_batch . detach () . numpy ()
gt_res_batch = gt_res_batch . detach () . numpy ()
# pearson correlation of each hidden output
def norm ( x ):
return ( x - x . mean ( axis = 0 )) / x . std ( axis = 0 )
2024-06-28 11:45:23 +08:00
2024-06-21 16:41:34 +08:00
dim_corr = ( norm ( res_batch ) * norm ( gt_res_batch )) . mean ( axis = 0 ) # the correlation of each hidden output
# aggregate all the correlation
avr_corr = dim_corr . mean ()
2024-06-28 11:45:23 +08:00
# FIXME:
2024-06-21 16:41:34 +08:00
# It is too high(e.g. 0.944) .
2024-06-28 11:45:23 +08:00
# Check if it is not a good evaluation!!
2024-06-21 16:41:34 +08:00
# Maybe all the same initial params will results in extreamly high correlation without regard to the model structure.
return avr_corr