ncnn:https://github.com/Tencent/ncnn
1、.h5模型保存为TFSaveModel格式
import tensorflow as tf
from keras.models import load_model
# 加载Keras模型
model = load_model('encoder_model.h5')
# 转换为SavedModel类型
tf.saved_model.save(model, 'TFSaveModel')
2、TFSaveModel格式模型保存为onnx模型
python3 -m tf2onnx.convert --saved-model TFSaveModel --output onnxModel/encoder_model.onnx
打开https://netron.app/来看下网络结构,主要是先看输入部分的维度(网络结构后面会细讲哈)
可以看到输入维度[unk__64、unk__65、62],我们需要将unk__64、unk__65这两个改为具体数值,否则在导出ncnn模型时会报一些op不支持的错误,那么问题来了,要怎么改呢,我也不知道啊!!!
哈哈哈,开完笑的,都写出来了,怎么会不知道,请听我慢慢说来。
其实数据第一个是batch,第二个是输入句子的最大长度,第三个是字符总数量,我们在推理时,batch size一般为1,所以这个input_1的shape就是[1,max_encoder_seq_length, num_encoder_tokens]
max_encoder_seq_length, num_encoder_tokens 这两个参数可以在训练的时候获取到了,拿到这个input shape 之后,对onnx模型进行simplify,我训练出来的模型时得到的shape是[1,16,62],因此执行以下命令:
python3 -m onnxsim onnxModel/encoder_model.onnx onnxModel/encoder_model-sim.onnx --overwrite-input-shape 1,16,62
可得到简化后的onnx模型啦
这个时候,我们再用https://netron.app打开encoder_model-sim.onnx,可以看到encoder模型的输出了,有两个输出,均为[1,256]的维度
然后我们需要对decoder_model.h5也进行转换,
import tensorflow as tf
from keras.models import load_model
# 加载Keras模型
model = load_model('decoder_model.h5')
# 转换为SavedModel类型
tf.saved_model.save(model, 'TFSaveModel')
python3 -m tf2onnx.convert --saved-model TFSaveModel --output onnxModel/decoder_model.onnx
同样打开模型来看,能看到一共有三个输入,其中的input_3:[unk__57,256],input_4:[unk__58,256],为encoder的输出,因此可以得到这两个输入维度均为[1,256],那 input_2:[unk__55,unk__56,849]的维度是多少呢,我们接着往下看。
我们想一想,解码器除了接受编码器的数据,还有什么数据没给它呢,没有错,就是target_characters的特征,对于英翻中而言就是中文的字符,要解码器解出中文,肯定要把中文数据给它,要不然你让解码器去解空气嘛,实际上这个 input_2的维度就是
target_seq = np.zeros((1, 1, num_decoder_tokens))
num_decoder_tokens同样可以在训练的时候获取到(至于不知道怎么来的,可以看这个系列文章的第一、二篇),我这边得到的num_decoder_tokens是849,当然实际上这个模型的 input_2:[unk__55,unk__56,849]已经给了num_decoder_tokens,我们只需要把unk__55,unk__56都改为1就可以了,即[1,1,849],那么对onnx进行simplify
python3 -m onnxsim onnxModel/decoder_model.onnx onnxModel/decoder_model-sim.onnx --overwrite-input-shape input_2:1,1,849 input_3:1,256 input_4:1,256
成功完成simplify可得到:
完成了onnx模型的转换之后,我们要做的就是将模型转换为ncnn模型
3、onnx模型转换为ncnn
onnx2ncnn onnxModel/encoder_model-sim.onnx ncnnModel/encoder_model.param ncnnModel/encoder_model.bin
onnx2ncnn onnxModel/decoder_model-sim.onnx ncnnModel/decoder_model.param ncnnModel/decoder_model.bin
转换成功可以看到:
4、ncnn模型加载与推理(python版)
未完待续