relu的作用

一、reactsuper的作用

在進行神經網絡的設計時,我們通常會添加一些非線性函數對隱藏層進行激活,這些非線性函數被稱為激活函數,這些函數的作用在於增加模型的複雜度,以更好地擬合訓練數據。relu激活函數是非常常用的一種,因為其相比於其他函數來說計算速度比較快,同時也相對不容易出現梯度消失的情況。

relu 函數可以定義為 max(0,x),它對非負值返回輸入值(直接傳輸到輸出端),而對負值返回0。在整個網絡中,relu函數負責非線性轉換從而增強網絡的表達能力,甚至可以將低維的輸入空間映射到高維的特徵空間。

def relu(x):
    return np.maximum(0, x)

二、relu層的作用

在構建卷積神經網絡時,經常使用的一個層是 relu 層,這個層的作用就是應用 relu 函數到每一個輸入神經元,這樣輸出就不再是線性的而是非線性的,並能夠在跟小的計算負載下進行擬合。由於 relu 可以自動執行去除線性軸大多數部分的工作,因此可以被看作是一個類似降維的操作。

在網絡的實現上,relu層往往添加在卷積層或全連接層後面,起到增強層數的效果,並能提高模型表現。其主要的作用是在計算神經元的加權和時,能夠將負數直接變為0,這樣就能強制網絡學習到較為魯棒的特徵。當 relu 激活函數提取的特徵能夠很好地識別訓練數據的特徵時,就可以用來對未知數據進行預測。

class ReLU(Layer):
    def forward(self, x):
        self.x = x
        return np.maximum(0, x)
    
    def backward(self, grad):
        grad[self.x < 0] = 0
        return grad

三、relu函數使用方法

在使用 relu 函數時,我們可以直接調用 np.maximum(0,x) 函數,其中 x 是輸入的一個向量、矩陣或張量等。同時,也可以使用類似 Keras 這樣的深度學習框架內置的 relu 層,來簡化我們對 relu 函數的使用。例如在 Keras 中,我們可以直接定義一個激活函數層使用 relu 激活函數。

from keras.layers import Activation
from keras.layers import Dense
model = Sequential([
    Dense(units=64, input_shape=(784,)),
    Activation('relu'),
    Dense(units=10),
    Activation('softmax')
])

四、relu函數優缺點

我們知道,使用激活函數的主要原因是為了增強神經網絡的非線性能力,以更好地擬合訓練數據。而 relu 作為其中的一種激活函數,它的主要優點有兩個:

一方面是計算速度相對較快,這是由於 relu 函數計算簡單,僅需要一個比較運算和一個取最大值的操作即可;

另一方面是可以有效避免梯度消失的問題,當神經網絡的深度增加時,使用 sigmoid 或 tanh 等函數作為激活函數時,往往會出現梯度消失的情況,從而導致無法進行有效的反向傳播。而 relu 函數的導數在大於0時為1,在小於等於0時為0,這樣就保證了當值為0時,導數仍然為0,但並不會像 sigmoid、tanh 函數那樣導致梯度消失。

但是,relu 函數也存在缺點,主要原因在於其輸入小於0時對應的導數為0。這種情況稱之為“神經元死亡”,如果這種情況發生在大量的神經元中,就可能導致整個網絡的學習過程被破壞,無法進行訓練。一種改進的方法是使用 LeakyReLU 或 PRelu 等函數替代 relu 函數,這些函數在輸入小於0時的導數不再為0,從而避免了“神經元死亡”的情況。

五、對relu改進後的激活函數

經過不斷改進,出現了一些可以替代 relu 函數的激活函數,比如參數 ReLU (PReLU) 和 Exponential Linear Units (ELU) 等。PReLU 是基於參數的 ReLU 函數,不同於傳統的“輸入小於0時輸出0”的數值,PReLU 使用學習到的參數來將多數負輸入映射到非零輸出,以散布有用的梯度。比如這類函數可以解決 relu 導致的神經元死亡問題。

class PreLU(Layer):
    def __init__(self, dim):
        self.dim = dim
        self.alpha = np.random.normal(size=(dim,))
        self.alpha[self.alpha=0
        out = np.copy(x)
        out[out<0] *= self.alpha[np.newaxis,:]
        return out
    
    def backward(self, grad):
        grad[self.mask] = 1
        grad[~self.mask] = self.alpha[~self.mask]
        return grad

六、卷積神經網絡中relu層的作用

在卷積神經網絡中,常常使用 relu 函數作為激活函數,同時將其添加在卷積層和池化層之後。這種方式的主要作用在於,在輸入層和輸出層之間添加非線性映射,以提高模型的表達能力,在卷積層後應用 relu 函數,可以將負數直接變為0,這樣就能強制網絡學習到較為魯棒的特徵。

在使用 relu 函數的同時,我們還需要對其超參數進行調整,以達到較好的效果。超參數的主要有兩個:滑動窗口大小和步幅。其中滑動窗口大小是指單次取出的可能與卷積層大小相同或更大的圖像塊;而步幅則是指窗口每次滑動的距離。通過調整這兩個超參數,我們可以有效地提高卷積神經網絡的效果。

class Conv:
    def __init__(self, in_channel, out_channel, kernel_size, stride=1, bias=True):
        self.w = np.random.randn(out_channel, in_channel, kernel_size, kernel_size)
        self.b = np.zeros((out_channel, 1)) if bias else None
        self.stride = stride
        self.kernel_size = kernel_size

    def forward(self, x):
        n, c, h, w = x.shape
        hh = int((h - self.kernel_size) / self.stride) + 1
        ww = int((w - self.kernel_size) / self.stride) + 1
        out = np.zeros((n, self.w.shape[0], hh, ww))

        self.x_cache = x

        for example in range(n):
            for ch in range(self.w.shape[0]):
                for i in range(hh):
                    for j in range(ww):
                        out[example, ch, i, j] = np.sum(x[example, :, i*self.stride:i*self.stride+self.kernel_size, j*self.stride:j*self.stride+self.kernel_size] * self.w[ch, :, :, :])

        if self.b is not None:
            out += self.b.reshape(1, self.b.shape[0], 1, 1)
        return out

    def backward(self, grad_out):
        n, c, h_out, w_out = grad_out.shape
        _, _, h_in, w_in = self.x_cache.shape

        grad_w = np.zeros_like(self.w)
        grad_x = np.zeros_like(self.x_cache)
        for example in range(n):
            for ch in range(c):
                for i in range(h_out):
                    for j in range(w_out):
                        grad_x[example, ch, i*self.stride:i*self.stride+self.kernel_size, j*self.stride:j*self.stride+self.kernel_size] += grad_out[example, :, i, j] * self.w[:, ch, :, :]
                        grad_w[:, ch, :, :] += grad_out[example, :, i, j][:, np.newaxis, np.newaxis] * self.x_cache[example, :, i*self.stride:i*self.stride+self.kernel_size, j*self.stride:j*self.stride+self.kernel_size]
        self.w -= self.lr * grad_w / n
        if self.b is not None:
            self.b -=  self.lr * np.mean(grad_out, axis=(0, 2, 3), keepdims=True)

        return grad_x

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

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

相關推薦

  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • @scope("prototype")的作用及應用

    本文將從以下幾個方面進行詳細闡述@scope(“prototype”)在編程開發中的作用和應用。 一、代碼復用 在開發中,往往會有很多地方需要復用同一個類的…

    編程 2025-04-28
  • Python中import sys的作用

    Python是一種非常強大的編程語言,它的標準庫提供了許多有用的模塊和函數。sys模塊是Python標準庫中的一個重要模塊,用於與Python解釋器和操作系統進行交互。它允許開發者…

    編程 2025-04-28
  • Python配置環境變量的作用

    Python配置環境變量是為了讓計算機能夠更方便地找到Python語言及其相關工具的位置,使其可以在任意目錄下使用Python命令。當您安裝Python後,您需要進行環境變量設置,…

    編程 2025-04-28
  • Python的意義和作用

    Python是一種高級語言,它的簡潔易讀和豐富的庫使得它成為了廣泛使用的編程語言之一。Python可以完成諸如數據科學、機器學習、網絡編程等各種任務,因此被很多開發人員和研究人員視…

    編程 2025-04-27
  • Python定義空列表及其作用

    Python是一種廣泛使用的強類型解釋型編程語言。在Python中,我們可以使用列表來存儲一系列不同類型的元素。列表是Python內置的一種高效數據結構,可以在其中存儲任意數量的元…

    編程 2025-04-27
  • 理解Python __init__的作用

    對__init__的作用進行詳細的闡述,並給出對應代碼示例。 一、對象實例化與構造函數 在面向對象編程中,我們經常需要創建對象,而對象的創建和初始化需要先定義一個類,然後通過在類中…

    編程 2025-04-27
  • 從多個角度詳細解析endup函數的作用

    一、代碼示例 /** * 將字符串末尾的n個字符移到字符串開頭 * @param {string} str – 需要進行字符處理的字符串 * @param {number} n -…

    編程 2025-04-25
  • Redis的作用

    一、緩存 Redis最常見的用途是作為緩存。所謂緩存,就是將頻繁讀取、但不經常修改的數據存儲在內存中,用戶請求數據時優先從內存中讀取,可大幅提升數據訪問效率。Redis的數據結構特…

    編程 2025-04-24

發表回復

登錄後才能評論