Pytorch 中的 Swish 激活函数

激活函数是人工神经网络的基本组成部分。他们将非线性引入模型,使其能够学习数据中的复杂关系。Swish 激活函数就是此类激活函数之一,因其独特的属性和相对于广泛使用的整流线性单元 (ReLU) 激活的潜在优势而受到关注。在本文中,我们将深入研究 Swish 激活函数,提供数学公式,探索其相对于 ReLU 的优势,并使用 PyTorch 演示其实现。

Swish 激活功能

Swish 激活函数由 Google 研究人员于 2017 年推出,其数学定义如下:

Swish(x) = x * sigmoid(x)

Where:

  • x:激活函数的输入值。
  • sigmoid(x):sigmoid 函数,将任何实数值映射到范围 [0, 1]。随着 x 的增加,它从 0 平滑过渡到 1。

Swish 激活将线性分量(输入 x)与非线性分量(sigmoid函数)相结合,产生平滑且可微的激活函数。

在哪里使用 Swish 激活?

Swish 可用于各种神经网络架构,包括前馈神经网络、卷积神经网络 (CNN) 和循环神经网络 (RNN)。它的优势在深度网络中变得尤为明显,它可以帮助缓解梯度消失问题。

Swish 激活函数相对于 ReLU 的优点

现在,我们来探讨一下 Swish 激活函数与流行的 ReLU 激活函数相比的优势。

平滑度和可微分性

由于 sigmoid 分量的存在,Swish 是一个平滑且可微的函数。此属性使其非常适合基于梯度的优化技术,例如随机梯度下降 (SGD) 和反向传播。相比之下,ReLU 在零处不可微(ReLU 的导数在 x=0 时未定义),这可能会带来优化挑战。

改进深度网络的学习

在深度神经网络中,与 ReLU 相比,Swish 可以实现更好的学习和收敛。Swish 的平滑性有助于梯度在网络中更平滑地流动,减少训练期间梯度消失的可能性。这在非常深的网络中尤其有用。

类似的计算成本

Swish 激活的计算效率很高,类似于 ReLU。这两个函数都涉及基本的算术运算,不会显着增加训练或推理过程中的计算负担。

使用 PyTorch 实现

现在,我们来看看如何使用 PyTorch 实现 Swish 激活函数。我们将创建一个自定义 Swish 模块并将其集成到一个简单的神经网络中。

让我们从导入必要的库开始。

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

一旦我们完成了库的导入,我们就可以定义自定义激活------Swish。

以下代码定义了一个继承 PyTorch 基类的类。类内部有一个forward方法。该方法定义模块如何处理输入数据。它将输入张量作为参数,并在应用 Swish 激活后返回输出张量。

python 复制代码
# Swish功能
class Swish(nn.Module):
	def forward(self, x):
		return x * torch.sigmoid(x)

定义 Swish 类后,我们继续定义神经网络模型。

在下面的代码片段中,我们使用 PyTorch 定义了一个专为图像分类任务设计的神经网络模型。

  • 输入层有28×28像素。

  • 隐藏层

    • 第一个隐藏层由 256 个神经元组成。它采用扁平输入并应用线性变换来产生输出。
    • 第二个隐藏层由 128 个神经元组成,从前一层获取 256 维输出并产生 128 维输出。
    • Swish 激活函数应用于两个隐藏层,以向网络引入非线性。
    • 输出层由 10 个神经元组成,用于执行 10 个类别的分类。
python 复制代码
# 定义神经网络模型
class Net(nn.Module):
	def __init__(self):
		super(Net, self).__init__()
		self.fc1 = nn.Linear(28 * 28, 256)
		self.fc2 = nn.Linear(256, 128)
		self.fc3 = nn.Linear(128, 10)
		self.swish = Swish()

	def forward(self, x):
		x = x.view(-1, 28 * 28)
		x = self.fc1(x)
		x = self.swish(x)
		x = self.fc2(x)
		x = self.swish(x)
		x = self.fc3(x)
		return x

为了设置用于训练的神经网络,我们创建模型的实例,定义损失函数、优化器和数据转换。

python 复制代码
# 创建模型的实例
model = Net()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 定义数据转换
transform = transforms.Compose([
	transforms.ToTensor(),
])

完成此步骤后,我们可以继续在数据集上训练和评估模型。让我们使用以下代码加载 MNIST 数据并创建用于训练的数据加载器。

python 复制代码
# 加载MNIST数据集
train_dataset = datasets.MNIST('', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('', train=False, download=True, transform=transform)

# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

有了这些数据加载器,我们就可以继续训练循环来迭代批量的训练和测试数据。

在下面的代码中,我们执行了神经网络的训练循环。该循环将重复 5 个时期,在此期间更新模型的权重,以最大限度地减少损失并提高其在训练数据上的性能。

python 复制代码
# 训练循环
num_epochs = 5
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model.to(device)

for epoch in range(num_epochs):
	model.train()
	total_loss = 0.0
	for batch_idx, (data, target) in enumerate(train_loader):
		data, target = data.to(device), target.to(device)
		optimizer.zero_grad()
		output = model(data)
		loss = criterion(output, target)
		loss.backward()
		optimizer.step()
		total_loss += loss.item()
	
	print(f"Epoch {epoch+1}/{num_epochs}, Loss: {total_loss / len(train_loader)}")

输出:

python 复制代码
Epoch 1/5, Loss: 1.6938323568503062
Epoch 2/5, Loss: 0.4569567457397779
Epoch 3/5, Loss: 0.3522500048557917
Epoch 4/5, Loss: 0.31695075702369213
Epoch 5/5, Loss: 0.2961081813474496

最后一步是模型评估步骤。

python 复制代码
# 评估循环
model.eval()
correct = 0
total = 0
with torch.no_grad():
	for data, target in test_loader:
		data, target = data.to(device), target.to(device)
		outputs = model(data)
		_, predicted = torch.max(outputs.data, 1)
		total += target.size(0)
		correct += (predicted == target).sum().item()

print(f"Accuracy on test set: {100 * correct / total}%")

输出:

python 复制代码
Accuracy on test set: 92.02%

结论

Swish 激活函数为 ReLU 等传统激活函数提供了一种有前景的替代方案。它的平滑性、可微性和改善深度网络学习的潜力使其成为现代神经网络架构的宝贵工具。通过在 PyTorch 中实施 Swish,您可以利用其优势并探索其在各种机器学习任务中的有效性。

相关推荐
明月_清风5 分钟前
Python 内存手术刀:sys.getrefcount 与引用计数的生死时速
后端·python
明月_清风7 分钟前
Python 消失的内存:为什么 list=[] 是新手最容易踩的“毒苹果”?
后端·python
IT_陈寒14 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
流浪克拉玛依15 小时前
Go Web 服务限流器实战:从原理到压测验证 --使用 Gin 框架 + Uber Ratelimit / 官方限流器,并通过 Vegeta 进行性能剖析
后端
孟沐15 小时前
保姆级教程:手写三层架构 vs MyBatis-Plus
后端
星浩AI15 小时前
让模型自己写 Skills——从素材到自动生成工作流
人工智能·后端·agent
华仔啊17 小时前
为啥不用 MP 的 saveOrUpdateBatch?MySQL 一条 SQL 批量增改才是最优解
java·后端
武子康18 小时前
大数据-242 离线数仓 - DataX 实战:MySQL 全量/增量导入 HDFS + Hive 分区(离线数仓 ODS
大数据·后端·apache hive
砍材农夫18 小时前
TCP和UDP区别
后端
千寻girling19 小时前
一份不可多得的 《 Django 》 零基础入门教程
后端·python·面试