@@ -29,12 +29,12 @@ class ExampleReproIssueSoftmax
2929 MYODDWEB_PROFILE_FUNCTION (" ExampleReproIssueSoftmax" );
3030
3131 // 17 inputs, 80 LSTM, 40 LSTM, 7 total outputs (2 in branch 0, 5 in branch 1)
32- std::vector<unsigned > topology = { 17 , 80 , 40 , 7 };
32+ std::vector<unsigned > topology = { 17 , 64 , 32 , 7 };
3333
3434 std::vector<LayerDetails> trunk_hidden_layers =
3535 {
36- LayerDetails (Layer::Architecture::Lstm, 80 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 ),
37- LayerDetails (Layer::Architecture::Lstm, 40 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 )
36+ LayerDetails (Layer::Architecture::Gru, 64 , activation (activation::method::tanh, 0.1 ), 0.1 , 0.0001 , OptimiserType::NadamW, 0.9 ),
37+ LayerDetails (Layer::Architecture::Gru, 32 , activation (activation::method::tanh, 0.1 ), 0.1 , 0.0001 , OptimiserType::NadamW, 0.9 )
3838 };
3939
4040 std::vector<MultiOutputLayerDetails> multi_output_layer_details;
@@ -43,38 +43,39 @@ class ExampleReproIssueSoftmax
4343 MultiOutputLayerDetails b0
4444 (
4545 {
46- LayerDetails (Layer::Architecture::FF , 16 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 ),
47- LayerDetails (Layer::Architecture::FF , 32 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 )
46+ LayerDetails (Layer::Architecture::FF , 32 , activation (activation::method::tanh, 0.01 ), 0 , 0.0001 , OptimiserType::NadamW, 0.9 ),
47+ LayerDetails (Layer::Architecture::FF , 16 , activation (activation::method::tanh, 0.01 ), 0 , 0.0001 , OptimiserType::NadamW, 0.9 )
4848 },
49- OutputLayerDetails (2 , activation (activation::method::tanh, 0.01 ), ErrorCalculation::type::huber_direction_loss, EvaluationConfig (0.01 , 0.15 , 0.3 , 0.3 , false , 1.0 ), 0.0 , OptimiserType::NadamW, 0.95 )
49+ OutputLayerDetails (2 , activation (activation::method::tanh, 0.1 ), ErrorCalculation::type::huber_direction_loss, EvaluationConfig (0.01 , 0.15 , 0.3 , 0.3 , false , 1.0 ), 0.0 , OptimiserType::NadamW, 0.99 )
5050 );
5151
5252 // Branch 1: 5 outputs, Softmax
5353 MultiOutputLayerDetails b1
5454 (
5555 {
56- LayerDetails (Layer::Architecture::FF , 16 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 ),
57- LayerDetails (Layer::Architecture::FF , 32 , activation (activation::method::tanh, 0.01 ), 0.15 , 0.0001 , OptimiserType::NadamW, 0.95 )
56+ LayerDetails (Layer::Architecture::FF , 32 , activation (activation::method::tanh, 0.01 ), 0 , 0.0001 , OptimiserType::NadamW, 0.9 ),
57+ LayerDetails (Layer::Architecture::FF , 16 , activation (activation::method::tanh, 0.01 ), 0 , 0.0001 , OptimiserType::NadamW, 0.9 )
5858 },
59- OutputLayerDetails (5 , activation (activation::method::softmax, 0.01 ), ErrorCalculation::type::cross_entropy, EvaluationConfig (0.0 , 0.2 , 1.0 , 0.3 , false , 1.0 ), 0.0 , OptimiserType::NadamW, 0.95 )
59+ OutputLayerDetails (5 , activation (activation::method::softmax, 0.01 ), ErrorCalculation::type::cross_entropy, EvaluationConfig (0.0 , 0.2 , 1.0 , 0.3 , false , 1.0 ), 0.0 , OptimiserType::NadamW, 0.99 )
6060 );
6161
6262 multi_output_layer_details.push_back (b0);
6363 multi_output_layer_details.push_back (b1);
6464
6565 auto options = NeuralNetworkOptions::create (topology)
66- .with_batch_size (32 ) // Match REAL
66+ .with_batch_size (32 )
6767 .with_output_layer_details (multi_output_layer_details)
6868 .with_log_level (log_level)
69- .with_learning_rate (0.0015 ) // Match REAL
70- .with_learning_rate_warmup (0.0003 , 0.07 ) // Match REAL
71- .with_learning_rate_decay_rate (0.985 ) // Match REAL
72- .with_clip_threshold (1.5 ) // Match REAL
73- .with_number_of_epoch (500 )
69+ .with_learning_rate (0.0005 )
70+ .with_learning_rate_warmup (0.0002 , 0.07 )
71+ .with_learning_rate_decay_rate (0.985 )
72+ .with_clip_threshold (1.5 )
73+ .with_number_of_epoch (5000 )
7474 .with_hidden_layers (trunk_hidden_layers)
75- .with_shuffle_training_data (true )
75+ .with_shuffle_training_data (false )
76+ .with_shuffle_bptt_batches (true )
7677 .with_enable_bptt (true )
77- .with_bptt_max_ticks (24 ) // Match REAL
78+ .with_bptt_max_ticks (24 )
7879 .with_final_error_calculation_types ({
7980 ErrorCalculation::type::huber_loss,
8081 ErrorCalculation::type::huber_direction_loss,
@@ -191,110 +192,129 @@ class ExampleReproIssueSoftmax
191192 for (int i = 0 ; i < 5 ; ++i)
192193 Logger::info (" Class " , i, " : " , (double )counts[i] / outputs.size () * 100.0 , " %" );
193194
194- nn->train (inputs, outputs);
195+ try {
196+ nn->train (inputs, outputs);
195197
196- // Metrics for both branches
197- std::vector<ErrorCalculation::type> all_layer_metrics = {
198- ErrorCalculation::type::huber_direction_loss,
199- ErrorCalculation::type::cross_entropy,
200- ErrorCalculation::type::directional_confidence_score,
201- ErrorCalculation::type::prediction_coverage
202- };
198+ // Metrics for both branches
199+ std::vector<ErrorCalculation::type> all_layer_metrics = {
200+ ErrorCalculation::type::huber_direction_loss,
201+ ErrorCalculation::type::cross_entropy,
202+ ErrorCalculation::type::directional_confidence_score,
203+ ErrorCalculation::type::prediction_coverage
204+ };
203205
204- auto metrics_results = nn->calculate_forecast_metrics_all_layers (all_layer_metrics, true );
206+ auto metrics_results = nn->calculate_forecast_metrics_all_layers (all_layer_metrics, true );
205207
206- Logger::info (" Branch 0 Metrics (Regression/Huber):" );
207- if (metrics_results.size () > 0 )
208- {
209- for (const auto & m : metrics_results[0 ])
208+ Logger::info (" Branch 0 Metrics (Regression/Huber):" );
209+ if (metrics_results.size () > 0 )
210210 {
211- Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
211+ for (const auto & m : metrics_results[0 ])
212+ {
213+ Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
214+ }
212215 }
213- }
214216
215- Logger::info (" Branch 1 Metrics (Softmax/Cross-Entropy):" );
216- if (metrics_results.size () > 1 )
217- {
218- for (const auto & m : metrics_results[1 ])
217+ Logger::info (" Branch 1 Metrics (Softmax/Cross-Entropy):" );
218+ if (metrics_results.size () > 1 )
219219 {
220- Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
220+ for (const auto & m : metrics_results[1 ])
221+ {
222+ Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
223+ }
221224 }
222- }
223225
224- // Detailed sample check
225- Logger::info (" Checking sample 0 results:" );
226- auto res0 = nn->think (inputs[0 ]);
227- Logger::info (" Think: " , Logger::vec_to_string ( res0) );
228- Logger::info (" Given: " , Logger::vec_to_string ( outputs[0 ]) );
226+ // Detailed sample check
227+ Logger::info (" Checking sample 0 results:" );
228+ auto res0 = nn->think (inputs[0 ]);
229+ Logger::info (" Think: " , res0);
230+ Logger::info (" Given: " , outputs[0 ]);
229231
230- if (!save_nn_file.empty ())
231- {
232- NeuralNetworkSerializer::save (*nn, save_nn_file);
232+ if (!save_nn_file.empty ())
233+ {
234+ NeuralNetworkSerializer::save (*nn, save_nn_file);
235+ }
236+ } catch (const std::exception& e) {
237+ Logger::set_level (Logger::LogLevel::Error);
238+ Logger::error (" ReproIssueMarketData failed with error: " , e.what ());
233239 }
234240
235241 delete nn;
236242 TEST_END
237243 }
238244
239- static void ReproIssueMarketData (const std::string& save_nn_file, const std::string& csv_file, Logger::LogLevel log_level, size_t max_rows = 0 )
240- {
241- TEST_START (" Repro Issue Market Data" )
242- NeuralNetwork* nn = create_neural_network (log_level);
243- std::vector<std::vector<double >> inputs, outputs;
244-
245- if (!load_csv_data (csv_file, inputs, outputs, max_rows))
245+ static void ReproIssueMarketData (const std::string& save_nn_file, const std::string& csv_file, Logger::LogLevel log_level, size_t max_rows = 0 )
246246 {
247- Logger::error (" Failed to load CSV: " , csv_file);
248- delete nn;
249- return ;
250- }
247+ TEST_START (" Repro Issue Market Data" )
248+ NeuralNetwork* nn = create_neural_network (log_level);
249+ std::vector<std::vector<double >> inputs, outputs;
251250
252- Logger::info (" Loaded " , inputs.size (), " samples from " , csv_file);
253- // Verify distribution
254- std::vector<int > counts (5 , 0 );
255- for (const auto & o : outputs)
256- {
251+ if (!load_csv_data (csv_file, inputs, outputs, max_rows))
252+ {
253+ Logger::error (" Failed to load CSV: " , csv_file);
254+ delete nn;
255+ return ;
256+ }
257+
258+ Logger::info (" Loaded " , inputs.size (), " samples from " , csv_file);
259+ // Verify distribution
260+ std::vector<int > counts (5 , 0 );
261+ for (const auto & o : outputs)
262+ {
263+ for (int i = 0 ; i < 5 ; ++i)
264+ {
265+ if (o[2 + i] > 0.5 ) { counts[i]++; break ; }
266+ }
267+ }
257268 for (int i = 0 ; i < 5 ; ++i)
258269 {
259- if (o[ 2 + i] > 0.5 ) { counts[i]++; break ; }
270+ Logger::info ( " Class " , i, " : " , ( double ) counts[i] / outputs. size () * 100.0 , " % " );
260271 }
261- }
262- for (int i = 0 ; i < 5 ; ++i)
263- Logger::info (" Class " , i, " : " , (double )counts[i] / outputs.size () * 100.0 , " %" );
264272
265- nn->train (inputs, outputs);
273+ try {
274+ nn->train (inputs, outputs);
266275
267- // Monitoring
268- // Logger::info("Final Softmax Weights Sum: ", nn->get_output_layer_weights_sum(1));
269- // Logger::info("Final Logits (sample 0): ", Logger::vec_to_string(nn->get_output_layer_logits(1, inputs[0])));
276+ // Monitoring
277+ // Logger::info("Final Softmax Weights Sum: ", nn->get_output_layer_weights_sum(1));
278+ // Logger::info("Final Logits (sample 0): ", Logger::vec_to_string(nn->get_output_layer_logits(1, inputs[0])));
270279
271- // Calculate metrics for both layers - request only appropriate metrics for each
272- std::vector<ErrorCalculation::type> all_layer_metrics = { ErrorCalculation::type::huber_direction_loss, ErrorCalculation::type::cross_entropy, ErrorCalculation::type::directional_confidence_score, ErrorCalculation::type::prediction_coverage };
280+ // Calculate metrics for both layers - request only appropriate metrics for each
281+ std::vector<ErrorCalculation::type> all_layer_metrics = { ErrorCalculation::type::huber_direction_loss, ErrorCalculation::type::cross_entropy, ErrorCalculation::type::directional_confidence_score, ErrorCalculation::type::prediction_coverage };
273282
274- auto all_layer_metrics_results = nn->calculate_forecast_metrics_all_layers (all_layer_metrics, true );
283+ auto all_layer_metrics_results = nn->calculate_forecast_metrics_all_layers (all_layer_metrics, true );
275284
276- Logger::info (" Layer 0 Metrics (Regression):" );
277- for (const auto & m : all_layer_metrics_results[0 ])
278- {
279- Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
280- }
285+ Logger::info (" Layer 0 Metrics (Regression):" );
286+ for (const auto & m : all_layer_metrics_results[0 ])
287+ {
288+ Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
289+ }
281290
282- Logger::info (" Layer 1 Metrics (Softmax):" );
283- for (const auto & m : all_layer_metrics_results[1 ])
284- {
285- Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
286- }
291+ Logger::info (" Layer 1 Metrics (Softmax):" );
292+ for (const auto & m : all_layer_metrics_results[1 ])
293+ {
294+ Logger::info (" " , ErrorCalculation::type_to_string (m.error_type ()), " : " , m.error ());
295+ }
296+
297+ auto size = static_cast <size_t >(inputs.size () / 2.0 );
287298
288- auto res0 = nn->think (inputs[0 ]);
289- Logger::debug (" Think:" , Logger::vec_to_string ( res0) );
290- Logger::debug (" Given:" , Logger::vec_to_string ( outputs[0 ]) );
299+ auto res0 = nn->think (inputs[0 ]);
300+ Logger::debug (" Think:" , res0);
301+ Logger::debug (" Given:" , outputs[0 ]);
291302
292- auto res1 = nn->think (inputs[1 ]);
293- Logger::debug (" Think:" , Logger::vec_to_string (res1) );
294- Logger::debug (" Given:" , Logger::vec_to_string ( outputs[1 ]) );
303+ auto res = nn->think (inputs[size ]);
304+ Logger::debug (" Think:" , res );
305+ Logger::debug (" Given:" , outputs[size] );
295306
307+ auto res1 = nn->think (inputs[1 ]);
308+ Logger::debug (" Think:" , res1);
309+ Logger::debug (" Given:" , outputs[1 ]);
296310
297- NeuralNetworkSerializer::save (*nn, save_nn_file);
311+ NeuralNetworkSerializer::save (*nn, save_nn_file);
312+ }
313+ catch (const std::exception& e)
314+ {
315+ Logger::set_level (Logger::LogLevel::Error);
316+ Logger::error (" ReproIssueMarketData failed with error: " , e.what ());
317+ }
298318 delete nn;
299319 TEST_END
300320 }
0 commit comments