AsymmNet源于德、中三方团队思路,通过调整卷积计算量分配提升性能,在特定区间效果显著。文中介绍了数据集处理、模型开发与训练等,显示其训练及收敛快,性能优。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜


论文地址:https://arxiv.org/pdf/2104.07770.pdf
我们将网上获取的数据集以压缩包的方式上传到aistudio数据集中,并加载到我们的项目内。
在使用之前我们进行数据集压缩包的一个解压。
In [ ]!unzip -oq /home/aistudio/data/data69664/Images.zip -d work/datasetIn [ ]
import paddleimport numpy as npfrom typing import Callable#参数配置config_parameters = { "class_dim": 16, #分类数
"target_path":"/home/aistudio/work/",
'train_image_dir': '/home/aistudio/work/trainImages', 'eval_image_dir': '/home/aistudio/work/evalImages', 'epochs':100, 'batch_size': 32, 'lr': 0.01}
接下来我们使用标注好的文件进行数据集类的定义,方便后续模型训练使用。
In [ ]import osimport shutil
train_dir = config_parameters['train_image_dir']
eval_dir = config_parameters['eval_image_dir']
paths = os.listdir('work/dataset/Images')if not os.path.exists(train_dir):
os.mkdir(train_dir)if not os.path.exists(eval_dir):
os.mkdir(eval_dir)for path in paths:
imgs_dir = os.listdir(os.path.join('work/dataset/Images', path))
target_train_dir = os.path.join(train_dir,path)
target_eval_dir = os.path.join(eval_dir,path) if not os.path.exists(target_train_dir):
os.mkdir(target_train_dir) if not os.path.exists(target_eval_dir):
os.mkdir(target_eval_dir) for i in range(len(imgs_dir)): if ' ' in imgs_dir[i]:
new_name = imgs_dir[i].replace(' ', '_') else:
new_name = imgs_dir[i]
target_train_path = os.path.join(target_train_dir, new_name)
target_eval_path = os.path.join(target_eval_dir, new_name)
if i % 5 == 0:
shutil.copyfile(os.path.join(os.path.join('work/dataset/Images', path), imgs_dir[i]), target_eval_path) else:
shutil.copyfile(os.path.join(os.path.join('work/dataset/Images', path), imgs_dir[i]), target_train_path)print('finished train val split!')finished train val split!
我们先看一下解压缩后的数据集长成什么样子,对比分析经典模型在Caltech101抽取16类mini版数据集上的效果
In [ ]import osimport randomfrom matplotlib import pyplot as pltfrom PIL import Image
imgs = []
paths = os.listdir('work/dataset/Images')for path in paths:
img_path = os.path.join('work/dataset/Images', path) if os.path.isdir(img_path):
img_paths = os.listdir(img_path)
img = Image.open(os.path.join(img_path, random.choice(img_paths)))
imgs.append((img, path))
f, ax = plt.subplots(4, 4, figsize=(12,12))for i, img in enumerate(imgs[:16]):
ax[i//4, i%4].imshow(img[0])
ax[i//4, i%4].axis('off')
ax[i//4, i%4].set_title('label: %s' % img[1])
plt.show()<Figure size 864x864 with 16 Axes>
#数据集的定义class Dataset(paddle.io.Dataset):
"""
步骤一:继承paddle.io.Dataset类
"""
def __init__(self, transforms: Callable, mode: str ='train'):
"""
步骤二:实现构造函数,定义数据读取方式
"""
super(Dataset, self).__init__()
self.mode = mode
self.transforms = transforms
train_image_dir = config_parameters['train_image_dir']
eval_image_dir = config_parameters['eval_image_dir']
train_data_folder = paddle.vision.DatasetFolder(train_image_dir)
eval_data_folder = paddle.vision.DatasetFolder(eval_image_dir)
if self.mode == 'train':
self.data = train_data_folder elif self.mode == 'eval':
self.data = eval_data_folder def __getitem__(self, index):
"""
步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
"""
data = np.array(self.data[index][0]).astype('float32')
data = self.transforms(data)
label = np.array([self.data[index][1]]).astype('int64')
return data, label
def __len__(self):
"""
步骤四:实现__len__方法,返回数据集总数目
"""
return len(self.data)
In [ ]
from paddle.vision import transforms as T#数据增强transform_train =T.Compose([T.Resize((256,256)), #T.RandomVerticalFlip(10),
#T.RandomHorizontalFlip(10),
T.RandomRotation(10),
T.Transpose(),
T.Normalize(mean=[0, 0, 0], # 像素值归一化
std =[255, 255, 255]), # transforms.ToTensor(), # transpose操作 + (img / 255),并且数据结构变为PaddleTensor
T.Normalize(mean=[0.50950350, 0.54632660, 0.57409690],# 减均值 除标准差
std= [0.26059777, 0.26041326, 0.29220656])# 计算过程:output[channel] = (input[channel] - mean[channel]) / std[channel]
])
transform_eval =T.Compose([ T.Resize((256,256)),
T.Transpose(),
T.Normalize(mean=[0, 0, 0], # 像素值归一化
std =[255, 255, 255]), # transforms.ToTensor(), # transpose操作 + (img / 255),并且数据结构变为PaddleTensor
T.Normalize(mean=[0.50950350, 0.54632660, 0.57409690],# 减均值 除标准差
std= [0.26059777, 0.26041326, 0.29220656])# 计算过程:output[channel] = (input[channel] - mean[channel]) / std[channel]
])
根据所使用的数据集需求实例化数据集类,并查看总样本量。
简小派
简小派是一款AI原生求职工具,通过简历优化、岗位匹配、项目生成、模拟面试与智能投递,全链路提升求职成功率,帮助普通人更快拿到更好的 offer。
123
查看详情
In [ ]
train_dataset =Dataset(mode='train',transforms=transform_train)
eval_dataset =Dataset(mode='eval', transforms=transform_eval )#数据异步加载train_loader = paddle.io.DataLoader(train_dataset,
places=paddle.CUDAPlace(0),
batch_size=32,
shuffle=True, #num_workers=2,
#use_shared_memory=True
)
eval_loader = paddle.io.DataLoader (eval_dataset,
places=paddle.CUDAPlace(0),
batch_size=32, #num_workers=2,
#use_shared_memory=True
)print('训练集样本量: {},验证集样本量: {}'.format(len(train_loader), len(eval_loader)))训练集样本量: 45,验证集样本量: 12
本次我们选取了经典的卷积神经网络resnet50,vgg19,mobilenet_v2来进行实验比较。
In [ ]network = paddle.vision.models.mobilenet_v2(num_classes=16)#模型封装model = paddle.Model(network)#模型可视化model.summary((-1, 3,256 , 256))
#优化器选择class S*eBestModel(paddle.callbacks.Callback):
def __init__(self, target=0.5, path='work/best_model', verbose=0):
self.target = target
self.epoch = None
self.path = path def on_epoch_end(self, epoch, logs=None):
self.epoch = epoch def on_eval_end(self, logs=None):
if logs.get('acc') > self.target:
self.target = logs.get('acc')
self.model.s*e(self.path) print('best acc is {} at epoch {}'.format(self.target, self.epoch))
callback_visualdl = paddle.callbacks.VisualDL(log_dir='work/vgg19')
callback_s*ebestmodel = S*eBestModel(target=0.5, path='work/best_model')
callbacks = [callback_visualdl, callback_s*ebestmodel]
base_lr = config_parameters['lr']
epochs = config_parameters['epochs']def make_optimizer(parameters=None):
momentum = 0.9
learning_rate= paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=base_lr, T_max=epochs, verbose=False)
weight_decay=paddle.regularizer.L2Decay(0.0001)
optimizer = paddle.optimizer.Momentum(
learning_rate=learning_rate,
momentum=momentum,
weight_decay=weight_decay,
parameters=parameters) return optimizer
optimizer = make_optimizer(model.parameters())
model.prepare(optimizer,
paddle.nn.CrossEntropyLoss(),
paddle.metric.Accuracy())
model.fit(train_loader,
eval_loader,
epochs=100,
batch_size=1, # 是否打乱样本集
callbacks=callbacks,
verbose=1) # 日志展示格式
在总结了以前的工作后,作者认为要实现更节约资源的设计,feature reuse是有效的操作。

图1 Asymmetrical bottlenecks模块细节示意图
In [ ]__all__ = ['AsymmNet_Large', 'AsymmNet_Small', 'AsymmNet']import paddleimport paddle.nn as nnimport mathimport paddle.nn.functional as Fclass HardSigmoid(nn.Layer):
def __init__(self):
super(HardSigmoid, self).__init__()
self.relu = nn.ReLU6() def forward(self, x):
return self.relu(x + 3) / 6class HardSwish(nn.Layer):
def __init__(self):
super(HardSwish, self).__init__()
self.sigmoid = HardSigmoid() def forward(self, x):
return x * self.sigmoid(x)class Activation(nn.Layer):
def __init__(self, act_func):
super(Activation, self).__init__() if act_func == "relu":
self.act = nn.ReLU() elif act_func == "ReLU6":
self.act = nn.ReLU6() elif act_func == "hard_sigmoid":
self.act = HardSigmoid() elif act_func == "hard_swish":
self.act = HardSwish() else: raise NotImplementedError def forward(self, x):
return self.act(x)def make_divisible(x, divisible_by=8):
return int(math.ceil(x * 1. / divisible_by) * divisible_by)class _BasicUnit(nn.Layer):
def __init__(self, num_in, num_out, kernel_size=1, strides=1, pad=0, num_groups=1,
use_act=True, act_type="relu", norm_layer=nn.BatchNorm2D):
super(_BasicUnit, self).__init__()
self.use_act = use_act
self.conv = nn.Conv2D(in_channels=num_in, out_channels=num_out,
kernel_size=kernel_size, stride=strides,
padding=pad, groups=num_groups, bias_attr=False,
)
self.bn = norm_layer(num_out) if use_act is True:
self.act = Activation(act_type) def forward(self, x):
out = self.conv(x)
out = self.bn(out) if self.use_act:
out = self.act(out) return outclass SE_Module(nn.Layer):
def __init__(self, channels, reduction=4):
super(SE_Module, self).__init__()
self.Avg = nn.AdaptiveAvgPool2D(1)
reduction_c = make_divisible(channels // reduction)
self.out = nn.Sequential(
nn.Conv2D(channels, reduction_c, 1, bias_attr=True),
nn.ReLU(),
nn.Conv2D(reduction_c, channels, 1, bias_attr=True),
HardSigmoid()
) def forward(self, x):
y = self.Avg(x)
y = self.out(y) return x * yclass AsymmBottleneck(nn.Layer):
def __init__(self, num_in, num_mid, num_out, kernel_size, asymmrate=1,
act_type="relu", use_se=False, strides=1,
norm_layer=nn.BatchNorm2D):
super(AsymmBottleneck, self).__init__() assert isinstance(asymmrate, int)
self.asymmrate = asymmrate
self.use_se = use_se
self.use_short_cut_conv = (num_in == num_out and strides == 1)
self.do_expand = (num_mid > max(num_in, asymmrate * num_in)) if self.do_expand:
self.expand = _BasicUnit(num_in, num_mid - asymmrate * num_in,
kernel_size=1,
strides=1, pad=0, act_type=act_type,
norm_layer=norm_layer)
num_mid += asymmrate * num_in
self.dw_conv = _BasicUnit(num_mid, num_mid, kernel_size, strides,
pad=self._get_pad(kernel_size), act_type=act_type,
num_groups=num_mid, norm_layer=norm_layer) if self.use_se:
self.se = SE_Module(num_mid)
self.pw_conv_linear = _BasicUnit(num_mid, num_out, kernel_size=
1, strides=1,
pad=0, act_type=act_type, use_act=False,
norm_layer=norm_layer, num_groups=1) def forward(self, x):
if self.do_expand:
out = self.expand(x)
feat = [] for i in range(self.asymmrate):
feat.append(x)
feat.append(out) for i in range(self.asymmrate):
feat.append(x) if self.asymmrate > 0:
out = paddle.concat(feat, axis=1) else:
out = x
out = self.dw_conv(out) if self.use_se:
out = self.se(out)
out = self.pw_conv_linear(out) if self.use_short_cut_conv: return x + out return out def _get_pad(self, kernel_size):
if kernel_size == 1: return 0
elif kernel_size == 3: return 1
elif kernel_size == 5: return 2
elif kernel_size == 7: return 3
else: raise NotImplementedErrordef get_asymmnet_cfgs(model_name):
if model_name == 'asymmnet_large':
inplanes = 16
cfg = [ # k, exp, c, se, nl, s,
# stage1
[3, 16, 16, False, 'relu', 1], # stage2
[3, 64, 24, False, 'relu', 2],
[3, 72, 24, False, 'relu', 1], # stage3
[5, 72, 40, True, 'relu', 2],
[5, 120, 40, True, 'relu', 1],
[5, 120, 40, True, 'relu', 1], # stage4
[3, 240, 80, False, 'hard_swish', 2],
[3, 200, 80, False, 'hard_swish', 1],
[3, 184, 80, False, 'hard_swish', 1],
[3, 184, 80, False, 'hard_swish', 1],
[3, 480, 112, True, 'hard_swish', 1],
[3, 672, 112, True, 'hard_swish', 1], # stage5
[5, 672, 160, True, 'hard_swish', 2],
[5, 960, 160, True, 'hard_swish', 1],
[5, 960, 160, True, 'hard_swish', 1],
]
cls_ch_squeeze = 960
cls_ch_expand = 1280
elif model_name == 'asymmnet_small':
inplanes = 16
cfg = [ # k, exp, c, se, nl, s,
[3, 16, 16, True, 'relu', 2],
[3, 72, 24, False, 'relu', 2],
[3, 88, 24, False, 'relu', 1],
[5, 96, 40, True, 'hard_swish', 2],
[5, 240, 40, True, 'hard_swish', 1],
[5, 240, 40, True, 'hard_swish', 1],
[5, 120, 48, True, 'hard_swish', 1],
[5, 144, 48, True, 'hard_swish', 1],
[5, 288, 96, True, 'hard_swish', 2],
[5, 576, 96, True, 'hard_swish', 1],
[5, 576, 96, True, 'hard_swish', 1],
]
cls_ch_squeeze = 576
cls_ch_expand = 1280
else: raise ValueError('{} model_name is not supported now!'.format(model_name)) return inplanes, cfg, cls_ch_squeeze, cls_ch_expandclass AsymmNet(nn.Layer):
def __init__(self, cfgs_name, num_classes=config_parameters['class_dim'], multiplier=1.0, asymmrate=1, dropout_rate=0.2,
norm_layer=nn.BatchNorm2D):
super(AsymmNet, self).__init__()
inplanes, cfg, cls_ch_squeeze, cls_ch_expand = get_asymmnet_cfgs(cfgs_name)
k = multiplier
self.inplanes = make_divisible(inplanes * k)
self.first_block = nn.Sequential(
nn.Conv2D(3, self.inplanes, 3, 2, 1, bias_attr=False),
nn.BatchNorm2D(self.inplanes),
HardSwish(),
)
asymm_layers = [] for layer_cfg in cfg:
layer = self._make_layer(kernel_size=layer_cfg[0],
exp_ch=make_divisible(k * layer_cfg[1]),
out_channel=make_divisible(k * layer_cfg[2]),
use_se=layer_cfg[3],
act_func=layer_cfg[4],
asymmrate=asymmrate,
stride=layer_cfg[5],
norm_layer=norm_layer,
)
asymm_layers.append(layer)
self.asymm_block = nn.Sequential(*asymm_layers)
self.last_block = nn.Sequential(
nn.Conv2D(self.inplanes, make_divisible(k * cls_ch_squeeze), 1, bias_attr=False),
nn.BatchNorm2D(make_divisible(k * cls_ch_squeeze)),
HardSwish(),
nn.AdaptiveAvgPool2D(1),
nn.Conv2D(make_divisible(k * cls_ch_squeeze), cls_ch_expand, 1, bias_attr=False),
HardSwish(),
nn.Dropout2D(p=dropout_rate),
nn.Flatten(),
)
self.output = nn.Linear(cls_ch_expand, num_classes) def _make_layer(self, kernel_size, exp_ch, out_channel, use_se, act_func, asymmrate, stride,
norm_layer):
mid_planes = exp_ch
out_planes = out_channel
layer = AsymmBottleneck(self.inplanes, mid_planes,
out_planes, kernel_size, asymmrate,
act_func, strides=stride, use_se=use_se, norm_layer=norm_layer)
self.inplanes = out_planes return layer def forward(self, x):
x = self.first_block(x)
x = self.asymm_block(x)
x = self.last_block(x)
x = self.output(x) return xclass AsymmNet_Large(AsymmNet):
def __init__(self, **kwargs):
super(AsymmNet_Large, self).__init__(cfgs_name='asymmnet_large', **kwargs)class AsymmNet_Small(AsymmNet):
def __init__(self, **kwargs):
super(AsymmNet_Small, self).__init__(cfgs_name='asymmnet_small', **kwargs)if __name__ == '__main__':
img = paddle.rand((1, 3, 256, 256))
vit = AsymmNet_Large()
out = vit(img) print(out.shape)[1, 16]
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:641: UserWarning: When training, we now always track global mean and variance. "When training, we now always track global mean and variance.")
model = AsymmNet_Large() model = paddle.Model(model) model.summary((1,3,256,256))In [ ]
#优化器选择class S*eBestModel(paddle.callbacks.Callback):
def __init__(self, target=0.5, path='work/best_model', verbose=0):
self.target = target
self.epoch = None
self.path = path def on_epoch_end(self, epoch, logs=None):
self.epoch = epoch def on_eval_end(self, logs=None):
if logs.get('acc') > self.target:
self.target = logs.get('acc')
self.model.s*e(self.path) print('best acc is {} at epoch {}'.format(self.target, self.epoch))
callback_visualdl = paddle.callbacks.VisualDL(log_dir='work/AsymmNet_Net')
callback_s*ebestmodel = S*eBestModel(target=0.5, path='work/best_model')
callbacks = [callback_visualdl, callback_s*ebestmodel]
base_lr = config_parameters['lr']
epochs = config_parameters['epochs']def make_optimizer(parameters=None):
momentum = 0.9
learning_rate= paddle.optimizer.lr.CosineAnnealingDecay(learning_rate=base_lr, T_max=epochs, verbose=False)
weight_decay=paddle.regularizer.L2Decay(0.0002)
optimizer = paddle.optimizer.Momentum(
learning_rate=learning_rate,
momentum=momentum,
weight_decay=weight_decay,
parameters=parameters) return optimizer
optimizer = make_optimizer(model.parameters())
In [ ]
model.prepare(optimizer,
paddle.nn.CrossEntropyLoss(),
paddle.metric.Accuracy())
In [32]
model.fit(train_loader,
eval_loader,
epochs=100,
batch_size=1, # 是否打乱样本集
callbacks=callbacks,
verbose=1) # 日志展示格式
AsymmNet模型训练速度很快,模型收敛的速度也非常快,性能有了大幅度的提升。

以上就是AsymmNet :使用非对称瓶颈实现的超轻量卷积神经网络!的详细内容,更多请关注其它相关文章!
# ai
# 网络视频营销推广案例
# 加载
# 第二个
# 数据结构
# 把它
# 是在
# 第一个
# 一言
# 非对称
# 超轻
# type
# python
# 异步加载
# cos
# red
# igs
# asic
# udio
# latte
# fig
# 中文网
# 平价购物搜索关键词排名
# seo专业广告
# 黄岛网站建设公司首选
# 温州网站优化和推广公司
# 邢台做网站推广的公司
# 天心区网店营销推广中心
# 山东网站seo优化哪家便宜
# 阿迪达斯网站推广
# 免费网站建设方案报价
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
发布最新版本的 PICO OS 5.7.0:支持VR头盔录屏并跨平台分享至微信
MiracleVision视觉大模型
华为AI大模型将融入HarmonyOS 4
组建团队,字节跳动要造机器人?
复旦发布「新闻推荐生态系统模拟器」SimuLine:单机支持万名读者、千名创作者、100+轮次推荐
Meta Quest订阅服务每月7.99美元畅玩两款VR游戏应用
专家解读国家网信办深度合成服务算法备案信息公告:不等于百度、阿里、腾讯等生成式AI产品获批
北京市通用人工智能产业创新伙伴计划名单公布,京东科技入选“算力伙伴”
这款在《自然通讯》发表的机器人,为变形金刚来到现实创造可能性
此「错」并非真的错:从四篇经典论文入手,理解Transformer架构图「错」在何处
DragGAN开源三天Star量23k,这又来一个DragDiffusion
金山办公:AI是重要的产品战略之一
无需标注数据,「3D理解」进入多模态预训练时代!ULIP系列全面开源,刷新SOTA
J*a与人工智能结合:构建智能云服务
利用AI技术更好地发展农村电商
首家承认ChatGPT影响其收入的公司Chegg选择拥抱AI ,裁减4%员工
联想举办2025创新开放日,展出260余项算力及AI产品技术
报告称 70% 程序员已使用各种 AI 工具编程
如何用AI重塑你的工作流(一)
常见的五个人工智能误解
人工智能助力林草行业高质量发展
科技数码圈的新物种 乐天派桌面机器人 AI +安卓+机器人 首发价1799元
如何用Transformer BEV克服自动驾驶的极端情况?
360发布认知型通用大模型“360智脑4.0” 全面接入360全家桶
消息称苹果 iPhone 15 系列健康应用将深度融合 AI 技术
联想创投携手12家被投企业MWC展示元宇宙、机器人等技术
MIT开发“PhotoGuard”技术保护图像免遭恶意AI编辑
【|直播|预告】人工智能高峰论坛将于7月2日13:30准时开播!
Bing Chat 和 Bing Search 正式引入深色模式
AI绘画,还需要懂数学?
Meta 人工智能业务落后竞争对手,研究人员大量离职成重要原因
郭帆谈ChatGPT:电影行业需要创新,否则人工智能将让电影变得平庸
国宝级文物“铜兽驮跪坐人顶尊铜像”完成模拟拼接,腾讯AI立功
联合国秘书长称支持建立全球人工智能监管机构
无人机巡检方案是什么,该如何选择适合的巡检方案
七大主流AI企业包括OpenAI、谷歌等联合承诺:引入水印技术,并允许第三方审核AI内容
《流浪地球2》里机器人公司的创始人:未来10年,机器人的崛起!
技术如何使人变得懒惰?
优化J*a与MySQL合作:分享批处理操作的技巧
昇腾AI大模型训推一体化解决方案将在WAIC发布
特斯拉人形机器人将于 7 月亮相上海 2025 世界人工智能大会
网易云音乐内测上线“私人DJ” 打造AI推荐音乐助手
探展WAIC | 第四范式“式说”聚焦toB大模型,布局生成式AI重构企业软件
厂商陆续公布AI进展 完美世界游戏展示复合应用AI in GamePlay
定义人工智能的十个关键术语
时间、空间可控的视频生成走进现实,阿里大模型新作VideoComposer火了
干货满满,2025昆山元宇宙国际装备展等你来打卡!
揭秘AI数字人语录:抖音AI小和尚、老者语录能赚钱吗?
企业软件行业更将被AI全面重构!Moka李国兴:未来优秀组织和个人将一定是善于使用AI生产力的
360°/180°双模式,佳能公布可折叠小体积的VR全景相机
2025-07-18
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。