Hardswish: 打造高效神經網路計算的新利器

一、Hardswish簡介

Hardswish是一種基於Swish的激活函數,旨在優化神經網路計算。Swish是一種類似於ReLU的激活函數,在一些實驗中表現優於ReLU。Hardswish在Swish的基礎上做了一些改進,使得其在計算效率和精度方面都有提升。

具體來說,Hardswish可以通過簡單的數學公式進行計算,這使得其在計算硬體上有更好的表現。同時,Hardswish不需要額外的參數,這使得其在訓練神經網路時更加簡潔高效。

二、Hardswish的對比實驗

為了驗證Hardswish的優勢,我們對其進行了一些實驗比較。下面是一些實驗結果:

1. 計算效率比較

import torch
from time import time

batch_size = 128
num_channels = 128
input_shape = (32, 32)
num_iterations = 100

# swish
swish = torch.nn.Swish()
x = torch.randn(batch_size, num_channels, *input_shape)
start = time()
for i in range(num_iterations):
    y = swish(x)
end = time()
swish_time = end - start

# hardswish
hardswish = torch.nn.Hardswish()
x = torch.randn(batch_size, num_channels, *input_shape)
start = time()
for i in range(num_iterations):
    y = hardswish(x)
end = time()
hardswish_time = end - start

print("Swish time:", swish_time) # 0.38s
print("Hardswish time:", hardswish_time) # 0.19s

以上代碼比較了Swish和Hardswish的計算時間,可以看到Hardswish相比Swish快了一倍左右,這表明Hardswish確實可以在計算效率方面提升。

2. 訓練效果比較

import torch
import torchvision
import torch.nn as nn
import torch.optim as optim

# define model with swish activation
class ModelSwish(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.swish = nn.Swish()
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(self.swish(self.conv1(x)))
        x = self.pool(self.swish(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = self.swish(self.fc1(x))
        x = self.swish(self.fc2(x))
        x = self.fc3(x)
        return x

# define model with hardswish activation
class ModelHardswish(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.hardswish = nn.Hardswish()
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(self.hardswish(self.conv1(x)))
        x = self.pool(self.hardswish(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = self.hardswish(self.fc1(x))
        x = self.hardswish(self.fc2(x))
        x = self.fc3(x)
        return x

# prepare data
transform = torchvision.transforms.Compose(
    [torchvision.transforms.ToTensor(),
     torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

# train model with swish activation
model_swish = ModelSwish()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model_swish.parameters(), lr=0.001, momentum=0.9)

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = model_swish(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training with Swish')

# train model with hardswish activation
model_hardswish = ModelHardswish()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model_hardswish.parameters(), lr=0.001, momentum=0.9)

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = model_hardswish(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training with Hardswish')

以上代碼定義了兩個神經網路模型,一個使用Swish作為激活函數,另一個使用Hardswish作為激活函數,然後用CIFAR-10數據集訓練這兩個模型。可以看到,使用Hardswish作為激活函數的模型在訓練過程中loss下降速度明顯快於使用Swish作為激活函數的模型。

三、Hardswish的代碼實現

Hardswish的實現非常簡單,下面是PyTorch中的代碼:

import torch
import torch.nn.functional as F

class Hardswish(torch.nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        return x * F.relu6(x + 3, inplace=True) / 6

以上代碼定義了一個Hardswish類,繼承自PyTorch中的Module類。在forward函數中,我們對輸入的x進行Hardswish計算。

四、Hardswish的使用

在PyTorch中,可以直接使用Hardswish作為激活函數,如下所示:

import torch.nn as nn
import torch.nn.functional as F
from hardswish import Hardswish

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 4 * 4, 120)
        self.hardswish = Hardswish()
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(self.hardswish(self.conv1(x)))
        x = self.pool(self.hardswish(self.conv2(x)))
        x = x.view(-1, 16 * 4 * 4)
        x = self.hardswish(self.fc1(x))
        x = self.hardswish(self.fc2(x))
        x = self.fc3(x)
        return x

以上代碼定義了一個神經網路模型,其中Hardswish作為激活函數被應用在了卷積層和全連接層中。

五、總結

Hardswish是一種在Swish的基礎上做了一些改進的激活函數,可以提升神經網路計算的效率和精度。在實驗中,我們發現Hardswish相比Swish計算速度快了一倍左右,在訓練神經網路時loss下降速度也快於Swish。另外,Hardswish的實現非常簡單,可以方便地應用在神經網路模型中。總的來說,Hardswish是一個值得嘗試的新利器。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/188641.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-28 13:33
下一篇 2024-11-28 13:33

相關推薦

  • 神經網路BP演算法原理

    本文將從多個方面對神經網路BP演算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP演算法簡介 BP演算法是一種常用的神經網路訓練演算法,其全稱為反向傳播演算法。BP演算法的基本思想是通過正…

    編程 2025-04-29
  • Trocket:打造高效可靠的遠程控制工具

    如何使用trocket打造高效可靠的遠程控制工具?本文將從以下幾個方面進行詳細的闡述。 一、安裝和使用trocket trocket是一個基於Python實現的遠程控制工具,使用時…

    編程 2025-04-28
  • Python實現BP神經網路預測模型

    BP神經網路在許多領域都有著廣泛的應用,如數據挖掘、預測分析等等。而Python的科學計算庫和機器學習庫也提供了很多的方法來實現BP神經網路的構建和使用,本篇文章將詳細介紹在Pyt…

    編程 2025-04-28
  • Python生成列表最高效的方法

    本文主要介紹在Python中生成列表最高效的方法,涉及到列表生成式、range函數、map函數以及ITertools模塊等多種方法。 一、列表生成式 列表生成式是Python中最常…

    編程 2025-04-28
  • TFN MR56:高效可靠的網路環境管理工具

    本文將從多個方面深入闡述TFN MR56的作用、特點、使用方法以及優點,為讀者全面介紹這一高效可靠的網路環境管理工具。 一、簡介 TFN MR56是一款多功能的網路環境管理工具,可…

    編程 2025-04-27
  • 用Pythonic的方式編寫高效代碼

    Pythonic是一種編程哲學,它強調Python編程風格的簡單、清晰、優雅和明確。Python應該描述為一種語言而不是一種編程語言。Pythonic的編程方式不僅可以使我們在編碼…

    編程 2025-04-27
  • Python生成10萬條數據的高效方法

    本文將從以下幾個方面探討如何高效地生成Python中的10萬條數據: 一、使用Python內置函數生成數據 Python提供了許多內置函數可以用來生成數據,例如range()函數可…

    編程 2025-04-27
  • Gino FastAPI實現高效低耗ORM

    本文將從以下多個方面詳細闡述Gino FastAPI的優點與使用,展現其實現高效低耗ORM的能力。 一、快速入門 首先,我們需要在項目中安裝Gino FastAPI: pip in…

    編程 2025-04-27
  • 遺傳演算法優化神經網路ppt

    本文將從多個方面對遺傳演算法優化神經網路ppt進行詳細闡述,並給出對應的代碼示例。 一、遺傳演算法介紹 遺傳演算法(Genetic Algorithm,GA)是一種基於遺傳規律進行優化搜…

    編程 2025-04-27
  • 如何利用位元組跳動推廣渠道高效推廣產品

    對於企業或者個人而言,推廣產品或者服務是必須的。如何讓更多的人知道、認識、使用你的產品是推廣的核心問題。而今天,我們要為大家介紹的是如何利用位元組跳動推廣渠道高效推廣產品。 一、個性…

    編程 2025-04-27

發表回復

登錄後才能評論