Skip to content

  • 体验新版
    • 正在加载...
  • 登录
  • PaddlePaddle
  • Paddle
  • Issue
  • #16943

P
Paddle
  • 项目概览

PaddlePaddle / Paddle
大约 2 年 前同步成功

通知 2325
Star 20933
Fork 5424
  • 代码
    • 文件
    • 提交
    • 分支
    • Tags
    • 贡献者
    • 分支图
    • Diff
  • Issue 1423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
  • Wiki 0
    • Wiki
  • 分析
    • 仓库
    • DevOps
  • 项目成员
  • Pages
P
Paddle
  • 项目概览
    • 项目概览
    • 详情
    • 发布
  • 仓库
    • 仓库
    • 文件
    • 提交
    • 分支
    • 标签
    • 贡献者
    • 分支图
    • 比较
  • Issue 1,423
    • Issue 1,423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
    • 合并请求 543
  • Pages
  • 分析
    • 分析
    • 仓库分析
    • DevOps
  • Wiki 0
    • Wiki
  • 成员
    • 成员
  • 收起侧边栏
  • 动态
  • 分支图
  • 创建新Issue
  • 提交
  • Issue看板
已关闭
开放中
Opened 4月 17, 2019 by saxon_zh@saxon_zhGuest

fluid.io.save_persistables 保存中间结果后读取出来重新存为fluid.io.save_inference_model 参数大小不对

Created by: xiangyubo

  • 版本、环境信息:    1)PaddlePaddle版本:1.3.2 训练    3)GPU:v100训练 4)系统环境:windows7, python 3.5.0,Paddle 1.3.0 加载并转成预测

使用1.3.2的 paddle 训练,然后使用 save_persistables 保存成单文件。之后希望读取中间结果,保存成一个预测模型。在 windows 机器上,paddle 1.3.0 版本,用 save_inference_model 保存,不指定模型名字。 保存之后,发现参数的大小可能不对。我第一个卷积层的参数是 3x3x3x16,共432个浮点数,应该占用1728字节。但是保存下来之后只有1049个字节。 后来尝试切换到1.3.2 的 paddle 版本做中间结果转换,依然大小不对。

转存代码

-- coding: UTF-8 --

""" 将训练完成的YOLOv3模型固化 """ from future import absolute_import from future import division from future import print_function import paddle.fluid as fluid from paddle.fluid.initializer import MSRA from paddle.fluid.param_attr import ParamAttr from paddle.fluid.regularizer import L2Decay

target_size = [3, 256, 256] nms_threshold = 0.45 confs_threshold = 0.5 path = "./yolo-model" class_dim = 21 anchors = [10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319] anchor_mask = [[3, 4, 5], [0, 1, 2]]

class YOLOv3Tiny(object): def init(self, class_num, anchors, anchor_mask): self.outputs = [] self.downsample_ratio = 1 self.anchor_mask = anchor_mask self.anchors = anchors self.class_num = class_num

    self.yolo_anchors = []
    self.yolo_classes = []
    for mask_pair in self.anchor_mask:
        mask_anchors = []
        for mask in mask_pair:
            mask_anchors.append(self.anchors[2 * mask])
            mask_anchors.append(self.anchors[2 * mask + 1])
        self.yolo_anchors.append(mask_anchors)
        self.yolo_classes.append(class_num)

def name(self):
    return 'YOLOv3-tiny'

def get_downsample_ratio(self):
    return self.downsample_ratio

def get_yolo_anchors(self):
    return self.yolo_anchors

def get_yolo_classes(self):
    return self.yolo_classes

def conv_bn(self,
            input,
            num_filters,
            filter_size,
            stride,
            padding,
            num_groups=1,
            act='relu',
            use_cudnn=True):
    conv = fluid.layers.conv2d(
        input=input,
        num_filters=num_filters,
        filter_size=filter_size,
        stride=stride,
        padding=padding,
        act=None,
        groups=num_groups,
        use_cudnn=use_cudnn,
        param_attr=ParamAttr(initializer=fluid.initializer.Normal(0., 0.02)),
        bias_attr=False)

    # batch_norm中的参数不需要参与正则化,所以主动使用正则系数为0的正则项屏蔽掉
    out = fluid.layers.batch_norm(
        input=conv, act=act, 
        param_attr=ParamAttr(initializer=fluid.initializer.Normal(0., 0.02), regularizer=L2Decay(0.)),
        bias_attr=ParamAttr(initializer=fluid.initializer.Constant(0.0), regularizer=L2Decay(0.)))

    return out

def depthwise_conv_bn(self, input, filter_size=3, stride=1, padding=1):
    num_filters = input.shape[1]
    return self.conv_bn(input, 
            num_filters=num_filters, 
            filter_size=filter_size, 
            stride=stride, 
            padding=padding, 
            num_groups=num_filters)

def downsample(self, input, pool_size=2, pool_stride=2):
    self.downsample_ratio *= 2
    return fluid.layers.pool2d(input=input, pool_type='max', pool_size=pool_size,
                                pool_stride=pool_stride)

def basicblock(self, input, num_filters):
    conv1 = self.conv_bn(input, num_filters, filter_size=3, stride=1, padding=1)
    out = self.downsample(conv1)
    return out


def upsample(self, input, scale=2):
    # get dynamic upsample output shape
    shape_nchw = fluid.layers.shape(input)
    shape_hw = fluid.layers.slice(shape_nchw, axes=[0], starts=[2], ends=[4])
    shape_hw.stop_gradient = True
    in_shape = fluid.layers.cast(shape_hw, dtype='int32')
    out_shape = in_shape * scale
    out_shape.stop_gradient = True

    # reisze by actual_shape
    out = fluid.layers.resize_nearest(
        input=input,
        scale=scale,
        actual_shape=out_shape)
    return out

def yolo_detection_block(self, input, num_filters):
    route = self.conv_bn(input, num_filters, filter_size=1, stride=1, padding=0)
    tip = self.conv_bn(route, num_filters * 2, filter_size=3, stride=1, padding=1)
    return route, tip

def net(self, img): 
    # darknet-tiny
    stages = [16, 32, 64, 128, 256, 512]
    assert len(self.anchor_mask) <= len(stages), "anchor masks can't bigger than downsample times"
    # 256x256
    downsample_ = self.basicblock(img, stages[0])
    blocks = []

    for i, stage_count in enumerate(stages):
        if i == 0:
            continue
        if i == len(stages) - 1:
            block = self.conv_bn(downsample_, stage_count, filter_size=3, stride=1, padding=1)
            blocks.append(block)
            block = self.depthwise_conv_bn(blocks[-1])
            block = self.depthwise_conv_bn(blocks[-1])
            block = self.conv_bn(blocks[-1], stage_count * 2, filter_size=1, stride=1, padding=0)
            blocks.append(block)
        else:
            downsample_ = self.basicblock(downsample_, stage_count)
            blocks.append(downsample_)
    
    blocks = blocks[-1:-5:-3]   # 取倒数两层,并且逆序,后面跨层级联需要

    # yolo detector
    for i, block in enumerate(blocks):
        # yolo 中跨视域链接
        if i > 0:
            block = fluid.layers.concat(input=[route, block], axis=1)
        if i < 1:
            route, tip = self.yolo_detection_block(block, num_filters=256 // (2**i))
        else:
            tip = self.conv_bn(block, num_filters=256, filter_size=3, stride=1, padding=1)
        block_out = fluid.layers.conv2d(
            input=tip,
            num_filters=len(self.anchor_mask[i]) * (self.class_num + 5),      # 5 elements represent x|y|h|w|score
            filter_size=1,
            stride=1,
            padding=0,
            act=None,
            param_attr=ParamAttr(initializer=fluid.initializer.Normal(0., 0.02)),
            bias_attr=ParamAttr(initializer=fluid.initializer.Constant(0.0), regularizer=L2Decay(0.)))
        self.outputs.append(block_out)
        # 为了跨视域链接,差值方式提升特征图尺寸
        if i < len(blocks) - 1:
            route = self.conv_bn(route, 128 // (2**i), filter_size=1, stride=1, padding=0)
            route = self.upsample(route)

    return self.outputs

def freeze_model():

exe = fluid.Executor(fluid.CPUPlace())
image = fluid.layers.data(name='image', shape=target_size, dtype='float32')
model = YOLOv3Tiny(class_dim, anchors, anchor_mask)
pred = model.net(image)

freeze_program = fluid.default_main_program()
fluid.io.load_persistables(exe, '.', freeze_program, 'yolo-v3-tiny')
freeze_program = freeze_program.clone(for_test=True)

fluid.io.save_inference_model(path, ['image'], pred, exe, freeze_program)

if name == 'main': freeze_model()

指派人
分配到
无
里程碑
无
分配里程碑
工时统计
无
截止日期
无
标识: paddlepaddle/Paddle#16943
渝ICP备2023009037号

京公网安备11010502055752号

网络110报警服务 Powered by GitLab CE v13.7
开源知识
Git 入门 Pro Git 电子书 在线学 Git
Markdown 基础入门 IT 技术知识开源图谱
帮助
使用手册 反馈建议 博客
《GitCode 隐私声明》 《GitCode 服务条款》 关于GitCode
Powered by GitLab CE v13.7