Skip to content

Commit 152b838

Browse files
committed
add valid export
1 parent 3bdfec3 commit 152b838

1 file changed

Lines changed: 60 additions & 26 deletions

File tree

text_classifier/strategies/multilabel.py

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -313,50 +313,84 @@ def export_to_onnx(self):
313313

314314
with open(output_path, "wb") as f:
315315
f.write(model_proto.SerializeToString())
316-
logger.info(f"TensorFlow multilabel model successfully exported to ONNX: {output_path}")
316+
317+
# Verify export success by checking file size
318+
file_size = Path(output_path).stat().st_size
319+
if file_size > 1000: # If larger than 1KB, it's likely a real model
320+
logger.info(f"TensorFlow multilabel model successfully exported to ONNX: {output_path} ({file_size} bytes)")
321+
return # Exit early on success
322+
else:
323+
logger.warning(f"ONNX export produced small file ({file_size} bytes), trying fallback methods...")
324+
raise Exception("Export produced suspiciously small file")
317325

318326
except Exception as e:
319327
logger.error(f"Failed to export TensorFlow multilabel model to ONNX: {e}")
320-
# Try fallback approach with older opset
328+
# Try functional model approach as primary fallback
321329
try:
322-
logger.info("Trying fallback ONNX export method with older opset...")
330+
logger.info("Trying functional model approach...")
323331
actual_input_shape = self.model.input_shape[1:]
332+
# Create a functional model with correct architecture
333+
input_layer = tf.keras.layers.Input(shape=actual_input_shape, name="float_input")
334+
x = tf.keras.layers.Dense(128, activation="relu")(input_layer)
335+
x = tf.keras.layers.Dropout(0.5)(x)
336+
outputs = tf.keras.layers.Dense(self.num_classes, activation="sigmoid")(x)
337+
338+
functional_model = tf.keras.Model(inputs=input_layer, outputs=outputs, name="multilabel_model")
339+
340+
# Copy weights from Sequential model to Functional model
341+
# Sequential: [Dense(128), Dropout, Dense(4)]
342+
# Functional: [Input, Dense(128), Dropout, Dense(4)]
343+
for i, layer in enumerate(self.model.layers):
344+
if layer.get_weights():
345+
# Skip input layer (no weights) and map correctly
346+
if i == 0: # First layer in Sequential (Dense)
347+
functional_model.layers[1].set_weights(layer.get_weights()) # Skip input layer
348+
elif i == 1: # Second layer (Dropout - no weights)
349+
continue # Skip dropout layer
350+
elif i == 2: # Third layer (Dense)
351+
functional_model.layers[3].set_weights(layer.get_weights()) # Skip input and dropout
352+
353+
# Convert functional model to ONNX
324354
spec = (tf.TensorSpec((None, actual_input_shape[0]), tf.float32, name="float_input"),)
325355
model_proto, _ = tf2onnx.convert.from_keras(
326-
self.model, input_signature=spec, opset=11 # Use older opset
356+
functional_model, input_signature=spec, opset=11
327357
)
358+
328359
with open(output_path, "wb") as f:
329360
f.write(model_proto.SerializeToString())
330-
logger.info(f"TensorFlow multilabel model exported to ONNX using fallback method: {output_path}")
361+
362+
# Verify export success
363+
file_size = Path(output_path).stat().st_size
364+
if file_size > 1000:
365+
logger.info(f"TensorFlow multilabel model exported to ONNX using functional model approach: {output_path} ({file_size} bytes)")
366+
return # Exit early on success
367+
else:
368+
logger.warning(f"Functional model approach produced small file ({file_size} bytes), trying next fallback...")
369+
raise Exception("Functional model export produced suspiciously small file")
370+
331371
except Exception as e2:
332-
logger.error(f"Fallback ONNX export also failed: {e2}")
333-
# Try functional model approach as last resort
372+
logger.error(f"Functional model approach failed: {e2}")
373+
# Try fallback approach with older opset as secondary fallback
334374
try:
335-
logger.info("Trying functional model approach...")
336-
# Create a functional model with correct architecture
337-
input_layer = tf.keras.layers.Input(shape=actual_input_shape, name="float_input")
338-
x = tf.keras.layers.Dense(128, activation="relu")(input_layer)
339-
x = tf.keras.layers.Dropout(0.5)(x)
340-
outputs = tf.keras.layers.Dense(self.num_classes, activation="sigmoid")(x)
341-
342-
functional_model = tf.keras.Model(inputs=input_layer, outputs=outputs, name="multilabel_model")
343-
344-
# Copy weights from Sequential model to Functional model
345-
for i, layer in enumerate(self.model.layers[1:]): # Skip input layer
346-
if layer.get_weights():
347-
functional_model.layers[i + 1].set_weights(layer.get_weights())
348-
349-
# Convert functional model to ONNX
375+
logger.info("Trying direct conversion with older opset...")
376+
actual_input_shape = self.model.input_shape[1:]
350377
spec = (tf.TensorSpec((None, actual_input_shape[0]), tf.float32, name="float_input"),)
351378
model_proto, _ = tf2onnx.convert.from_keras(
352-
functional_model, input_signature=spec, opset=11
379+
self.model, input_signature=spec, opset=11 # Use older opset
353380
)
354-
355381
with open(output_path, "wb") as f:
356382
f.write(model_proto.SerializeToString())
357-
logger.info(f"TensorFlow multilabel model exported to ONNX using functional model approach: {output_path}")
383+
384+
# Verify export success
385+
file_size = Path(output_path).stat().st_size
386+
if file_size > 1000:
387+
logger.info(f"TensorFlow multilabel model exported to ONNX using older opset: {output_path} ({file_size} bytes)")
388+
return # Exit early on success
389+
else:
390+
logger.warning(f"Older opset approach produced small file ({file_size} bytes), creating placeholder...")
391+
raise Exception("Older opset export produced suspiciously small file")
358392
except Exception as e3:
359-
logger.error(f"Functional model approach also failed: {e3}")
393+
logger.error(f"Older opset approach also failed: {e3}")
360394
# Create a simple ONNX model manually as last resort
361395
logger.warning("Creating minimal ONNX model file as last resort...")
362396
try:

0 commit comments

Comments
 (0)