Pytorch训练的模型转.onnx、.pb、.h5、.tftile

Pytorch训练的模型转.onnx、.pb、.h5、.tftile

由于深度学习训练出后的参数往往是保存在指定的模型中的,这在使用时将不是那么方便,同时为了减小训练出的模型所占的内存空间,通常只保存了模型的参数,而未将整个网络一起保存,这样便直接导致了保存的模型无法直接转换成其他格式的模型。在此,我们提供了一个将pytorch模型转换成tftile的方法,希望能帮助大家任意转换各种模型以便使用!

Pytorch模型导入

这一部分我们根据pytorch保存整个模型以及只保存模型参数进行了不同的导入方式分析,并对将模型导入到CPU或GPU的方式进行了说明。
当Pytorch保存的是整个模型的时候,可以直接对模型进行导入,如:

import torch
torch_model = torch.load(model_path) #model_path是模型所在路径

要判断模型是否导入成功,只用运行一下下列语句,若不报错即导入成功:

torch_model.eval()

若上述语句运行报错,则极大可能是保存的为模型参数,此时需要结合网络结构一起将模型参数进行导入,以ResNet18为例:

import torch
from models.resnet import ResNet18 #将模型对应的网咯导入进来,大部分测试代码中能够找到

## 根据将模型导入至CPUGPU对模型导入方式进行定义
def load_model(model, pretrained_path, load_to_cpu):
    print('Loading pretrained model from {}'.format(pretrained_path))
    if load_to_cpu:
        pretrained_dict = torch.load(pretrained_path, map_location=lambda storage, loc: storage)
    else:
        device = torch.cuda.current_device()
        pretrained_dict = torch.load(pretrained_path, map_location=lambda storage, loc: storage.cuda(device))
    model.load_state_dict(pretrained_dict, strict=False)
    return model

net = ResNet18(phase = 'test') #这里需要根据模型的传入参数进行修改
net = load_model(net, model_path, True)

导入完成后运行下列代码,查看模型是否导入成功

net.eval() # 查看模型是否导入成功
print(net) # 可以将网络结构进行打印,方便查看

当然,当我们直接运行别人的工程时,可在测试代码中找到net.eval(),在其后一般认为其模型导入结束

Pytorch模型转.onnx、.pb、.h5

这一部分的转换我们参考了博客的方法,亲测可行,这里直接附上代码,当然使用前需要自己提前安装相应模块,可直接通过pip install即可

import torch
import onnx
from onnx_tf.backend import prepare
from onnx2keras import onnx_to_keras
import keras
import tensorflow as tf

def pth_to_onnx(input_path,output_path):
    '''
    1)声明:使用本函数之前,必须保证你手上已经有了.pth模型文件.
    2)功能:本函数功能四将pytorch训练得到的.pth文件转化为onnx文件。
    '''
    torch_model = torch.load(input_path)       # pytorch模型加载,此处加载的模型包含图和参数
    # torch_model = selfmodel()  # 若只保存参数,selfmodel参考上述loadmodel进行改写
    torch_model.eval()
    x = torch.randn(1,1,28,28)          # 输入一张28*28的灰度图像并生成张量
    export_onnx_file = output_path         #输出.onnx文件的文件路径及文件名
    torch.onnx.export(torch_model,
                      x,
                      export_onnx_file,
                      opset_version=9,    #操作的版本,稳定操作集为9
                      do_constant_folding=True,          # 是否执行常量折叠优化
                      input_names=["input"],        # 输入名
                      output_names=["output"],       # 输出名
                      dynamic_axes={"input": {0: "batch_size"},         # 批处理变量
                                    "output": {0: "batch_size"}}
                      )
    # onnx_model = onnx.load('model_all.onnx')    #加载.onnx文件
    # onnx.checker.check_model(onnx_model)
    # print(onnx.helper.printable_graph(onnx_model.graph))       #打印.onnx文件信息

def onnx_to_pb(output_path):
    '''
    将.onnx模型保存为.pb文件模型
    '''
    model = onnx.load(output_path) #加载.onnx模型文件
    tf_rep = prepare(model)
    tf_rep.export_graph('model_all.pb')    #保存最终的.pb文件

def onnx_to_h5(output_path ):
    '''
    将.onnx模型保存为.h5文件模型,并打印出模型的大致结构
    '''
    onnx_model = onnx.load(output_path)
    k_model = onnx_to_keras(onnx_model, ['input'])
    keras.models.save_model(k_model, 'kerasModel.h5', overwrite=True, include_optimizer=True)    #第二个参数是新的.h5模型的保存地址及文件名
    # 下面内容是加载该模型,然后将该模型的结构打印出来
    model = tf.keras.models.load_model('kerasModel.h5')
    model.summary()
    print(model)
    
if __name__=='__main__':
    input_path = "model_all.pth"    #输入需要转换的.pth模型路径及文件名
    output_path = "model_all.onnx"  #转换为.onnx后文件的保存位置及文件名
    pth_to_onnx(input_path,output_path)  #执行pth转onnx函数,具体转换参数去该函数里面修改
    # onnx_pre(output_path)   #【可选项】若有需要,可以使用onnxruntime进行部署测试,看所转换模型是否可用,其中,output_path指加载进去的onnx格式模型所在路径及文件名
    # onnx_to_pb(output_path)   #将onnx模型转换为pb模型
    # onnx_to_h5(output_path )   #将onnx模型转换为h5模型

以上即实现了将Pytorch下训练保存的模型转换为.onnx、.pb、.h5。

.h5文件转.tftile文件

这一部分的转换我们参考了网址相关内容,转换方式如下:
首选使用pip install安装相应模块,并将刚才转换好的.h5模型进行导入及预测

import os
import time
import tensorflow as tf

# 恢复 keras 模型,并预测
keras_file = '../Models/model.h5'
model = tf.keras.models.load_model(keras_file)
# model.summary()
# tf.autograph.set_verbosity(0)

start_time = time.time()
pred = model.predict(image_bn)
stop_time = time.time()

print(f"prediction: {pred}")
print('time: {:.3f}ms'.format((stop_time - start_time) * 1000))
print("model size: {:.2f} MB".format(os.path.getsize(keras_file)/1024/1024))

输出为:
prediction: [[0.9730365 0.02696355]]
time: 126.018ms
model size: 7.46 MB
其次是将刚才导入的.h5模型转换成.tftile格式

# 最直接的保存为tflite,没有任何量化
converter = tf.lite.TFLiteConverter.from_keras_model(model)

tflite_model = converter.convert()

tflite_file = Path("../Models/Tflites/model.tflite")
tflite_file.write_bytes(tflite_model)

最后对导出的.tftile模型进行导入,查看模型相关信息,代码如下:

tflite_file = Path("../Models/Tflites/model.tflite")
# tflite 模型推理
interpreter = tf.lite.Interpreter(model_path=str(tflite_file))
interpreter.allocate_tensors()

# Get input and output tensors.
input_details = interpreter.get_input_details()[0]
output_details = interpreter.get_output_details()[0]

interpreter.set_tensor(input_details['index'], image_bn)

start_time = time.time()
interpreter.invoke()
stop_time = time.time()

output_data = interpreter.get_tensor(output_details['index'])
print(f"prediction: {output_data}")
print('time: {:.3f}ms'.format((stop_time - start_time) * 1000))
print("model size: {:.2f} MB".format(os.path.getsize(tflite_file)/1024/1024))

输出结果如:
prediction: [[0.9730364 0.02696356]]
time: 1.637ms
model size: 2.47 MB
至此,从Pytorch中训练保存的模型已顺利完成到.onnx、.pb、.h5、.tftile的转化,欢迎大家收藏转载,也感谢文中提及的博客及网址对本文的贡献!

  • 12
    点赞
  • 116
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值