美文网首页
Paddle训练之后的镜像-动态图转静态图,并使用inferen

Paddle训练之后的镜像-动态图转静态图,并使用inferen

作者: onmeiei | 来源:发表于2022-05-16 11:56 被阅读0次
    class SampleInfer(Processor):
        preprocess: []
        pool: paddle.inference.PredictorPool
        ids: {}
    
        def __init__(self):
            logging.info("Loading model file")
            # 加载动态图,并转换为静态图
            model = RedNet26(pretrained='/share/PaddleClas/output/RedNet26/latest')
            # 静态图需要制定输入的形状,`None`代表可变,例如:本例子中,每次可以同时预测多张图像。
            static_mode = paddle.jit.to_static(model, input_spec=[InputSpec(shape=[None, 3, 224, 224], name='x')])
            # 保存jit(静态模型)
            paddle.jit.save(static_mode, '/share/PaddleClas/output/RedNet26/static/latest')
    
            # 开始模型加载,需要指定两个参数,一个是网络结构,一个是训练参数。此时不再需要RedNet26网络结构了,直接加载就可以了。
            config = paddle.inference.Config('/share/PaddleClas/output/RedNet26/static/latest.pdmodel', '/share/PaddleClas/output/RedNet26/static/latest.pdiparams')
            # 使用0号显卡的100M显存
            config.enable_use_gpu(100, 0)
            # predictor不是线程安全的,所以需要创建一个PredictorPool来保证线程的并发安全性。
            self.pool = paddle.inference.PredictorPool(config, 4)
            
            # 数据预处理,与训练时一致即可。
            self.preprocess = []
            self.preprocess.append(DecodeImage(to_rgb=True, channel_first=False))
            self.preprocess.append(ResizeImage(resize_short=256))
            self.preprocess.append(CropImage(size=224))
            self.preprocess.append(NormalizeImage(scale=1.0, mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], order=''))
            self.preprocess.append(ToCHWImage())
            
            self.ids = {}
            self.idx = 0
            
        def process(self, msg: str):
            # 线程号绑定predictor,这里未处理锁,正式代码自行处理一下。
            tid = threading.current_thread().ident
            if not tid in self.ids:
                self.idx += 1
                self.ids[tid] = int(self.idx)
            idx = self.ids[tid]
            logging.info("tid({}) use idx({})".format(tid, idx))
            
            # 第一步:获取图像内容
            img = base64.decodebytes(bytes(msg, encoding="utf-8"))
            req = img
            # 第二步:加载图像内容,并进行预处理(匹配网络输入的数据结构)
            for process in self.preprocess:
                req = process(req)
            # 第三步:升维,因为只有一张图,所以需要升维成4D,以匹配InputSpec
            req = np.expand_dims(req, axis=0)
    
            # 第四步:获取本线程绑定的predictor对象 
            predictor = self.pool.retrive(idx)
    
            # 第五步:开始预测,并获得预测结果
            try:
                input_names = predictor.get_input_names() # 获得输入参数名称,即'x',在静态图构建过程中使用InputSpec指定的
                input_tensor = predictor.get_input_handle(input_names[0])
                input_tensor.copy_from_cpu(req) # 将数据从内存中拷贝到GPU(因为本例子使用了gpu做预测)中
                predictor.run()
                output_names = predictor.get_output_names()
                output_tensor = predictor.get_output_handle(output_names[0])
                resp = output_tensor.copy_to_cpu() # 将数据从GPU读取到内存中进行处理。
                return str(resp.argmax())
            finally:
                predictor.clear_intermediate_tensor() # 释放中间计算产生的Tensor
                predictor.try_shrink_memory() # 释放显存
    

    相关文章

      网友评论

          本文标题:Paddle训练之后的镜像-动态图转静态图,并使用inferen

          本文链接:https://www.haomeiwen.com/subject/hgaiurtx.html