leap-model-parser 0.1.185.dev10__tar.gz → 0.1.185.dev12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/PKG-INFO +2 -2
  2. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/leap_graph_editor.py +33 -157
  3. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/pyproject.toml +2 -2
  4. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/LICENSE +0 -0
  5. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/README.md +0 -0
  6. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/__init__.py +0 -0
  7. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/contract/__init__.py +0 -0
  8. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/contract/graph.py +0 -0
  9. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/contract/importmodelresponse.py +0 -0
  10. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/contract/nodedata.py +0 -0
  11. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/contract/ui_components.json +0 -0
  12. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/keras_json_model_import.py +0 -0
  13. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/model_parser.py +0 -0
  14. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/__init__.py +0 -0
  15. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/layerpedia/__init__.py +0 -0
  16. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/layerpedia/layerpedia.py +0 -0
  17. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/tlinspection/__init__.py +0 -0
  18. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/tlinspection/leapinspection.py +0 -0
  19. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/uicomponents/__init__.py +0 -0
  20. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/uicomponents/generatenodedata.py +0 -0
  21. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/uicomponents/tensorflowinscpection.py +0 -0
  22. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/uicomponents/ui_components.json +0 -0
  23. {leap_model_parser-0.1.185.dev10 → leap_model_parser-0.1.185.dev12}/leap_model_parser/utils/uicomponents/ui_components_config.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: leap-model-parser
3
- Version: 0.1.185.dev10
3
+ Version: 0.1.185.dev12
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/leap-model-parser
6
6
  License: MIT
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.8
13
13
  Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
- Requires-Dist: code-loader (==1.0.87.dev7)
15
+ Requires-Dist: code-loader (==1.0.87.dev8)
16
16
  Requires-Dist: keras-data-format-converter (==0.1.22)
17
17
  Requires-Dist: leap-model-rebuilder (==0.1.7)
18
18
  Requires-Dist: numpy (>=1.22.3,<2.0.0)
@@ -7,45 +7,6 @@ from keras import Model
7
7
  from leap_model_parser.contract.graph import Node as Node, OutputData, ConnectionOutput, ConnectionInput, InputData
8
8
 
9
9
 
10
- # class NodeMappingType(Enum):
11
- # Visualizer = 'Visualizer'
12
- # Metric = 'Metric'
13
- # GroundTruth = 'GroundTruth'
14
- # Input = 'Input'
15
- # Layer = 'Layer'
16
- # Loss = 'Loss'
17
- # CustomLoss = 'CustomLoss'
18
- # Optimizer = 'Optimizer'
19
- # Prediction0 = 'Prediction0'
20
- # Prediction1 = 'Prediction1'
21
- # Prediction2 = 'Prediction2'
22
- # Prediction3 = 'Prediction3'
23
- # Input0 = 'Input0'
24
- # Input1 = 'Input1'
25
- # Input2 = 'Input2'
26
- # Input3 = 'Input3'
27
- # Input4 = 'Input4'
28
- # Input5 = 'Input5'
29
- #
30
- #
31
- #
32
- #
33
- #
34
- # @dataclass
35
- # class NodeMapping:
36
- # name: str
37
- # type: NodeMappingType
38
- # user_unique_name: Optional[str] = None
39
- # sub_type: Optional[str] = None
40
- # arg_names: Optional[List[str]] = None
41
- #
42
- #
43
- # @dataclass
44
- # class NodeConnection:
45
- # node: NodeMapping
46
- # node_inputs: Optional[Dict[str, NodeMapping]]
47
- # prediction_type_name: Optional[str] = None
48
-
49
10
 
50
11
  class LeapGraphEditor:
51
12
  def __init__(self, model_graph: Dict[str, Node], keras_model: Model):
@@ -55,33 +16,18 @@ class LeapGraphEditor:
55
16
  node_ids_as_int = [int(node_id) for node_id in model_graph.keys()]
56
17
  self._next_node_id_index = max(node_ids_as_int) + 1
57
18
 
58
- # def add_dataset(self, dataset_name: str, raw_dataset_version: Dict[str, Any],
59
- # dataset_parse_result: DatasetIntegParseResult):
60
- #
61
- # LeapGraphEditor._add_setup_to_metadata(raw_dataset_version['metadata'], dataset_parse_result)
62
- # raw_dataset_version['name'] = dataset_name
63
- #
64
- # dataset_node = self._get_dataset_node()
65
- # dataset_node.data['datasetVersion'] = raw_dataset_version
66
- # dataset_node.data['selected_dataset'] = dataset_name
67
- # self._add_arg_names_to_visualizers(dataset_parse_result)
68
19
 
69
20
  def add_connections_to_graph(self, connections: List[NodeConnection]):
70
- connections = self._validate_and_reorder_connections_list(connections)
21
+ connections = self._replace_prediction_node_name_with_correct_name(connections)
71
22
  for connection in connections:
72
23
  self._add_node_connection_to_graph(connection)
73
24
 
74
25
  def _add_node_connection_to_graph(self, node_connection: NodeConnection):
75
- # if node_connection.node.type.value.startswith('Input'):
76
- # input_index = int(node_connection.node.type.value.replace('Input', ''))
77
- #
78
- # origin_name = self.keras_model.inputs[input_index].node.layer.name
79
- #
80
- # _find_node_by_origin_name
81
- # # elif node_connection.node.type == NodeMappingType.Input:
82
- # # self._find_or_add_input_node()
83
-
84
-
26
+ if node_connection.node.type == NodeMappingType.PredictionLabels:
27
+ prediction_labels_name = node_connection.node.name
28
+ prediction_node = list(node_connection.node_inputs.values())[0]
29
+ prediction_node_id = self._find_node_by_origin_name(prediction_node.name).id
30
+ self.model_graph[prediction_node_id].data['prediction_type'] = prediction_labels_name
85
31
  if node_connection.node.type == NodeMappingType.Visualizer:
86
32
  new_visualizer_node_id = self._add_visualizer_node(
87
33
  node_connection.node.name, node_connection.node.sub_type,
@@ -97,26 +43,12 @@ class LeapGraphEditor:
97
43
  input_node_id = self._find_or_add_input_node(node)
98
44
  self._add_connection_to_node(new_metric_node_id, input_name, input_node_id)
99
45
  elif node_connection.node.type in (NodeMappingType.Loss, NodeMappingType.CustomLoss):
100
- prediction_type_name = node_connection.prediction_type_name
101
- # if prediction_type_name is None:
102
- # raise Exception("prediction_type_name is required for loss connection")
103
-
104
46
  new_loss_node_id = self._add_loss_node(node_connection.node.name,
105
47
  node_connection.node.type == NodeMappingType.CustomLoss,
106
48
  node_connection.node.arg_names)
107
49
  for input_name, node in node_connection.node_inputs.items():
108
50
  input_node_id = self._find_or_add_input_node(node)
109
- # if node.type == NodeMappingType.Layer:
110
- # self.model_graph[input_node_id].data['prediction_type'] = prediction_type_name
111
51
  self._add_connection_to_node(new_loss_node_id, input_name, input_node_id)
112
- # elif node_connection.node.type == NodeMappingType.Optimizer:
113
- # new_optimizer_node_id = self._add_optimizer_node(node_connection.node.name)
114
- # loss_node_ids = self._get_all_loss_node_ids()
115
- # assert len(loss_node_ids) > 0
116
- # for i, loss_node_id in enumerate(loss_node_ids):
117
- # self._add_connection_to_node(new_optimizer_node_id, str(i), loss_node_id)
118
- # self.model_graph[new_optimizer_node_id].data['custom_input_keys'] = list(
119
- # self.model_graph[new_optimizer_node_id].inputs.keys())
120
52
  else:
121
53
  raise Exception(f"Can't add node of type {node_connection.node.type.name}")
122
54
 
@@ -140,30 +72,18 @@ class LeapGraphEditor:
140
72
  return node
141
73
  return None
142
74
 
143
- def _validate_and_reorder_connections_list(self, connections: List[NodeConnection]) -> List[NodeConnection]:
144
- # optimizers = [connection for connection in connections if connection.node.type == NodeType.Optimizer]
75
+ def _replace_prediction_node_name_with_correct_name(self, connections: List[NodeConnection]) -> List[NodeConnection]:
145
76
  for connection in connections:
146
77
  if connection.node_inputs is None:
147
78
  continue
148
79
  for input_name, input_node in connection.node_inputs.items():
149
80
  if 'Prediction' in input_node.type.value:
150
- prediction_index= int(input_node.type.value.replace('Prediction', ''))
81
+ prediction_index = int(input_node.type.value.replace('Prediction', ''))
151
82
  origin_name = self.keras_model.outputs[prediction_index].node.layer.name
152
83
  input_node.name = origin_name
153
84
 
154
85
  return connections
155
- losses = [connection for connection in connections
156
- if connection.node.type in (NodeMappingType.Loss, NodeMappingType.CustomLoss)]
157
- visualizers = [connection for connection in connections if connection.node.type == NodeMappingType.Visualizer]
158
86
 
159
- # if len(optimizers) == 0:
160
- # raise Exception('At least one optimizer needed')
161
- # if len(losses) == 0:
162
- # raise Exception('At least one loss needed')
163
- # if len(optimizers) + len(losses) + len(visualizers) < len(connections):
164
- # raise Exception('Unsupported node type')
165
-
166
- return visualizers + losses
167
87
 
168
88
  def _find_encoder_node_id(self, encoder_name: str) -> Optional[str]:
169
89
  for node_id, node_response in self.model_graph.items():
@@ -247,9 +167,6 @@ class LeapGraphEditor:
247
167
  outputs={
248
168
  f'{new_node_id}-loss': ConnectionOutput([])
249
169
  }
250
- # outputs={
251
- # f'{new_node_id}-loss': {'connections': []}
252
- # }
253
170
  )
254
171
  if arg_names is not None:
255
172
  loss_node.data['arg_names'] = arg_names
@@ -258,28 +175,12 @@ class LeapGraphEditor:
258
175
  self.model_graph[new_node_id] = loss_node
259
176
  return new_node_id
260
177
 
261
- # def _add_optimizer_node(self, optimizer_name: str) -> str:
262
- # new_node_id = self._generate_new_node_id()
263
- #
264
- # optimizer_node = NodeResponse(
265
- # new_node_id,
266
- # optimizer_name,
267
- # data={'type': 'Optimizer', 'selected': optimizer_name},
268
- # inputs={},
269
- # outputs={})
270
- #
271
- # self.model_graph[new_node_id] = optimizer_node
272
- # return new_node_id
273
-
274
178
  def _get_output_name_from_node_id(self, input_node_id: str, input_name: Optional[str] = None) -> str:
275
179
  input_node_outputs_len = len(self.model_graph[input_node_id].outputs)
276
180
  if input_node_outputs_len == 0:
277
181
  output_name_to_add = f'{input_node_id}-feature_map'
278
182
  self.model_graph[input_node_id].outputs[output_name_to_add] = ConnectionOutput([])
279
183
 
280
- # self.model_graph[input_node_id].outputs[output_name_to_add] = {
281
- # 'connections': []
282
- # }
283
184
  return output_name_to_add
284
185
  if input_node_outputs_len == 1:
285
186
  return list(self.model_graph[input_node_id].outputs.keys())[0]
@@ -296,16 +197,32 @@ class LeapGraphEditor:
296
197
  output_name = self._get_output_name_from_node_id(input_node_id, input_name)
297
198
  input_name = f'{node_id}-{input_name}'
298
199
  self.model_graph[node_id].inputs[input_name] = ConnectionInput([InputData(input_node_id, output_name)])
299
- # self.model_graph[node_id].inputs[input_name] = {
300
- # 'connections': [{'data': {}, 'node': input_node_id, 'output': output_name}]
301
- # }
302
-
303
- # if 'connections' not in self.model_graph[input_node_id].outputs[output_name]:
304
- # self.model_graph[input_node_id].outputs[output_name]['connections'] = []
305
- output_connection = OutputData(node_id, input_name)
306
- # output_connection = {'input': input_name, 'node': node_id, 'data': {}}
200
+
307
201
  self.model_graph[input_node_id].outputs[output_name].connections.append(output_connection)
308
202
 
203
+ def _handle_input_node_with_index(self, input_node: NodeMapping):
204
+ input_index = int(input_node.type.value.replace('Input', ''))
205
+ origin_name = self.keras_model.inputs[input_index].node.layer.name
206
+ input_node_id = self._find_input_node_by_origin_name(origin_name).id
207
+ self.model_graph[input_node_id].data['output_name'] = input_node.name
208
+ output_keys = list(self.model_graph[input_node_id].outputs.keys())
209
+ for output_key in output_keys:
210
+ new_output_key = f'{input_node_id}-{input_node.name}'
211
+ if output_key == new_output_key:
212
+ continue
213
+ self.model_graph[input_node_id].outputs[new_output_key] = self.model_graph[input_node_id].outputs[
214
+ output_key]
215
+ del self.model_graph[input_node_id].outputs[output_key]
216
+ for connection in self.model_graph[input_node_id].outputs[new_output_key].connections:
217
+ for connection_input in self.model_graph[connection.node].inputs[connection.input].connections:
218
+ if connection_input.output == output_key:
219
+ connection_input.output = new_output_key
220
+
221
+ if input_node_id is None:
222
+ raise Exception(f"Couldn't find input node by origin name {origin_name}")
223
+
224
+ return input_node_id
225
+
309
226
  def _find_or_add_input_node(self, input_node: NodeMapping) -> str:
310
227
  if input_node.type in (NodeMappingType.Input, NodeMappingType.GroundTruth):
311
228
  input_node_id = self._find_encoder_node_id(input_node.name)
@@ -315,24 +232,7 @@ class LeapGraphEditor:
315
232
  else:
316
233
  raise Exception(f'Couldnt find input node name {input_node.name}')
317
234
  elif 'Input' in input_node.type.value:
318
- input_index = int(input_node.type.value.replace('Input', ''))
319
- origin_name = self.keras_model.inputs[input_index].node.layer.name
320
- input_node_id = self._find_input_node_by_origin_name(origin_name).id
321
- self.model_graph[input_node_id].data['output_name'] = input_node.name
322
- output_keys = list(self.model_graph[input_node_id].outputs.keys())
323
- for output_key in output_keys:
324
- new_output_key = f'{input_node_id}-{input_node.name}'
325
- if output_key == new_output_key:
326
- continue
327
- self.model_graph[input_node_id].outputs[new_output_key] = self.model_graph[input_node_id].outputs[output_key]
328
- del self.model_graph[input_node_id].outputs[output_key]
329
- for connection in self.model_graph[input_node_id].outputs[new_output_key].connections:
330
- for connection_input in self.model_graph[connection.node].inputs[connection.input].connections:
331
- if connection.output == output_key:
332
- connection.output = new_output_key
333
-
334
- if input_node_id is None:
335
- raise Exception(f"Couldn't find input node by origin name {origin_name}")
235
+ input_node_id = self._handle_input_node_with_index(input_node)
336
236
  elif input_node.type.value.startswith('Prediction'):
337
237
  input_node_id = self._find_node_by_origin_name(input_node.name).id
338
238
  else:
@@ -350,13 +250,6 @@ class LeapGraphEditor:
350
250
  loss_node_ids.append(node_id)
351
251
  return loss_node_ids
352
252
 
353
- # def _get_dataset_node(self) -> NodeResponse:
354
- # for node_response in self.model_graph.values():
355
- # if 'type' in node_response.data and node_response.data['type'] == 'dataset':
356
- # return node_response
357
- #
358
- # raise Exception("Didn't find dataset node")
359
-
360
253
  @staticmethod
361
254
  def _convert_dataclass_to_json_dict(_dataclass):
362
255
  if isinstance(_dataclass, Enum):
@@ -372,20 +265,3 @@ class LeapGraphEditor:
372
265
  for element in _dataclass
373
266
  ]
374
267
  return _dataclass
375
-
376
- # @staticmethod
377
- # def _add_setup_to_metadata(dataset_version_metadata: Dict[str, Any],
378
- # dataset_parse_result: DatasetIntegParseResult):
379
- # setup_json = LeapGraphEditor._convert_dataclass_to_json_dict(dataset_parse_result.setup)
380
- #
381
- # dataset_version_metadata['setup'] = setup_json
382
-
383
- # def _add_arg_names_to_visualizers(self, dataset_parse_result: DatasetIntegParseResult):
384
- # visualizer_instance_by_name: Dict[str, VisualizerInstance] = {
385
- # visualizer_instance.name: visualizer_instance
386
- # for visualizer_instance in dataset_parse_result.setup.visualizers
387
- # }
388
- #
389
- # for _, node_response in self.model_graph.items():
390
- # if node_response.data['type'] == 'Visualizer':
391
- # node_response.data['arg_names'] = visualizer_instance_by_name[node_response.data['selected']].arg_names
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "leap-model-parser"
3
- version = "0.1.185.dev10"
3
+ version = "0.1.185.dev12"
4
4
  description = ""
5
5
  authors = ["idan <idan.yogev@tensorleap.ai>"]
6
6
  license = "MIT"
@@ -22,7 +22,7 @@ onnx2kerastl = "0.0.174"
22
22
  keras-data-format-converter = "0.1.22"
23
23
  leap-model-rebuilder = "0.1.7"
24
24
  tensorflow-io-gcs-filesystem = "0.34.0"
25
- code-loader = "1.0.87.dev7"
25
+ code-loader = "1.0.87.dev8"
26
26
 
27
27
  [tool.poetry.dev-dependencies]
28
28
  pytest = "^7.1.1"