从" 算力调度 "与" 激活函数 "两个正交的维度对卷积神经网络(CNN)做优化------用一个异构式 CPU+GPU 协同计算模型提升训练速度与性耗比,又提出一种新的 ReLU-Swish 激活函数,同时缓解 ReLU 的"神经元坏死"与 Swish 的"收敛慢、计算量大"两大痛点。
目录
[2.1 痛点一:训练越来越慢,单一设备"力不从心"](#2.1 痛点一:训练越来越慢,单一设备"力不从心")
[2.2 痛点二:激活函数"按下葫芦浮起瓢"](#2.2 痛点二:激活函数"按下葫芦浮起瓢")
[三、背景:TensorFlow 架构与优势](#三、背景:TensorFlow 架构与优势)
[四、贡献一:异构式 CPU+GPU 协同计算模型](#四、贡献一:异构式 CPU+GPU 协同计算模型)
[4.1 核心思想:让 CPU 和 GPU"各司其职"](#4.1 核心思想:让 CPU 和 GPU"各司其职")
[4.2 怎么落地:tf.device 设备放置 + 任务切割](#4.2 怎么落地:tf.device 设备放置 + 任务切割)
[4.3 结果:训练耗时明显下降](#4.3 结果:训练耗时明显下降)
[五、贡献二:ReLU-Swish 激活函数](#五、贡献二:ReLU-Swish 激活函数)
[5.1 激活函数全景回顾](#5.1 激活函数全景回顾)
[5.2 ReLU-Swish:各取一半的分段函数](#5.2 ReLU-Swish:各取一半的分段函数)
[6.1 收敛速度](#6.1 收敛速度)
[6.2 准确率](#6.2 准确率)
[6.3 谷歌 Swish vs ReLU 的参考数据(表 3 复现)](#6.3 谷歌 Swish vs ReLU 的参考数据(表 3 复现))
[6.4 小结](#6.4 小结)
[7.1 创新点](#7.1 创新点)
[7.2 不足与可商榷之处](#7.2 不足与可商榷之处)
[8.1 ReLU-Swish 与 HardSwish:2019 年的"不谋而合"](#8.1 ReLU-Swish 与 HardSwish:2019 年的"不谋而合")
[8.2 三行代码就能复现](#8.2 三行代码就能复现)
[8.3 对"CPU+GPU 异构"的现代反思](#8.3 对"CPU+GPU 异构"的现代反思)
这是一篇典型的" 应用型优化 "论文:它没有去发明全新的网络结构,而是抓住卷积神经网络训练中两个最"实打实"的痛点------ 算得慢 和 激活函数不够好用 ------分别给出一个工程上可直接落地的改进。这种"小切口、能落地"的思路,恰恰是我读下来最受启发的地方。
一、原文摘要
原文中文摘要 :针对卷积神经网络在性耗比上的不足,提出了异构式 CPU+GPU 的协同计算模型,在模型计算过程中使 CPU 负责逻辑性强的事物处理和串行计算,使 GPU 执行高
度线程化的并行处理任务。通过实验测试与单 GPU 训练、单 CPU 训练进行对比,结果表明异构式 CPU+GPU 计算模型在性耗比上更加优异。针对在卷积神经网络中 Swish 激活函数在反向传播求导误差梯度时涉及参数较多所导致的计算量较大、收敛速度慢,以及 ReLU 激活函数在 x 负区间内导数为零所导致的负梯度被置为零且神经元可能无法被激活的问题,提出了新的激活函数 ReLU-Swish。实验结果表明,ReLU-Swish 激活函数在收敛速度以及模型测试训练的准确率上对比 Swish 激活函数及 ReLU 激活函数有较明显的提高。
一句话拆解:全文其实就是两大贡献、两条主线------
- 算力线 :单 CPU 或单 GPU 训练复杂 CNN 时,总有一类设备在"闲着",性耗比低 → 提出异构式 CPU+GPU 协同计算模型。
- 算法线 :ReLU 会"杀死"神经元,Swish 精度好但"收敛慢、算得贵" → 提出ReLU-Swish 激活函数,把两者的优点各取一半拼起来。
二、为什么要做这项研究
作者在引言里点出两个"难言之隐",我认为这正是本文的价值起点。
2.1 痛点一:训练越来越慢,单一设备"力不从心"
随着深度学习的爆发,CNN 的层数、参数量、数据量都在膨胀,模型训练的难度和耗时呈指数级增长 。单 CPU 是串行计算,快不起来;单 GPU 虽然擅长并行,但在处理逻辑控制密集的任务时并不高效。更关键的是------当任务全压在某一类设备上时,另一类设备往往处于闲置状态,这是纯粹的算力浪费,直接拉低了"性耗比"(性能/功耗)。
2.2 痛点二:激活函数"按下葫芦浮起瓢"
激活函数是 CNN 中把神经元输入映射到输出的关键一环,作者对它们的优劣做了清晰的梳理:
- Sigmoid / Tanh / Softsign :都是 S 型饱和函数,两端梯度趋于 0,极易梯度消失。
- ReLU :正区间线性、梯度恒为 1,收敛快、解决了梯度消失,但 x<0 时梯度恒为 0 ,负梯度被直接置零,神经元可能"再也不会被激活"------即著名的 "死神经元(Dead ReLU / 坏死)" 现象。
- PReLU / ELU :给负区间引入非零值以降低坏死率,但要么噪声稳定性存疑,要么计算量、过拟合风险上升。
- Swish :精度比 ReLU 更好,但它在反向传播求梯度时涉及参数多、计算量大 ,导致收敛速度反而不如 ReLU。
一句话:现有的激活函数,在"防坏死"和"快收敛"之间总是顾此失彼。于是作者想:能不能各取一半,拼出一个新函数?
三、背景:TensorFlow 架构与优势
作者先交代了"为什么选 TensorFlow"。
TensorFlow 基本系统架构自下而上分为五层(设备层 → 通信层 → 计算图层 → API 接口 → 应用层),核心在中间两层:

TensorFlow 基本系统架构
- 计算图层:构建分布式子图,把计算任务切割后分别调度到 CPU、GPU 等不同设备上------这正是本文 CPU+GPU 异构模型的底层依据。
- 通信层 :负责设备管理与通讯,依赖 gRPC 协议实现设备间的数据更新与传输,支撑异构特性。
TensorFlow 的三大优势(可用性、灵活性、开源)里,最关键的是灵活性 :它的分布式架构天然支持"同时使用 CPU+GPU 一起算",这为后面的异构协同模型铺平了道路。
作者还对比了主流框架的评分(见下图雷达图,TensorFlow 综合评分 88 分最高):

主流深度学习框架评分雷达图
四、贡献一:异构式 CPU+GPU 协同计算模型
4.1 核心思想:让 CPU 和 GPU"各司其职"
CPU 与 GPU 虽然都有总线、缓存、运算单元,但特长完全不同:
|---------|--------------------|----------------|
| 维度 | CPU | GPU |
| 擅长任务 | 逻辑控制密集、串行、分支复杂的任务 | 数据密集、高度并行的吞吐任务 |
| SIMD 单元 | 少 | 多(远大于 CPU) |
| 线程数 | 少 | 多(远大于 CPU) |
| 典型场景 | 分布式控制、物理模拟、AI 复杂逻辑 | 数据分析、图像处理、矩阵运算 |
单 CPU / 单 GPU 的缺点:任务全压在一个设备上,另一个设备闲置 → 资源浪费 → 性耗比降低。
本文方案 :把 CNN 的计算任务按模块特性拆开 ,逻辑性强的交给 CPU、高度线程化的并行部分交给 GPU,让两者同时工作:

异构式 CPU+GPU 协同计算模型
4.2 怎么落地:tf.device 设备放置 + 任务切割
作者用的是 TensorFlow 1.x 的经典写法,通过 tf.device 把不同算子显式地放到不同设备上:
# 异构式 CPU+GPU:变量放 CPU,计算放 GPU
with tf.device('/cpu:0'):
w = tf.get_variable(...)
b = tf.get_variable(...)
with tf.device('/gpu:0'):
ad = w + b
mu = w * b
在分布式层面,训练请求的流转是:Client 创建 Session → 序列化图定义发给 Distributed Master → Master 按模型参数切割任务并调度到设备。其中 /job:worker/task:0 负责模型训练与推理,/job:ps/task:0(Parameter Server)负责参数存储与更新:

任务切割与分配流程
4.3 结果:训练耗时明显下降
在三台相同配置服务器上的对比实验(取两次测试平均值)如下表:
|-----------------|----------------|
| 训练模型 | 平均训练耗时 / s |
| 单 CPU | 189.490 |
| 单 GPU | 168.870 |
| 异构式 CPU+GPU | 133.995 |

训练耗时对比
结论 :异构式 CPU+GPU 比单 CPU 快约 29.3% ,比单 GPU 快约 20.6% ,且训练准确率几乎不变。作者认为,本质收益在于**"让 CPU 和 GPU 同时作业,避免设备闲置,从而提升性耗比"**。
五、贡献二:ReLU-Swish 激活函数
这是全文我最感兴趣的部分,我们先把"激活函数家族"捋一遍,再看作者怎么"拼"出新函数。
5.1 激活函数全景回顾

常见激活函数一览
① ReLU ------ 简单高效,但有"死穴"
ReLU(x) = max(0, x) = \begin{cases} x, & x > 0 \\ 0, & x \le 0 \end{cases}

ReLU 及其死区
- 优点:正区间线性,梯度恒为 1,收敛快;计算只需"判断是否大于 0"。
- 缺点(坏死) :x<0 时梯度为 0,负梯度被置零,该神经元可能永远无法再被激活,模型有效容量下降。
② PReLU ------ 带参数的 ReLU
负区间用可学习的斜率 a_i 替代 0,缓解坏死。缺点:无法保证是一个"噪声稳定的去激活状态",且 a_i=0 时退化为 ReLU。
③ ELU ------ 指数线性单元
④ Swish ------ 自门控激活函数

Swish 及其极小值
Swish 平滑、非单调,精度优于 ReLU,但:
- 收敛慢:正区间不是线性,比 ReLU 慢一截;
- 计算贵 :反向传播求梯度涉及 \sigma(x) 的导数,参数多、计算量大。
谷歌的测试也印证了这一点:在 MNIST / Fashion-MNIST 上 Swish 的 准确率 普遍略高于 ReLU,但这是以更大的计算量为代价换来的。
5.2 ReLU-Swish:各取一半的分段函数
作者盯着 Swish 和 ReLU 的曲线,做了一个非常直观的"剪裁拼合":正半轴用 ReLU(线性、快),负半轴用 Swish(保留小负值、防坏死):

ReLU-Swish 的分段构造

ReLU-Swish 与 Swish、ReLU 对比
这个设计的双重动机非常清楚:
- 降计算、提收敛 :正区间把 Swish 的非线性段换成 ReLU 的线性段,反向传播时正半轴梯度恒为 1,省掉大量计算、加快收敛。
- 防坏死、保精度 :负区间保留 Swish 的"小负值",让负梯度不至于被完全置零,避免死神经元,同时维持与 Swish 高度相近的特征表达能力。
我的理解: ReLU-Swish 本质上是"Swish 的保活优点 + ReLU 的线性速度"的取并集 。用一句话概括它的设计哲学------ 取 Swish 之"活",弃其"慢";取 ReLU 之"快",弃其"死" 。
六、实验与结果分析
6.1 收敛速度
作者给出,ReLU-Swish 的收敛速度明显快于 Swish(正半轴线性带来更快的下降):

收敛速度示意
6.2 准确率
在"卷积核为 10 的小型 CNN 测试模型"上,取 3 次 CIFAR-10 / MNIST 训练结果的平均 accuracy:

准确率对比
- ReLU-Swish:97.52%
- Swish:96.7%
准确率上 ReLU-Swish 也有所提升(+0.82 个百分点)。
6.3 谷歌 Swish vs ReLU 的参考数据(表 3 复现)
作为背景,作者引用了谷歌在 AlexNet 上对比 Swish 与 ReLU 的测试结果:

谷歌 Swish vs ReLU 测试
🔎 一个小发现(疑点) :图中 Fashion-MNIST 在 45 层时 Swish 标为 97.69%,与"层数越深越难、准确率整体递减"的趋势明显不符, 疑为原文表格的数据笔误 。精读论文时这种"数据一致性"正是我们要盯住的地方。
6.4 小结
|-----------|---------------------------------------|
| 优化目标 | 结果 |
| 训练耗时(性耗比) | 异构 CPU+GPU 133.995s,显著低于单 CPU / 单 GPU |
| 收敛速度 | ReLU-Swish 快于 Swish |
| 准确率 | ReLU-Swish 97.52% > Swish 96.7% |
七、创新与不足
7.1 创新点
- 工程落地性极强:CPU+GPU 异构模型不需要改网络结构,只需调整任务调度,就能白赚 20%+ 的训练提速。
- 激活函数"取长补短"的思路朴素而有效:用一个分段函数同时化解"坏死"与"收敛慢"这对矛盾,实现简单、几乎无额外参数。
- 两个维度互补:一个管"算得快不快",一个管"学得好不好",从系统到算法形成了完整的优化闭环。
7.2 不足与可商榷之处
- 实验规模偏小 :只在"卷积核为 10 的小型 CNN" + CIFAR-10 / MNIST 上验证,缺少在 ResNet、ImageNet 等更大模型/数据集上的结果,泛化性说服力有限。
- 对比不够系统:没有把 ReLU-Swish 与 ELU、PReLU、LeakyReLU、GELU、Mish 等做同条件下的公平对比。
- "性耗比"未真正量化 :论文用"训练耗时"近似性耗比,但没有给出实测功耗(W)数据,"性耗比"这一核心概念缺了"耗"的量化支撑。
- x=0 处不可导 :ReLU-Swish 在 0 点的左导数为 \sigma(0)=0.5、右导数为 1,是个"尖点"。虽然实践中影响很小,但从理论上讲并非处处光滑。
- 时代局限:tf.device 的手工设备放置是 TensorFlow 1.x 的做法,如今更推荐 tf.distribute、混合精度(AMP)、XLA 等自动化手段。
八、思考延伸
8.1 ReLU-Swish 与 HardSwish:2019 年的"不谋而合"
我觉得最有意思的是这条线索:ReLU-Swish 与 MobileNetV3 提出的 h-swish(HardSwish)其实是同年(2019 年前后)的两个"殊途同归"。
- Swish 现在在 PyTorch 里就是 SiLU(torch.nn.SiLU)。
- 谷歌在 MobileNetV3 里为了在移动端降低 Swish 的计算成本 ,提出了 h-swish:
h\text{-}swish(x) = x \cdot \frac{ReLU6(x+3)}{6}
两者都是"把 Swish 里算得贵的部分换成分段线性来加速 ",但方向恰好相反:
|--------------------------|------------------|----------------|
| | 保留 Swish 的部分 | 换成线性/便宜的部分 |
| ReLU-Swish(本文) | 负半轴(保活) | 正半轴 → ReLU |
| h-swish(MobileNetV3) | 正半轴(近似 Swish) | 用 ReLU6 分段线性近似 |
这恰好说明:"给 Swish 做廉价近似"是那个时间点的共识需求,而本文从"防坏死"角度切入,与 MobileNetV3 从"移动端提速"切入,形成了很好的呼应。能在 2019 年独立想到这一层,是本文真正的闪光点。
8.2 三行代码就能复现
ReLU-Swish 的实现门槛极低,PyTorch 里三行即可:
import torch
def relu_swish(x):
return torch.where(x >= 0, x, x * torch.sigmoid(x))
# 等价于:x * torch.where(x >= 0, 1.0, torch.sigmoid(x))
TensorFlow 2.x 版:
import tensorflow as tf
def relu_swish(x):
return tf.where(x >= 0, x, x * tf.math.sigmoid(x))
正因为实现简单、无额外参数,它非常适合作为"即插即用"的激活函数做快速实验。
8. 3 对"CPU+GPU 异构"的现代反思
论文的 CPU+GPU 模型放在今天看是"朴素但方向正确"。如今工程界的标准答案是 tf.distribute.Strategy (如 MirroredStrategy)、PyTorch 的 DataParallel/DistributedDataParallel、Horovod、NCCL 通信、混合精度训练(AMP) 。但作者"按任务特性而非一刀切地调度设备 "的思想,与现在"把矩阵乘丢给 Tensor Core、把数据预处理丢给 CPU 多线程 "的实践是一脉相承的。若再补上实测功耗,把"性耗比"从"耗时近似"升级为真正的"每瓦性能",这条线会更完整。
论文信息:郭敏钢,宫鹤. 基于 Tensorflow 对卷积神经网络的优化研究J. 计算机工程与应用, 2020, 56(1): 158-164. DOI: 10.3778/j.issn.1002-8331.1906-0214