Skip to content

Commit 4f1a3c3

Browse files
Dobiasdclaude
andauthored
Fix loading of single-input/output models (closes #461) (#463)
* Fix loading of single-input/output models (closes #461) Keras serializes a single connection in input_layers/output_layers as a flat ["layer", node_idx, tensor_idx], but multiple connections as a list of such triples. The previous code used create_vector for both, which iterated each element of the flat form and tried to parse a string/int as an inbound node, failing with "invalid format for inbound node" - the exact error from the README example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add regression test for flat input_layers/output_layers format Newer Keras versions serialize a single input/output as a flat triple ["layer", node_idx, tensor_idx] instead of a list containing one such triple. The existing readme_example_main test exercises a single-input model, but only catches this when CI runs against a Keras version that already emits the flat form. Post-process the readme example JSON into flat form and load it from a new test so this code path is covered on any Keras version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Remove synthetic flat-format regression test Drop the JSON post-processing helper and its test. Coverage will instead come from a follow-up CI bump to a Keras version that natively emits the flat input_layers/output_layers form, at which point the existing readme_example_main test exercises this code path against real Keras output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8b7a3d1 commit 4f1a3c3

1 file changed

Lines changed: 12 additions & 4 deletions

File tree

include/fdeep/import_model.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,16 @@ namespace internal {
311311
return node_connection(layer_id, node_idx, tensor_idx);
312312
}
313313

314+
inline std::vector<node_connection> create_node_connections_model_layer(const nlohmann::json& data)
315+
{
316+
assertion(data.is_array(), "input_layers/output_layers must be an array");
317+
// Keras serializes a single connection as a flat triple ["layer", node_idx, tensor_idx],
318+
// and multiple connections as a list of such triples.
319+
if (!data.empty() && !data.front().is_array())
320+
return { create_node_connection_model_layer(data) };
321+
return create_vector<node_connection>(create_node_connection_model_layer, data);
322+
}
323+
314324
inline node_connection create_node_connection(const nlohmann::json& args)
315325
{
316326
assertion(json_obj_has_member(args["config"], "keras_history"),
@@ -369,11 +379,9 @@ namespace internal {
369379

370380
assertion(data["config"]["input_layers"].is_array(), "no input layers");
371381

372-
const auto inputs = create_vector<node_connection>(
373-
create_node_connection_model_layer, data["config"]["input_layers"]);
382+
const auto inputs = create_node_connections_model_layer(data["config"]["input_layers"]);
374383

375-
const auto outputs = create_vector<node_connection>(
376-
create_node_connection_model_layer, data["config"]["output_layers"]);
384+
const auto outputs = create_node_connections_model_layer(data["config"]["output_layers"]);
377385

378386
return std::make_shared<model_layer>(name, layers, inputs, outputs);
379387
}

0 commit comments

Comments
 (0)