Tensorflow 量化 - 无法解析模型:pybind11::init():工厂函数返回 nullptr

Tensorflow Quantization - Failed to parse the model: pybind11::init(): factory function returned nullptr

我正在研究要部署在嵌入式系统上的 TensorFlow 模型。为此,我需要将模型量化为 int8。 该模型由三个不同的模型组成:

  1. CNN 作为特征提取器
  2. 用于时间预测的 TCN
  3. FC/Dense 作为最后一个分类器。

我从 this post 开始实施了 TCN,并做了一些修改。本质上,TCN 只是一组一维卷积(带有一些 0 填充)加上一个加法运算。

## Define TCN newer
tcn_input = tf.keras.Input(shape=tf.keras.backend.int_shape(glue)[1:])
# first causal conv for channel adaptation
k=1; d=1; padding = (k - 1) * d
# tcn_input_p = tf.pad(tcn_input, tf.constant([(0,0), (1,0), (0,0)]) * padding)
temp_block_input = tf.keras.layers.Conv1D(32,k, padding='valid', data_format='channels_last', name='adapt_conv')(tcn_input)

# TEMPORAL BLOCK 1
k=2; d=1; padding = (k - 1) * d
# temp_block_input_p = tf.pad(temp_block_input, tf.constant([(0,0), (1,0), (0,0)]) * padding)
temp_block_input_p = tf.keras.layers.ZeroPadding1D((padding, 0))(temp_block_input)
x = tf.keras.layers.Conv1D(32,k, padding='valid', data_format='channels_last', dilation_rate=d, activation='relu', name='conv1')(temp_block_input_p)
temp_block_input = tf.keras.layers.Add()([temp_block_input, x])

# TEMPORAL BLOCK 2
k=2; d=2; padding = (k - 1) * d
# temp_block_input_p = tf.pad(temp_block_input, tf.constant([(0,0), (1,0), (0,0)]) * padding)
temp_block_input_p = tf.keras.layers.ZeroPadding1D((padding, 0))(temp_block_input)
x = tf.keras.layers.Conv1D(32,k, padding='valid', data_format='channels_last', dilation_rate=d, activation='relu', name='conv2')(temp_block_input_p)
temp_block_input = tf.keras.layers.Add()([temp_block_input, x])

# TEMPORAL BLOCK 3
k=2; d=4; padding = (k - 1) * d
# temp_block_input_p = tf.pad(temp_block_input, tf.constant([(0,0), (1,0), (0,0)]) * padding)
temp_block_input_p = tf.keras.layers.ZeroPadding1D((padding, 0))(temp_block_input)
x = tf.keras.layers.Conv1D(32,k, padding='valid', data_format='channels_last', dilation_rate=d, activation='relu', name='conv3')(temp_block_input_p)
x = tf.keras.layers.Add()([temp_block_input, x])

tcn = tf.keras.Model(tcn_input, x, name='tcn')

tcn.summary()

我尝试使用以下代码量化 TCN(适用于其他模型,例如 CNN)

converter = tf.lite.TFLiteConverter.from_keras_model(tcn)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8

def representative_dataset(): # generate the inputs
    for sample in x_train:
        yield [cnn(i) for i in sample]

converter.representative_dataset = representative_dataset
quant_model = converter.convert()

with open(os.path.join('models','tcn_q.bin'), 'wb') as f:
    f.write(quant_model)

我收到以下错误。我也没有成功尝试以下:

Failed to parse the model: pybind11::init(): factory function returned nullptr.

到目前为止我找不到解决方案,但我相信应该可以量化这个网络,因为我使用的操作是基本的并且应该得到支持。 如果有任何想法,我也可以使用一些解决方法,但我想了解是哪一部分造成了问题。

作为侧节点,我还使用 netron.app 检查了网络,似乎使用一些额外的 Reshape、ExpandDims 和 BatchToSpace 层将 1D 卷积转换为 2D 卷积。不过我不确定这是否是个问题。

根据@JaesungChung的建议,问题似乎可以使用 tf-nightly 解决(我在 2.5.0-dev20210325 上测试过)。

在 2.4.0 中使用变通方法将 Conv1D 转换为宽度为 1 的 Conv2D 并使用扁平内核 (1, kernel_size) 可以获得相同的效果。