模型复现:ReXNet

P粉084495128
发布: 2025-07-29 10:02:24
原创
805人浏览过
本文复现了ReXNet模型,这是一款参数量小、精度高的新BackBone。介绍了其针对深度网络表达瓶颈问题提出的设计准则,还展示了模型搭建的基础模块(如ConvBN、Swish等)、主体结构及预设模型,并进行了模型验证,在ImageNet验证集上取得相应精度。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

模型复现:rexnet - php中文网

可图大模型
可图大模型

可图大模型(Kolors)是快手大模型团队自研打造的文生图AI大模型

可图大模型 32
查看详情 可图大模型

引入

  • 闲得无事,我又来复现模型了
  • 这次的目标又是一个新鲜出炉的新模型 ReXNet
  • 总体看上去就是一个很不错的新 BackBone,参数量比较小,但是精度却相当高

模型介绍

  • 相关资料:
    • 介绍文章:【ReXNet|消除表达瓶颈,提升性能指标】
    • 论文:【ReXNet: Diminishing Representational Bottleneck on Convolutional Neural Network】
    • 官方代码:【clovaai/rexnet】
  • 论文摘要:
    • 针对深度网络中存在的表达瓶颈问题,该文提出了一组用于提升模型性能的设计准则。
    • 作者认为:传统的网络架构设计范式会产生表达瓶颈问题,进而影响模型的性能。
    • 为研究表达瓶颈问题,作者研究了上万随机网络生成的特征的matric rank,同时进一步研究了网络的层通道配置方案。
    • 基于前述研究发现,作者提出了一组简单而有效的设计原则消除表达瓶颈问题。
    • 在基准网络上采用上述设计原则进行轻微调整即可取得ImageNet上的性能显著提升;
    • 此外,COCO目标检测与迁移学习的实验更进一步验证了所提方案的有效性:消除表达瓶颈问题有助于提升模型性能。

快速使用

  • 推荐使用 【Paddle-Image-Models】 项目来快速加载本模型
  • 具体使用方法请参考:【【Paddle-Image-Models】飞桨预训练图像模型库】

模型搭建

导入必要的包

In [1]
import paddleimport paddle.nn as nnfrom math import ceil
登录后复制
   

基础模块

  • 包含 ConvBN、Swish 和 SE 模块
In [2]
def ConvBN(out, in_channels, channels, kernel=1, stride=1, pad=0, num_group=1, act=None):
    out.append(nn.Conv2D(in_channels, channels, kernel,
                         stride, pad, groups=num_group, bias_attr=False))
    out.append(nn.BatchNorm2D(channels))    if act == 'swish':
        out.append(Swish())    elif act == 'relu':
        out.append(nn.ReLU())    elif act == 'relu6':
        out.append(nn.ReLU6())class Swish(nn.Layer):
    def __init__(self):
        super(Swish, self).__init__()    def forward(self, x):
        return x * nn.functional.sigmoid(x)class SE(nn.Layer):
    def __init__(self, in_channels, channels, se_ratio=12):
        super(SE, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2D(1)
        self.fc = nn.Sequential(
            nn.Conv2D(in_channels, channels // se_ratio,
                      kernel_size=1, padding=0),
            nn.BatchNorm2D(channels // se_ratio),
            nn.ReLU(),
            nn.Conv2D(channels // se_ratio, channels,
                      kernel_size=1, padding=0),
            nn.Sigmoid()
        )    def forward(self, x):
        y = self.avg_pool(x)
        y = self.fc(y)        return x * y
登录后复制
   

LinearBottleneck

In [3]
class LinearBottleneck(nn.Layer):
    def __init__(self, in_channels, channels, t, stride, use_se=True, se_ratio=12):
        super(LinearBottleneck, self).__init__()
        self.use_shortcut = stride == 1 and in_channels <= channels
        self.in_channels = in_channels
        self.out_channels = channels

        out = []        if t != 1:
            dw_channels = in_channels * t
            ConvBN(out, in_channels=in_channels,
                   channels=dw_channels, act='swish')        else:
            dw_channels = in_channels

        ConvBN(out, in_channels=dw_channels, channels=dw_channels, kernel=3, stride=stride, pad=1,
               num_group=dw_channels)        if use_se:
            out.append(SE(dw_channels, dw_channels, se_ratio))

        out.append(nn.ReLU6())
        ConvBN(out, in_channels=dw_channels, channels=channels)
        self.out = nn.Sequential(*out)    def forward(self, x):
        out = self.out(x)        if self.use_shortcut:
            out[:, 0:self.in_channels] += x        return out
登录后复制
   

ReXNet

  • 模型主体
In [4]
class ReXNetV1(nn.Layer):
    def __init__(self, input_ch=16, final_ch=180, width_mult=1.0, depth_mult=1.0,
                 class_dim=1000, use_se=True, se_ratio=12, dropout_ratio=0.2):
        super(ReXNetV1, self).__init__()

        layers = [1, 2, 2, 3, 3, 5]
        strides = [1, 2, 2, 2, 1, 2]
        use_ses = [False, False, True, True, True, True]

        layers = [ceil(element * depth_mult) for element in layers]
        strides = sum([[element] + [1] * (layers[idx] - 1)                       for idx, element in enumerate(strides)], [])        if use_se:
            use_ses = sum([[element] * layers[idx]                           for idx, element in enumerate(use_ses)], [])        else:
            use_ses = [False] * sum(layers[:])
        ts = [1] * layers[0] + [6] * sum(layers[1:])

        self.depth = sum(layers[:]) * 3
        stem_channel = 32 / width_mult if width_mult < 1.0 else 32
        inplanes = input_ch / width_mult if width_mult < 1.0 else input_ch

        features = []
        in_channels_group = []
        channels_group = []        # The following channel configuration is a simple instance to make each layer become an expand layer.
        for i in range(self.depth // 3):            if i == 0:
                in_channels_group.append(int(round(stem_channel * width_mult)))
                channels_group.append(int(round(inplanes * width_mult)))            else:
                in_channels_group.append(int(round(inplanes * width_mult)))
                inplanes += final_ch / (self.depth // 3 * 1.0)
                channels_group.append(int(round(inplanes * width_mult)))

        ConvBN(features, 3, int(round(stem_channel * width_mult)),
               kernel=3, stride=2, pad=1, act='swish')        for block_idx, (in_c, c, t, s, se) in enumerate(zip(in_channels_group, channels_group, ts, strides, use_ses)):
            features.append(LinearBottleneck(in_channels=in_c,
                                             channels=c,
                                             t=t,
                                             stride=s,
                                             use_se=se, se_ratio=se_ratio))

        pen_channels = int(1280 * width_mult)
        ConvBN(features, c, pen_channels, act='swish')

        features.append(nn.AdaptiveAvgPool2D(1))
        self.features = nn.Sequential(*features)
        self.output = nn.Sequential(
            nn.Dropout(dropout_ratio),
            nn.Conv2D(pen_channels, class_dim, 1))    def forward(self, x):
        x = self.features(x)
        x = self.output(x).squeeze()        return x
登录后复制
   

预设模型

In [5]
def rexnet_100(pretrained=False, **kwargs):
    model = ReXNetV1(width_mult=1.0, **kwargs)    return modeldef rexnet_130(pretrained=False, **kwargs):
    model = ReXNetV1(width_mult=1.3, **kwargs)    return modeldef rexnet_150(pretrained=False, **kwargs):
    model = ReXNetV1(width_mult=1.5, **kwargs)    return modeldef rexnet_200(pretrained=False, **kwargs):
    model = ReXNetV1(width_mult=2.0, **kwargs)    return modeldef rexnet_300(pretrained=False, **kwargs):
    model = ReXNetV1(width_mult=3.0, **kwargs)    return model
登录后复制
   

模型验证

  • 加载转换后的官方预训练模型,使用 ImageNet 1k 验证集进行模型测试
  • 验证精度是否与官方标称一致

解压数据集

In [ ]
!mkdir ~/data/ILSVRC2012
!tar -xf ~/data/data68594/ILSVRC2012_img_val.tar -C ~/data/ILSVRC2012
登录后复制
   

构建数据集

  • 构建一个 ILSVRC2012 ImageNet 1k 的数据集
In [6]
import osimport paddleimport numpy as npfrom PIL import Imageclass ILSVRC2012(paddle.io.Dataset):
    def __init__(self, root, label_list, transform):
        self.transform = transform
        self.root = root
        self.label_list = label_list
        self.load_datas()    def load_datas(self):
        self.imgs = []
        self.labels = []        with open(self.label_list, 'r') as f:            for line in f:
                img, label = line[:-1].split(' ')
                self.imgs.append(os.path.join(self.root, img))
                self.labels.append(int(label))    def __getitem__(self, idx):
        label = self.labels[idx]
        image = self.imgs[idx]
        image = Image.open(image).convert('RGB')
        image = self.transform(image)        return image.astype('float32'), np.array(label).astype('int64')    def __len__(self):
        return len(self.imgs)
登录后复制
   

模型验证

  • ReXNet 的官方标称精度如下:

模型复现:ReXNet - php中文网        

In [7]
import paddle.vision.transforms as T

model = rexnet_100()
model.set_dict(paddle.load('data/data75438/rexnetv1_1.0x.pdparams'))
model = paddle.Model(model)
model.prepare(metrics=paddle.metric.Accuracy(topk=(1, 5)))

val_transforms = T.Compose([
    T.Resize(256, interpolation='bicubic'),
    T.CenterCrop(224),
    T.ToTensor(),
    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
val_dataset = ILSVRC2012('data/ILSVRC2012', transform=val_transforms, label_list='data/data68594/val_list.txt')

model.evaluate(val_dataset, batch_size=512)
登录后复制
       
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
登录后复制
       
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/utils.py:77: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  return (isinstance(seq, collections.Sequence) and
登录后复制
       
step 10/98 - acc_top1: 0.7811 - acc_top5: 0.9396 - 7s/step
step 20/98 - acc_top1: 0.7836 - acc_top5: 0.9396 - 7s/step
step 30/98 - acc_top1: 0.7813 - acc_top5: 0.9392 - 7s/step
step 40/98 - acc_top1: 0.7793 - acc_top5: 0.9383 - 7s/step
step 50/98 - acc_top1: 0.7792 - acc_top5: 0.9389 - 7s/step
step 60/98 - acc_top1: 0.7797 - acc_top5: 0.9386 - 7s/step
step 70/98 - acc_top1: 0.7785 - acc_top5: 0.9386 - 7s/step
step 80/98 - acc_top1: 0.7789 - acc_top5: 0.9385 - 7s/step
step 90/98 - acc_top1: 0.7786 - acc_top5: 0.9385 - 7s/step
step 98/98 - acc_top1: 0.7786 - acc_top5: 0.9387 - 6s/step
Eval samples: 50000
登录后复制
       
{'acc_top1': 0.77862, 'acc_top5': 0.93868}
登录后复制
               

以上就是模型复现:ReXNet的详细内容,更多请关注php中文网其它相关文章!

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号