我将 Tensorflow lite 2.1.1-ALPHA-PRECOMPILED 用于带有标头的 arduino nano 33 ble
导入
import numpy as np
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout, Conv1D, MaxPooling1D
模型定义
def get_model(n_timesteps, n_features, n_outputs):
model = Sequential()
model.add(Conv1D(filters=32, kernel_size=3, activation='relu', input_shape=(n_timesteps,n_features)))
model.add(Conv1D(filters=32, kernel_size=3, activation='relu'))
model.add(Dropout(0.5))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(filters=16, kernel_size=5, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(n_outputs, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy', tf.keras.metrics.Precision()])
# fit network
return model
模型 = get_model(128, 6, num_class=4)
型号总结
TF Lite Converter 可以工作,但添加 Expandsdims 操作
# Convert the model to the TensorFlow Lite format without quantization
converter = tf.lite.TFLiteConverter.from_keras_model(model)
def representative_dataset():
for _, samp in enumerate(trainX):
yield [samp.astype(np.float32).reshape(1, 128, 6)]
# Set the optimization flag.
converter.optimizations = [tf.lite.Optimize.DEFAULT]
# Enforce integer only quantization
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
# Provide a representative dataset to ensure we quantize correctly.
converter.representative_dataset = representative_dataset
model_tflite = converter.convert()
# Save the model to disk
open('default_tf/model0_1.tflite', "wb").write(model_tflite)
当我通过 netron 检查 tflite 结构时,我发现包含了 exapandsDims 操作,如下图所示
我已经尝试包含
#include "tensorflow/lite/micro/all_ops_resolver.h"
我的草图但没有解决问题,io也尝试包含
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/micro/kernels/micro_ops.h"
static tflite::MicroMutableOpResolver<1> micro_op_resolver;
void setup(){
micro_op_resolver.AddExpandDims();
}
在这种情况下我收到错误:
micro_op_resolver.AddExpandDims();
^~~~~~~~~~~~~
exit status 1
'class tflite::MicroMutableOpResolver<1>' has no member named 'AddExpandDims'
我解决了将tensorflow的python版本从2.3.0降级到2.1.1的问题,在2.1.1中我训练了模型,在2.1.1中使用reshape操作转换模型intessorflow-lite,在2.3.0中用exapandsdims操作替换它.
我们遇到了同样的问题,但找到了避免降级 Tensorflow 的解决方案(因此我们可以使用最新的 Tensorflow 2.4.1)。 Tensorflow 1D 操作(例如
Conv1D
)是其高阶对应操作(例如 Conv2D
)的专门版本。因此,您可以在不牺牲精度的情况下“升级”您的一维操作。 Tensorflow Lite Converter 执行相同的操作,但将 Conv1D
替换为 Conv2D
以及之前的附加 ExpandDims
层 - 因此出现了问题。
程序如下:
input_shape
,例如,用 input_shape=(3,3,1)
代替 input_shape=(3,3)
Conv1D
至 Conv2D
、MaxPooling1D
至 MaxPooling2D
)kernel_size
图层的 Conv2D
,例如,用 kernel_size=(3,1)
代替 kernel_size=3
pool_size
(例如MaxPooling2D
或GlobalAveragePooling2D
),例如,用pool_size=(2,1)
代替pool_size=2
转换后的模型
def get_model(n_timesteps, n_features, n_outputs):
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3,1), activation='relu', input_shape=(n_timesteps,n_features,1)))
model.add(Conv2D(filters=32, kernel_size=(3,1), activation='relu'))
model.add(Dropout(0.5))
model.add(MaxPooling2D(pool_size=(2,1)))
model.add(Conv2D(filters=16, kernel_size=(5,1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,1)))
model.add(Flatten())
model.add(Dense(n_outputs, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy', tf.keras.metrics.Precision()])
# fit network
return model
缺点
我们试图通过在模型的
Reshape
层之后添加 Input
层来避免调整训练数据和输入数据以进行推理。不幸的是,在修剪、int8 量化并将我们的模型转换为 Tensorflow Lite Micro 后,这导致了另一个问题。无需重塑一切都可以正常工作。
我在使用 Arduino IDE 时遇到了类似的问题,能够安装最新版本的 tflite micro 并且解决了所有问题https://github.com/tensorflow/tflite-micro-arduino-examples
有人有解决办法吗?
我尝试了@cacti5的答案1: 我能够安装最新版本的 tflite micro https://github.com/tensorflow/tflite-micro-arduino-examples 我发现错误:主板不受支持 我正在研究 Arduino Nano connect RP2040
我尝试了 @ssgakhal 的答案 2: 首先,我无法在 Google colab 上安装 2.1.1.tensorflow 版本。 我可以安装的最后一个最旧的版本是 2.8.0。即使安装了这个,我在制作模型时使用的张量流的某些功能也面临着未定义的问题。
请分享您的想法。我面临 EXPAND DIMS 问题