深度學習的核心在於神經網路的建構與訓練,而理解神經網路的運作原理,則需掌握其基本操作單元以及啟用函式的應用。本文將深入探討這些基礎概念,並輔以 Python 程式碼示例,讓讀者更清晰地理解神經網路的運作機制。

在神經網路中,每個神經元接收輸入後,會進行一系列運算,最終產生輸出。這些運算包含加權和、偏差新增,以及啟用函式的應用。這些運算共同決定了神經元的輸出,進而影響整個網路的行為。

神經網路操作基礎:前向與反向傳播

神經網路的操作包含前向傳播和反向傳播兩個關鍵步驟。前向傳播計算神經網路的輸出,而反向傳播則計算梯度,用於更新網路的權重和偏差。

import numpy as np

class Operation:
    def __init__(self):
        pass

    def forward(self, input_: np.ndarray):
        self.input_ = input_
        self.output = self._output()
        return self.output

    def backward(self, output_grad: np.ndarray):
        np.testing.assert_array_equal(self.output.shape, output_grad.shape)  # 檢查形狀是否一致
        self.input_grad = self._input_grad(output_grad)
        return self.input_grad

    def _output(self) -> np.ndarray:
        raise NotImplementedError()

    def _input_grad(self, output_grad: np.ndarray) -> np.ndarray:
        raise NotImplementedError()

內容解密

Operation 類別定義了神經網路操作的基本框架,包含 forwardbackward 兩個方法,分別執行前向和反向傳播。_output_input_grad 方法則留給子類別實作,以定義具體的操作邏輯。

  graph LR
    A[輸入] --> B(前向傳播)
    B --> C[輸出]
    C --> D(反向傳播)
    D --> E[梯度]

圖表翻譯

此圖展示了神經網路操作的基本流程。輸入資料經過前向傳播計算得到輸出,然後透過反向傳播計算梯度,用於更新網路引數。

啟用函式:Sigmoid

啟用函式為神經網路引入了非線性,使其能夠學習更複雜的模式。Sigmoid 函式是一種常用的啟用函式,其輸出介於 0 和 1 之間。

class Sigmoid(Operation):
    def _output(self) -> np.ndarray:
        return 1.0 / (1.0 + np.exp(-self.input_))

    def _input_grad(self, output_grad: np.ndarray) -> np.ndarray:
        sigmoid_output = self._output()
        return sigmoid_output * (1 - sigmoid_output) * output_grad

內容解密

Sigmoid 類別繼承自 Operation,並實作了 _output_input_grad 方法,分別計算 Sigmoid 函式的輸出和輸入梯度。

  graph LR
    A[輸入] --> B{Sigmoid}
    B --> C[輸出]

圖表翻譯

此圖展示了 Sigmoid 啟用函式的運算流程。輸入資料經過 Sigmoid 函式轉換後,輸出值介於 0 和 1 之間。

本文介紹了神經網路的基本操作和 Sigmoid 啟用函式,並以 Python 程式碼示例說明其實作方式。理解這些基礎概念對於深入學習深度學習至關重要,也為構建更複雜的神經網路奠定了基礎。

神經網路操作基礎

在構建神經網路時,瞭解其基本操作單元至關重要。這些單元被稱為操作(Operation),它們負責處理輸入資料、產生輸出,並在訓練過程中計算梯度。以下,我們將深入探討操作的基礎知識。

基本操作類別

首先,我們定義一個基本的操作類別 Operation。這個類別將作為所有其他操作的基礎。

class Operation(object):
    '''
    基本操作類別。
    '''
    
    def __init__(self):
        pass
    
    def forward(self, input_: ndarray):
        '''
        前向傳遞,儲存輸入並計算輸出。
        
        :param input_: 輸入資料
        :return: 輸出資料
        '''
        self.input_ = input_
        self.output = self._output()
        return self.output
    
    def backward(self, output_grad: ndarray) -> ndarray:
        '''
        反向傳遞,計算輸入梯度。
        
        :param output_grad: 輸出梯度
        :return: 輸入梯度
        '''
        assert_same_shape(self.output, output_grad)
        self.input_grad = self._input_grad(output_grad)

前向傳遞與反向傳遞

  • 前向傳遞(Forward Pass):在前向傳遞中,操作接收輸入資料,然後計算並傳回其輸出。這個過程中,輸入資料被儲存起來,以便在反向傳遞中使用。

  • 反向傳遞(Backward Pass):在反向傳遞中,操作接收到其輸出的梯度,然後計算輸入的梯度。這個過程需要確保輸出梯度和輸出的形狀相同,以保證正確的梯度計算。

梯度檢查

在反向傳遞中,為了確保梯度計算的正確性,我們需要檢查輸出梯度和輸出的形狀是否相同。如果形狀不匹配,則會丟擲一個錯誤,以提示使用者檢查資料形狀。

實作具體操作

根據這個基本的操作類別,我們可以實作各種具體的操作,如加法、乘法等。每種具體操作都需要實作 _output_input_grad 方法,以定義其前向傳遞和反向傳遞的行為。

  flowchart TD
    A[輸入] --> B[前向傳遞]
    B --> C[計算輸出]
    C --> D[儲存輸出]
    D --> E[反向傳遞]
    E --> F[計算輸入梯度]
    F --> G[傳回輸入梯度]

內容解密

上述流程圖描述了操作的基本流程。首先,輸入資料被送入前向傳遞,然後計算並儲存輸出。在反向傳遞中,根據輸出的梯度計算輸入的梯度,並傳回結果。

圖表翻譯

此圖表展示了神經網路操作的基本流程,包括前向傳遞和反向傳遞。每個步驟都對應到操作類別中的特定方法,如 forwardbackward。這個流程是神經網路訓練的基礎,透過它,我們可以瞭解如何計算梯度並更新模型引數。

基礎神經網路操作類別

在深度學習中,神經網路的操作是根據多種基本運算所組成的。為了簡化這些運算的實作,我們定義了一個基礎類別 Operation,它包含了所有神經網路操作所需的基本方法。

Operation 類別

class Operation:
    def _output(self) -> ndarray:
        '''
        定義-operation的輸出。
        
        Raises:
            NotImplementedError: 必須由子類別實作。
        '''
        raise NotImplementedError()

    def _input_grad(self, output_grad: ndarray) -> ndarray:
        '''
        定義-operation的輸入梯度。
        
        Args:
            output_grad (ndarray): 輸出的梯度。
        
        Raises:
            NotImplementedError: 必須由子類別實作。
        '''
        raise NotImplementedError()

ParamOperation 類別

為了處理涉及模型引數的操作,我們定義了一個繼承自 Operation 的子類別 ParamOperation。這個類別主要用於封裝那些涉及模型引數更新的操作。

class ParamOperation(Operation):
    def __init__(self, param: ndarray) -> None:
        '''
        初始化ParamOperation。
        
        Args:
            param (ndarray): 模型引數。
        '''
        self.param = param

實作具體操作

在實際應用中,我們需要根據不同的操作(如矩陣乘法、啟用函式等)來實作 _output_input_grad 方法。這些具體實作將根據操作的性質和要求進行定義。

關於基礎類別的重要性

基礎類別的定義對於構建一個清晰、易於擴充套件的深度學習框架至關重要。它們提供了一個統一的介面和結構,使得開發人員可以方便地新增新的操作和模型元件。同時,基礎類別也幫助確保程式碼的一致性和可維護性。

未來工作

在未來的工作中,我們將繼續定義和實作更多的操作類別,包括但不限於矩陣乘法、卷積運算、池化層等。同時,我們也將著重於最佳化框架的效能和穩定性,以滿足實際應用的需求。

深度學習基礎:層的概念

在深度學習中,層(Layer)是指一組神經元的集合,它們一起工作以處理輸入資料並產生輸出。層是構成神經網路的基本單元,每個層都有一個特定的功能,例如線性變換、啟用函式等。

層的型別

層可以分為三種型別:輸入層(Input Layer)、隱藏層(Hidden Layer)和輸出層(Output Layer)。

  • 輸入層:負責接收輸入資料,並將其傳遞給下一層。
  • 隱藏層:負責處理輸入資料,對其進行變換和計算,以提取有用的特徵。
  • 輸出層:負責產生最終的輸出結果。

層的工作原理

每個層都有一個特定的工作原理。以下是層的工作原理的簡要概述:

  1. 線性變換:每個層都會對輸入資料進行線性變換,例如矩陣乘法。
  2. 啟用函式:每個層都會對線性變換的結果應用啟用函式,例如Sigmoid函式或ReLU函式。
  3. 梯度計算:在反向傳播中,每個層都會計算其輸出的梯度,以便更新權重和偏差。

層的實作

在實作層時,我們需要定義其工作原理,包括線性變換、啟用函式和梯度計算。以下是一個簡單的例子:

import numpy as np

class Layer:
    def __init__(self):
        self.weights = None
        self.bias = None

    def forward(self, input_data):
        # 線性變換
        linear_output = np.dot(input_data, self.weights) + self.bias
        # 啟用函式
        activated_output = self.activation(linear_output)
        return activated_output

    def activation(self, input_data):
        # Sigmoid函式
        return 1 / (1 + np.exp(-input_data))

    def backward(self, output_grad):
        # 梯度計算
        input_grad = np.dot(output_grad, self.weights.T)
        return input_grad

層的應用

層是構成神經網路的基本單元,它們可以被組合成更複雜的結構,以解決不同的問題。以下是一些層的應使用案例子:

  • 多層感知器:多層感知器是一種基本的神經網路結構,它由多個層組成,每個層都有一個特定的功能。
  • 卷積神經網路:卷積神經網路是一種特殊的神經網路結構,它使用卷積層和池化層來處理影像資料。
  • 迴圈神經網路:迴圈神經網路是一種特殊的神經網路結構,它使用迴圈層來處理序列資料。

神經網路中的權重乘法和偏差新增

在神經網路中,權重乘法和偏差新增是兩種基本的運算。權重乘法是指將輸入的特徵與權重矩陣進行乘法運算,而偏差新增則是指將偏差項新增到輸出的結果中。

權重乘法

權重乘法可以使用以下公式表示:

$$y = x \cdot W$$

其中,$x$是輸入的特徵,$W$是權重矩陣,$y$是輸出的結果。

在 Python 中,可以使用以下程式碼實作權重乘法:

import numpy as np

class WeightMultiply:
    def __init__(self, W):
        self.W = W

    def output(self, input_):
        return np.dot(input_, self.W)

    def input_grad(self, output_grad):
        return np.dot(output_grad, self.W.T)

    def param_grad(self, output_grad):
        return np.dot(self.input_.T, output_grad)

偏差新增

偏差新增可以使用以下公式表示:

$$y = x + b$$

其中,$x$是輸入的特徵,$b$是偏差項,$y$是輸出的結果。

在 Python 中,可以使用以下程式碼實作偏差新增:

import numpy as np

class BiasAdd:
    def __init__(self, b):
        self.b = b

    def output(self, input_):
        return input_ + self.b

    def input_grad(self, output_grad):
        return output_grad

    def param_grad(self, output_grad):
        return np.sum(output_grad, axis=0)

結合使用

權重乘法和偏差新增可以結合使用,以實作更複雜的神經網路結構。例如,可以使用以下程式碼實作一個簡單的全連線層:

import numpy as np

class FullyConnected:
    def __init__(self, W, b):
        self.weight_multiply = WeightMultiply(W)
        self.bias_add = BiasAdd(b)

    def output(self, input_):
        return self.bias_add.output(self.weight_multiply.output(input_))

    def input_grad(self, output_grad):
        return self.weight_multiply.input_grad(self.bias_add.input_grad(output_grad))

    def param_grad(self, output_grad):
        weight_grad = self.weight_multiply.param_grad(self.bias_add.input_grad(output_grad))
        bias_grad = self.bias_add.param_grad(output_grad)
        return weight_grad, bias_grad

這個程式碼定義了一個全連線層的類別,該類別包含了權重乘法和偏差新增兩個運算。輸出結果是先進行權重乘法,然後新增偏差項。梯度計算也是一樣,先計算偏差新增的梯度,然後計算權重乘法的梯度。

神經網路基礎:從基本運算到啟用函式

在深度學習的世界中,神經網路是核心組成部分。要構建一個神經網路,首先需要了解其基本運算單元,即神經元(Neuron)或節點(Node)。每個神經元都會接收輸入,進行某種形式的運算,然後輸出結果。這些運算可以是簡單的加權和(Weighted Sum),也可以是複雜的非線性轉換,如Sigmoid函式或ReLU(Rectified Linear Unit)函式。

基本運算:加權和與偏差

最基本的神經元運算是加權和,接著是新增偏差項。這可以用以下Python程式碼表示:

import numpy as np

class Operation:
    def __init__(self, B: np.ndarray):
        """
        初始化Operation類別,設定引數B。
        
        :param B: 偏差引數,為一維numpy陣列。
        """
        assert B.shape[0] == 1, "偏差引數必須是一維陣列"
        self.param = B
        super().__init__(B)

    def _output(self) -> np.ndarray:
        """
        計算輸出。
        
        :return: 輸出結果。
        """
        return self.input_ + self.param

    def _input_grad(self, output_grad: np.ndarray) -> np.ndarray:
        """
        計算輸入梯度。
        
        :param output_grad: 輸出梯度。
        :return: 輸入梯度。
        """
        return np.ones_like(self.input_) * output_grad

    def _param_grad(self, output_grad: np.ndarray) -> np.ndarray:
        """
        計算引數梯度。
        
        :param output_grad: 輸出梯度。
        :return: 引數梯度。
        """
        param_grad = np.ones_like(self.param) * output_grad
        return np.sum(param_grad, axis=0).reshape(1, param_grad.shape[1])

啟用函式:Sigmoid

啟用函式是神經網路中非常重要的組成部分,它們能夠引入非線性,使得神經網路能夠學習和表示更複雜的關係。Sigmoid函式是一種常用的啟用函式,它的輸出範圍在0到1之間,對於二元分類別問題尤其有用。

class Sigmoid(Operation):
    def _output(self) -> np.ndarray:
        """
        計算Sigmoid函式的輸出。
        
        :return: Sigmoid函式的輸出。
        """
        return 1 / (1 + np.exp(-self.input_))

    def _input_grad(self, output_grad: np.ndarray) -> np.ndarray:
        """
        計算Sigmoid函式的輸入梯度。
        
        :param output_grad: 輸出梯度。
        :return: 輸入梯度。
        """
        sigmoid_output = self._output()
        return output_grad * sigmoid_output * (1 - sigmoid_output)

啟用函式:Sigmoid

Sigmoid 啟用函式是一種常用的啟用函式,尤其是在二元分類別問題中。它的輸出範圍在 0 到 1 之間,使得它非常適合用於機率預測。

神經網路基本:操作與啟用

建構神經網路如同搭建積木,而操作(Operation)和啟用函式(Activation Function)正是這些積木的核心。操作負責處理和轉換資料,啟用函式則為網路引入非線性,使其具備學習複雜模式的能力。

操作:資料的搬運工

操作就像神經網路中的齒輪,負責將資料從輸入端傳遞到輸出端。每個操作都定義了特定的計算邏輯,例如矩陣乘法、加法等等。這些操作不僅僅是單純的數學運算,它們還需要記錄運算過程中的中間結果,以便在反向傳播過程中計算梯度,更新網路引數。

import numpy as np

class Operation:
    def __init__(self):
        pass

    def forward(self, input_: np.ndarray):
        self.input_ = input_
        self.output = self._output()
        return self.output

    def backward(self, output_grad: np.ndarray):
        assert self.output.shape == output_grad.shape
        self.input_grad = self._input_grad(output_grad)
        return self.input_grad

    def _output(self):
        raise NotImplementedError

    def _input_grad(self, output_grad):
        raise NotImplementedError


class ParamOperation(Operation):
    def __init__(self, param: np.ndarray):
        super().__init__()
        self.param = param

    def _param_grad(self, output_grad: np.ndarray) -> np.ndarray:
        raise NotImplementedError

內容解密

Operation 類別定義了操作的基本框架,包含 forwardbackward 兩個核心方法。forward 方法執行前向傳播,計算並儲存輸出;backward 方法執行反向傳播,計算輸入梯度。_output_input_grad 方法則由子類別根據具體操作邏輯實作。ParamOperation 類別繼承自 Operation,專門用於處理包含引數的操作,例如權重乘法。它新增了 _param_grad 方法,用於計算引數的梯度。

  graph LR
    A[輸入] --> B(前向傳播)
    B --> C{輸出}
    C --> D(反向傳播)
    D --> E{輸入梯度}
    B -- 引數 --> F{引數梯度}

圖表翻譯

此圖展示了操作的執行流程。輸入資料經過前向傳播產生輸出,然後反向傳播計算輸入梯度,同時根據引數計算引數梯度。這是一個迴圈迭代的過程,透過不斷調整引數,使網路的輸出逼近目標值。

啟用函式:Sigmoid 的魅力

啟用函式為神經網路注入了非線性,使其能夠學習複雜的非線性關係。Sigmoid 函式是一個經典的啟用函式,它將輸入值對映到 0 到 1 之間,常用於二元分類別問題。

class Sigmoid(Operation):
    def _output(self):
        return 1.0 / (1.0 + np.exp(-self.input_))

    def _input_grad(self, output_grad):
        sigmoid_output = self._output()
        return sigmoid_output * (1 - sigmoid_output) * output_grad

內容解密

Sigmoid 類別繼承自 Operation,實作了 _output_input_grad 方法,分別計算 Sigmoid 函式的輸出和輸入梯度。Sigmoid 函式的導數具有特殊的性質,可以直接用其輸出來表示,簡化了梯度的計算。

玄貓的洞見

操作和啟用函式是神經網路的基本。理解它們的工作原理對於構建和訓練神經網路至關重要。隨著深度學習的發展,新的操作和啟用函式不斷湧現,它們共同推動著神經網路技術的進步。選擇合適的操作和啟用函式,並根據具體問題進行調整,是提升神經網路效能的關鍵。未來,我們可以預見更多高效、靈活的操作和啟用函式的出現,為深度學習帶來更多可能性。對於臺灣的開發者而言,深入理解這些基礎概念,並結合本地應用場景進行創新,將有助於在全球深度學習浪潮中佔據一席之地。