-
Notifications
You must be signed in to change notification settings - Fork 75.2k
Description
1. System information
- OS Platform and Distribution: Windows 10
- TensorFlow installation: pip package
- TensorFlow library: 2.19
Issue
I'm encountering a critical issue with TensorFlow Lite conversion for on-device training scenarios where the converter systematically ignores weights that are properly loaded from external .h5 files during tf.Module initialization, resulting in severely underweight models and runtime failures.
The problem occurs in a standard transfer learning setup for on-device training where I have a pre-trained MobileNetV2 base model with a custom classification head that needs to be fine-tuned on mobile devices. The model architecture consists of MobileNetV2 as the base feature extractor with a classification head containing BatchNormalization and Dense layers. The intended workflow is to keep the base model frozen and only retrain the classification head on-device using user-specific data.
In my tf.Module implementation, I properly load trained weights from a .h5 file in the init method by first creating the model architecture with MobileNetV2 base and Sequential head layers, then loading a temporary model with the same architecture from the trained weights file, and finally transferring these weights to the respective components using set_weights. The weight loading process completes successfully and I can verify that all weights are properly transferred and the model functions correctly during Python execution with proper inference results.
However, when I convert this working model to TensorFlow Lite format using tf.lite.TFLiteConverter.from_saved_model, the converter appears to completely ignore the weights that were loaded in the initialization phase. The resulting TFLite model is only 0.4 MB instead of the expected 13-15 MB, clearly indicating that the trained weights have been stripped during conversion. When attempting to run inference with the converted model, I consistently encounter a RuntimeError stating "tensorflow/lite/kernels/read_variable.cc:67 variable != nullptr was not true" with "Node number X (READ_VARIABLE) failed to invoke" which suggests that the variables are not properly initialized in the converted model.
2. Code
import tensorflow as tf
import os
NUM_CLASSES = 62
IMG_SIZE = 224
class TransferLearningModel(tf.Module):
def __init__(self, learning_rate=0.0001):
super(TransferLearningModel, self).__init__()
self.base = tf.keras.applications.MobileNetV2(
input_shape=(IMG_SIZE, IMG_SIZE, 3),
include_top=False,
weights=None
)
self.head = tf.keras.Sequential([
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(1280, activation='hard_swish'),
tf.keras.layers.Dense(NUM_CLASSES,
kernel_constraint=tf.keras.constraints.UnitNorm(),
activation='softmax')
], name="classification_head")
self.base.build((None, IMG_SIZE, IMG_SIZE, 3))
self.head.build((None, 7, 7, 1280))
dummy_input = tf.zeros((1, IMG_SIZE, IMG_SIZE, 3))
_ = self.base(dummy_input, training=False)
dummy_features = tf.zeros((1, 7, 7, 1280))
_ = self.head(dummy_features, training=False)
loading_model = tf.keras.Sequential([
tf.keras.applications.MobileNetV2(
input_shape=(IMG_SIZE, IMG_SIZE, 3), include_top=False, weights=None
),
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(1280, activation='hard_swish'),
tf.keras.layers.Dropout(0.4),
tf.keras.layers.Dense(NUM_CLASSES,
kernel_constraint=tf.keras.constraints.UnitNorm(),
activation='softmax')
])
loading_model.load_weights('new_model.weights.h5')
self.base.set_weights(loading_model.layers[0].get_weights())
self.head.layers[1].set_weights(loading_model.layers[2].get_weights())
self.head.layers[2].set_weights(loading_model.layers[3].get_weights())
self.head.layers[3].set_weights(loading_model.layers[5].get_weights())
_ = [v.numpy() for v in self.base.variables]
_ = [v.numpy() for v in self.head.variables]
self.loss_fn = tf.keras.losses.CategoricalCrossentropy()
self.optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
@tf.function(input_signature=[
tf.TensorSpec([None, IMG_SIZE, IMG_SIZE, 3], tf.float32),
])
def infer(self, feature):
"""Runs inference using a manual forward pass without dropout."""
x = tf.keras.applications.mobilenet_v2.preprocess_input(tf.multiply(feature, 255))
bottleneck = self.base(x, training=False)
x_head = self.head.layers[0](bottleneck) # GlobalAveragePooling2D
x_head = self.head.layers[1](x_head, training=False) # BatchNormalization
x_head = self.head.layers[2](x_head) # Dense(1280)
# Dropout is skipped for inference
logits = self.head.layers[3](x_head) # Dense(NUM_CLASSES)
return {'output': logits}
@tf.function(input_signature=[
tf.TensorSpec([None, IMG_SIZE, IMG_SIZE, 3], tf.float32),
])
def load(self, feature):
"""Generates bottleneck features from the base model."""
x = tf.keras.applications.mobilenet_v2.preprocess_input(tf.multiply(feature, 255))
bottleneck = self.base(x, training=False)
return {'bottleneck': bottleneck}
@tf.function(input_signature=[
tf.TensorSpec([None, 7, 7, 1280], tf.float32),
tf.TensorSpec([None, NUM_CLASSES], tf.float32),
])
def train(self, bottleneck, label):
"""Runs one training step on the head model with manual dropout."""
with tf.GradientTape() as tape:
x = self.head.layers[0](bottleneck)
x = self.head.layers[1](x, training=True)
x = self.head.layers[2](x)
# Manually applied dropout as a stateless function
x = tf.nn.dropout(x, rate=0.4)
logits = self.head.layers[3](x)
loss = self.loss_fn(logits, label)
gradients = tape.gradient(loss, self.head.trainable_variables)
self.optimizer.apply_gradients(zip(gradients, self.head.trainable_variables))
result = {'loss': loss}
for grad, var in zip(gradients, self.head.trainable_variables):
result[f'gradient_{var.name}'] = grad
return result
@tf.function(input_signature=[tf.TensorSpec(shape=[], dtype=tf.string)])
def save(self, checkpoint_path):
tensor_names = [v.name for v in self.head.trainable_variables]
tensors_to_save = [v for v in self.head.trainable_variables]
tf.raw_ops.Save(filename=checkpoint_path, tensor_names=tensor_names, data=tensors_to_save, name='save')
return {'checkpoint_path': checkpoint_path}
@tf.function(input_signature=[tf.TensorSpec(shape=[], dtype=tf.string)])
def restore(self, checkpoint_path):
restored_tensors = {}
for var in self.head.trainable_variables:
restored = tf.raw_ops.Restore(file_pattern=checkpoint_path, tensor_name=var.name, dt=var.dtype, name='restore')
restored_shaped = tf.ensure_shape(restored, var.shape)
var.assign(restored_shaped)
restored_tensors[var.name] = restored_shaped
return restored_tensors
@tf.function(input_signature=[])
def initialize_weights(self):
for layer in self.head.layers:
if hasattr(layer, 'kernel_initializer'):
layer.kernel.assign(layer.kernel_initializer(shape=layer.kernel.shape))
return {"status": tf.constant("head weights re-initialized")}
Conversion function
def convert_and_save(saved_model_dir='test10'):
model = TransferLearningModel()
tf.saved_model.save(model, saved_model_dir, signatures={
'serving_default': model.infer.get_concrete_function(),
'train': model.train.get_concrete_function(),
'infer': model.infer.get_concrete_function(),
'save': model.save.get_concrete_function(),
'restore': model.restore.get_concrete_function(),
})
# Convert WITHOUT quantization to avoid calibration errors
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.target_spec.supported_types = [tf.float32]
converter.target_spec.supported_ops = [
tf.lite.OpsSet.TFLITE_BUILTINS,
tf.lite.OpsSet.SELECT_TF_OPS
]
converter.experimental_enable_resource_variables = True
converter.allow_custom_ops = True
size_bytes = get_dir_size(saved_model_dir)
print(f"SavedModel size: {size_bytes / 1024 / 1024:.2f} MB")
tflite_model = converter.convert()
size_mb = len(tflite_model) / (1024 * 1024)
print(f"Final .tflite size: {size_mb:.1f} MB")
return tflite_model
OUTPUT
Creating temporary loading model...
Loading weights from .h5 file...
Weights loaded successfully!
Transferring weights...
Weights successfully transferred!
Checking loaded weights:
Layer 0 (mobilenetv2_1.00_224): 260 weight arrays
Weight 0: shape (3, 3, 3, 32), mean -0.004990
Weight 1: shape (32,), mean 1.168323
Weight 2: shape (32,), mean 0.821846
Weight 3: shape (32,), mean -0.002469
Weight 4: shape (32,), mean 0.239839
Weight 5: shape (3, 3, 32, 1), mean -0.061606
Weight 6: shape (32,), mean 0.736491
Weight 7: shape (32,), mean 1.008941
Weight 8: shape (32,), mean -0.117763
Weight 9: shape (32,), mean 47.107918
Weight 10: shape (1, 1, 32, 16), mean -0.001357
Weight 11: shape (16,), mean 4.052639
Weight 12: shape (16,), mean -0.000762
Weight 13: shape (16,), mean -0.571955
Weight 14: shape (16,), mean 0.530758
Weight 15: shape (1, 1, 16, 96), mean 0.001886
Weight 16: shape (96,), mean 1.987437
Weight 17: shape (96,), mean 1.038911
Weight 18: shape (96,), mean 0.000172
Weight 19: shape (96,), mean 6.268150
Weight 20: shape (3, 3, 96, 1), mean -0.021097
Weight 21: shape (96,), mean 1.036526
Weight 22: shape (96,), mean 0.217431
Weight 23: shape (96,), mean -0.740752
Weight 24: shape (96,), mean 29.843842
Weight 25: shape (1, 1, 96, 24), mean -0.001718
Weight 26: shape (24,), mean 3.472332
Weight 27: shape (24,), mean 0.000772
Weight 28: shape (24,), mean -0.101340
Weight 29: shape (24,), mean 1.053672
Weight 30: shape (1, 1, 24, 144), mean -0.000179
Weight 31: shape (144,), mean 1.239605
Weight 32: shape (144,), mean 0.707251
Weight 33: shape (144,), mean -0.000023
Weight 34: shape (144,), mean 4.371830
Weight 35: shape (3, 3, 144, 1), mean -0.023609
Weight 36: shape (144,), mean 0.955329
Weight 37: shape (144,), mean 0.407806
Weight 38: shape (144,), mean -0.564833
Weight 39: shape (144,), mean 6.630934
Weight 40: shape (1, 1, 144, 24), mean -0.000216
Weight 41: shape (24,), mean 4.241892
Weight 42: shape (24,), mean 0.001505
Weight 43: shape (24,), mean 0.005389
Weight 44: shape (24,), mean 0.822385
Weight 45: shape (1, 1, 24, 144), mean 0.002719
Weight 46: shape (144,), mean 1.485302
Weight 47: shape (144,), mean 0.361015
Weight 48: shape (144,), mean 0.000327
Weight 49: shape (144,), mean 13.439985
Weight 50: shape (3, 3, 144, 1), mean 0.005178
Weight 51: shape (144,), mean 1.122493
Weight 52: shape (144,), mean 0.584812
Weight 53: shape (144,), mean -1.999832
Weight 54: shape (144,), mean 18.353617
Weight 55: shape (1, 1, 144, 32), mean 0.004478
Weight 56: shape (32,), mean 4.152534
Weight 57: shape (32,), mean -0.000241
Weight 58: shape (32,), mean 1.048755
Weight 59: shape (32,), mean 2.018366
Weight 60: shape (1, 1, 32, 192), mean -0.001115
Weight 61: shape (192,), mean 0.924960
Weight 62: shape (192,), mean 0.805240
Weight 63: shape (192,), mean -0.000023
Weight 64: shape (192,), mean 3.979796
Weight 65: shape (3, 3, 192, 1), mean -0.012799
Weight 66: shape (192,), mean 1.091821
Weight 67: shape (192,), mean -0.254846
Weight 68: shape (192,), mean -0.380581
Weight 69: shape (192,), mean 2.862192
Weight 70: shape (1, 1, 192, 32), mean 0.000126
Weight 71: shape (32,), mean 2.271835
Weight 72: shape (32,), mean -0.000410
Weight 73: shape (32,), mean -0.342637
Weight 74: shape (32,), mean 0.317802
Weight 75: shape (1, 1, 32, 192), mean -0.000209
Weight 76: shape (192,), mean 0.930026
Weight 77: shape (192,), mean 0.557240
Weight 78: shape (192,), mean 0.000428
Weight 79: shape (192,), mean 5.045975
Weight 80: shape (3, 3, 192, 1), mean 0.011029
Weight 81: shape (192,), mean 1.238579
Weight 82: shape (192,), mean -0.492934
Weight 83: shape (192,), mean -0.305698
Weight 84: shape (192,), mean 2.098765
Weight 85: shape (1, 1, 192, 32), mean 0.000315
Weight 86: shape (32,), mean 2.040147
Weight 87: shape (32,), mean -0.000458
Weight 88: shape (32,), mean 0.179969
Weight 89: shape (32,), mean 0.278432
Weight 90: shape (1, 1, 32, 192), mean 0.001166
Weight 91: shape (192,), mean 1.271105
Weight 92: shape (192,), mean -0.002536
Weight 93: shape (192,), mean 0.002222
Weight 94: shape (192,), mean 11.708385
Weight 95: shape (3, 3, 192, 1), mean 0.002027
Weight 96: shape (192,), mean 0.882687
Weight 97: shape (192,), mean 1.313080
Weight 98: shape (192,), mean -1.229888
Weight 99: shape (192,), mean 11.423688
Weight 100: shape (1, 1, 192, 64), mean -0.001002
Weight 101: shape (64,), mean 3.254565
Weight 102: shape (64,), mean 0.000102
Weight 103: shape (64,), mean -0.637107
Weight 104: shape (64,), mean 1.550269
Weight 105: shape (1, 1, 64, 384), mean -0.000815
Weight 106: shape (384,), mean 0.814320
Weight 107: shape (384,), mean 0.672446
Weight 108: shape (384,), mean -0.000180
Weight 109: shape (384,), mean 2.438531
Weight 110: shape (3, 3, 384, 1), mean -0.017628
Weight 111: shape (384,), mean 1.154124
Weight 112: shape (384,), mean -0.508610
Weight 113: shape (384,), mean -0.323673
Weight 114: shape (384,), mean 1.676837
Weight 115: shape (1, 1, 384, 64), mean 0.001047
Weight 116: shape (64,), mean 1.695319
Weight 117: shape (64,), mean 0.000040
Weight 118: shape (64,), mean 0.055587
Weight 119: shape (64,), mean 0.269053
Weight 120: shape (1, 1, 64, 384), mean -0.000944
Weight 121: shape (384,), mean 0.830921
Weight 122: shape (384,), mean 0.526378
Weight 123: shape (384,), mean -0.000185
Weight 124: shape (384,), mean 3.323902
Weight 125: shape (3, 3, 384, 1), mean 0.022523
Weight 126: shape (384,), mean 1.067608
Weight 127: shape (384,), mean -0.529855
Weight 128: shape (384,), mean -0.126540
Weight 129: shape (384,), mean 1.195757
Weight 130: shape (1, 1, 384, 64), mean 0.000536
Weight 131: shape (64,), mean 1.754528
Weight 132: shape (64,), mean 0.000096
Weight 133: shape (64,), mean 0.003234
Weight 134: shape (64,), mean 0.186160
Weight 135: shape (1, 1, 64, 384), mean -0.000904
Weight 136: shape (384,), mean 0.899831
Weight 137: shape (384,), mean 0.210936
Weight 138: shape (384,), mean -0.000010
Weight 139: shape (384,), mean 3.614889
Weight 140: shape (3, 3, 384, 1), mean 0.074855
Weight 141: shape (384,), mean 0.946092
Weight 142: shape (384,), mean -0.470055
Weight 143: shape (384,), mean -0.006143
Weight 144: shape (384,), mean 0.933807
Weight 145: shape (1, 1, 384, 64), mean 0.000237
Weight 146: shape (64,), mean 1.684268
Weight 147: shape (64,), mean 0.000014
Weight 148: shape (64,), mean 0.022946
Weight 149: shape (64,), mean 0.162055
Weight 150: shape (1, 1, 64, 384), mean -0.000522
Weight 151: shape (384,), mean 1.062904
Weight 152: shape (384,), mean 0.452908
Weight 153: shape (384,), mean -0.001081
Weight 154: shape (384,), mean 7.720592
Weight 155: shape (3, 3, 384, 1), mean 0.051686
Weight 156: shape (384,), mean 0.918869
Weight 157: shape (384,), mean 0.544240
Weight 158: shape (384,), mean -0.123217
Weight 159: shape (384,), mean 4.652045
Weight 160: shape (1, 1, 384, 96), mean -0.000054
Weight 161: shape (96,), mean 2.630192
Weight 162: shape (96,), mean -0.000499
Weight 163: shape (96,), mean -0.011032
Weight 164: shape (96,), mean 1.210233
Weight 165: shape (1, 1, 96, 576), mean -0.000249
Weight 166: shape (576,), mean 0.949186
Weight 167: shape (576,), mean 0.050647
Weight 168: shape (576,), mean 0.000028
Weight 169: shape (576,), mean 2.054210
Weight 170: shape (3, 3, 576, 1), mean 0.059372
Weight 171: shape (576,), mean 0.913221
Weight 172: shape (576,), mean -0.443031
Weight 173: shape (576,), mean -0.095461
Weight 174: shape (576,), mean 1.177511
Weight 175: shape (1, 1, 576, 96), mean 0.000196
Weight 176: shape (96,), mean 1.760301
Weight 177: shape (96,), mean -0.000486
Weight 178: shape (96,), mean -0.090314
Weight 179: shape (96,), mean 0.202150
Weight 180: shape (1, 1, 96, 576), mean -0.000266
Weight 181: shape (576,), mean 0.939002
Weight 182: shape (576,), mean -0.100255
Weight 183: shape (576,), mean 0.000089
Weight 184: shape (576,), mean 2.886753
Weight 185: shape (3, 3, 576, 1), mean 0.094127
Weight 186: shape (576,), mean 0.763083
Weight 187: shape (576,), mean -0.503600
Weight 188: shape (576,), mean 0.014172
Weight 189: shape (576,), mean 1.009352
Weight 190: shape (1, 1, 576, 96), mean 0.000029
Weight 191: shape (96,), mean 2.047109
Weight 192: shape (96,), mean -0.000192
Weight 193: shape (96,), mean -0.026967
Weight 194: shape (96,), mean 0.124487
Weight 195: shape (1, 1, 96, 576), mean -0.000788
Weight 196: shape (576,), mean 1.196608
Weight 197: shape (576,), mean -0.898888
Weight 198: shape (576,), mean 0.000247
Weight 199: shape (576,), mean 7.363639
Weight 200: shape (3, 3, 576, 1), mean 0.163633
Weight 201: shape (576,), mean 0.523937
Weight 202: shape (576,), mean 0.836180
Weight 203: shape (576,), mean -0.316935
Weight 204: shape (576,), mean 1.697920
Weight 205: shape (1, 1, 576, 160), mean 0.000127
Weight 206: shape (160,), mean 2.020815
Weight 207: shape (160,), mean 0.000245
Weight 208: shape (160,), mean 0.157705
Weight 209: shape (160,), mean 0.457630
Weight 210: shape (1, 1, 160, 960), mean -0.000120
Weight 211: shape (960,), mean 0.918483
Weight 212: shape (960,), mean 0.336421
Weight 213: shape (960,), mean 0.000074
Weight 214: shape (960,), mean 1.480832
Weight 215: shape (3, 3, 960, 1), mean 0.016892
Weight 216: shape (960,), mean 1.047455
Weight 217: shape (960,), mean -0.647139
Weight 218: shape (960,), mean -0.289626
Weight 219: shape (960,), mean 1.682111
Weight 220: shape (1, 1, 960, 160), mean 0.000044
Weight 221: shape (160,), mean 1.712374
Weight 222: shape (160,), mean 0.000154
Weight 223: shape (160,), mean -0.081155
Weight 224: shape (160,), mean 0.223927
Weight 225: shape (1, 1, 160, 960), mean 0.000224
Weight 226: shape (960,), mean 0.911476
Weight 227: shape (960,), mean 0.089401
Weight 228: shape (960,), mean 0.000616
Weight 229: shape (960,), mean 3.142139
Weight 230: shape (3, 3, 960, 1), mean 0.145435
Weight 231: shape (960,), mean 0.782417
Weight 232: shape (960,), mean -1.058022
Weight 233: shape (960,), mean 0.030494
Weight 234: shape (960,), mean 1.226274
Weight 235: shape (1, 1, 960, 160), mean -0.000375
Weight 236: shape (160,), mean 2.350677
Weight 237: shape (160,), mean 0.000120
Weight 238: shape (160,), mean -0.115010
Weight 239: shape (160,), mean 0.059018
Weight 240: shape (1, 1, 160, 960), mean -0.000209
Weight 241: shape (960,), mean 0.938125
Weight 242: shape (960,), mean -0.678866
Weight 243: shape (960,), mean 0.001223
Weight 244: shape (960,), mean 7.140286
Weight 245: shape (3, 3, 960, 1), mean 0.039748
Weight 246: shape (960,), mean 1.171708
Weight 247: shape (960,), mean 0.285590
Weight 248: shape (960,), mean -0.197455
Weight 249: shape (960,), mean 0.759097
Weight 250: shape (1, 1, 960, 320), mean 0.000019
Weight 251: shape (320,), mean 1.848464
Weight 252: shape (320,), mean -0.000037
Weight 253: shape (320,), mean -0.027375
Weight 254: shape (320,), mean 0.305095
Weight 255: shape (1, 1, 320, 1280), mean -0.000043
Weight 256: shape (1280,), mean 4.713092
Weight 257: shape (1280,), mean -4.648569
Weight 258: shape (1280,), mean -0.000076
Weight 259: shape (1280,), mean 1.068525
Layer 1 (global_average_pooling2d_11): No weights
Layer 2 (batch_normalization_11): 4 weight arrays
Weight 0: shape (1280,), mean 1.013351
Weight 1: shape (1280,), mean -0.000582
Weight 2: shape (1280,), mean 0.337323
Weight 3: shape (1280,), mean 0.174516
Layer 3 (dense_22): 2 weight arrays
Weight 0: shape (1280, 1280), mean -0.000280
Weight 1: shape (1280,), mean 0.005108
Layer 4 (dropout_5): No weights
Layer 5 (dense_23): 2 weight arrays
Weight 0: shape (1280, 62), mean -0.002399
Weight 1: shape (62,), mean -0.000846
INFO:tensorflow:Assets written to: test10\assets
INFO:tensorflow:Assets written to: test10\assets
WARNING:absl:Importing a function (__inference_internal_grad_fn_217398) with ops with unsaved custom gradients. Will likely fail if a gradient is requested.
WARNING:absl:Importing a function (__inference_internal_grad_fn_217359) with ops with unsaved custom gradients. Will likely fail if a gradient is requested.
SavedModel size: 30.64 MB
WARNING:absl:Importing a function (__inference_internal_grad_fn_217398) with ops with unsaved custom gradients. Will likely fail if a gradient is requested.
WARNING:absl:Importing a function (__inference_internal_grad_fn_217359) with ops with unsaved custom gradients. Will likely fail if a gradient is requested.
Final .tflite size: 0.4 MB`
3. Failure after conversion
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[110], line 17
14 input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
15 interpreter.set_tensor(input_details[0]['index'], input_data)
---> 17 interpreter.invoke()
19 # The function `get_tensor()` returns a copy of the tensor data.
20 # Use `tensor()` in order to get a pointer to the tensor.
21 output_data = interpreter.get_tensor(output_details[0]['index'])
973 """Invoke the interpreter.
974
975 Be sure to set the input sizes, allocate tensors and fill values before
(...)
982 ValueError: When the underlying interpreter fails raise ValueError.
983 """
984 self._ensure_safe()
--> 985 self._interpreter.Invoke()
RuntimeError: tensorflow/lite/kernels/read_variable.cc:67 variable != nullptr was not true.Node number 268 (READ_VARIABLE) failed to invoke.
5. Any other info / logs
The conversion appears successful (no errors during conversion), but the generated model is fundamentally broken:
Expected model size: 13-15 MB (reflecting MobileNetV2 + classification head weights)
Actual model size: 0.4 MB (indicating weights were stripped during conversion)
Runtime behavior: Immediate failure with READ_VARIABLE error when attempting inference
Root cause: Weights loaded in tf.Module.init() from external .h5 files are not preserved in the converted model
can the problem be with the hard_swish activation function or BatchNormalizationLayer?