機器學習-實現簡單神經網絡(筆記和代碼實現)

一、神經網絡簡介

       神經網絡算法的發展歷史

       起源:20世紀中葉,一種仿生學產品。

       興起:環境->2進制創新;能力->軟硬件;需求->人的性價比。

       主要功能:

           分類識別

           分類:圖像(自動駕駛)、語音(語音助手)、文本(新聞推送)

       (1)瞭解神經網絡的脈絡

            訓練學習:網絡結構、激勵函數、損失函數、梯度下降

            網絡結構:

    這就是一個神經網絡的結構,是一個單層的結構,但是具有輸入層、隱含層、輸出層、最終預測的值。

    邏輯迴歸:

        它是一種最簡化的網絡結構。

    激勵函數:

        作用:提供規模化的非線性化能力。

    常用的神經元:

        Sigmoid,它的優點是在整個區間上都是可導,缺點是不對稱:

        tanh:

        ReLU:

    目前使用的最多的神經元是ReLU。

    損失函數:

        理解神經網絡的相關概念和函數。

    單次訓練損失:

    全部訓練損失:

    梯度下降:

         理解邏輯迴歸中的梯度下降。

          對w、b進行同步更新。

    網絡向量化:

        理解神經網絡的網絡向量化。

    以上就是向量化的過程。

    網絡梯度下降:

    訓練過程:

        通過觀察神經網絡的學習過程形成較爲直觀的理解。

    總結:需要理解神經網絡的基本結構和核心組件概念。

二、機器學習-實現簡單神經網絡

    (1)介紹人工智能的基本概念和邏輯體系

    (2)研究兩種數據分類算法

    (3)通過python,運用分類算法,實現只有一層的神經網絡

    需要構造的神經網絡:

    (1)介紹分類算法的理論基礎

    (2)使用Pandas,NumPy和matplotlib等python開發庫去讀取,加工和可視化數據集。

    (3)使用python實現兩種分類算法

    分類算法:(1)感知器(2)適應性線性神經元

1. 感知器數據分類算法

    步驟:(權重向量W,訓練樣本X)

    ▷  把權重向量初始化爲0,或把每個分量初始化爲[0,1]間任意小數;

      把訓練樣本輸入感知器,得到分類結果(-1或1);

      根據分類結果更新權重向量。

 

    步調函數也叫做激活函數。

    權重和閾值的更新如下:

    感知器算法的適用範圍要滿足下面第一幅圖中的範圍:

    感知器算法算法步驟


2. 自適應線性神經元:

    自適應神經元算法步驟


    自適應線性神經元與感知器分類算法的區別:

      第一個:自適應性神經元輸入數據計算出結果,然後它會把計算的結果和輸入的正確結果進行比較,如果計算的結果與正確結果不一致,它就會根據和已給定結果的差距去動態的調整參數(w0,w1,…,wn)。

      第二個:自適應性神經元使用的激活函數與感知器用的是不一樣的,它不在是步調函數,而是直接把數據和神經參數相乘,所得的結果直接當成最終結果(x0*w0+x1*w1+x2*w2+…+xm*wm)。

    看一看自適應神經元時怎麼通過動態調整來調整它的神經元參數,使用的是一種漸進下降的數值算法,不斷縮短與正確結果的距離。


    

三、程序代碼

      使用python語言進行編寫,實現簡單的神經網絡算法,用感知器算法和自適應神經元兩種分類方法對數據集進行分類。

      用到的python版本:python 3.6   

      工具包:numpy、pandas、matplotlib

(1)感知器算法

# -*_coding:utf8-*-
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import ListedColormap


# 感知器算法
class Perceptron(object):
    """
    eta:學習率
    n_iter:權重向量的訓練次數
    W:神經分叉權重向量
    errors:用於記錄神經元判斷出錯次數
    """
    # 初始化
    def __init__(self, eta=0.01, n_iter=10):
        self.eta = eta
        self.n_iter = n_iter

    # 神經網絡輸入
    def net_input(self, X):
        """
        z=W0+W1*X1+...+Xn*Xn
        """
        return np.dot(X, self.w_[1:]) + self.w_[0]
    
    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)
    # 訓練函數
    def fit(self, X, y):
        """
        輸入訓練數據,培訓神經元
        X:輸入樣本向量
        y:對應樣本分類
        X:shape[n_samples,n_features]
        X:[[1,2,3],[4,5,6]]
        y:[1.-1]
        n_samples:2
        n_features:3
        初試話權重向量爲0
        """
        self.w_ = np.zeros(1 + X.shape[1])
        self.errors_ = []
        for _ in range(self.n_iter):
            errors = 0
            """
           X:[[1,2,3],[4,5,6]]
           y:[1,-1]
           zip(X,y)=[[1,2,3,1],[4,5,6,-1]] 
           """
            for xi, target in zip(X, y):
                """
                update=η*(y-y')
              """
                update = self.eta * (target - self.predict(xi))
                """
                xi是一個向量
                update * xi 等價:[ΔW(1)=X[1]*update,ΔW(2)=X[2]*update,ΔW(3)=X[3]*update]
              """
                self.w_[1:] += update * xi
                self.w_[0] += update
                errors += int(update != 0.0)
                self.errors_.append(errors)


# 繪圖函數
def plot_decision_regins(X, y, classifier, resolutions=0.02):
    marker = ('s', 'x', 'o', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max()
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max()

    print(x1_min, x1_max)
    print(x2_min, x2_max)

    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolutions), np.arange(x2_min, x2_max, resolutions))

    # 預測
    z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    z = z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1], alpha=0.8, c=cmap(idx), marker=marker[idx], label=cl)


file = open("F:/=data.csv")
df = pd.read_csv(file, header=None)
print(df.head(10))

y = df.loc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)

X = df.iloc[0:101, [0, 2]].values

plt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')
plt.scatter(X[50:100, 0], X[50:100, 1], color='blue', marker='x', label='versicolor')
plt.xlabel("Petal length")
plt.ylabel("Flower diameter length")
plt.legend(loc="upper left")
plt.show()

ppn = Perceptron(eta=0.1, n_iter=10)
ppn.fit(X, y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('sum-squared-error')
plt.show()

plot_decision_regins(X, y, ppn, resolutions=0.02)
plt.xlabel("Petal length")
plt.ylabel("Flower diameter length")
plt.legend(loc="upper left")
plt.show()
(2)自適應神經元
# -*_coding:utf8-*-
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.colors import ListedColormap


# 自適應神經元
class AdalineGD(object):
    """
    eta:float
    學習率 :0~1
    n_iter:int
    對訓練數據進行學習改進次數
    w_:一維向量
    存儲權重數值
    error_:
    存儲每次迭代改進時,網絡對數據進行錯誤判斷的次數
    """
    # 初始化
    def __init__(self, eta=0.01, n_iter=50):
        self.eta = eta
        self.n_iter = n_iter

    # 神經網絡輸入
    def net_input(self, X):
        """
        z=W0+W1*X1+...+Xn*Xn
        """
        return np.dot(X, self.w_[1:]) + self.w_[0]

    # 激活函數
    def activation(self, X):
        return self.net_input(X)

    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)

    # 訓練函數
    def fit(self, X, y):
        """
        X:二維數組[n_samples,n_features]
        n_samples:表示X中含有訓練數據條目數
        n_features:含有4個數據的一維向量,用於表示一條訓練條目
        y:一維向量
        用於存儲每一條訓練條目對應的正確分類
        """
        self.w_ = np.zeros(1 + X.shape[1])
        self.cost_ = []
        for i in range(self.n_iter):
            output = self.net_input(X)
            errors = (y - output)
            # 神經元參數的更新
            self.w_[1:] += self.eta * X.T.dot(errors)
            self.w_[0] += self.eta * errors.sum()
            cost = (errors ** 2).sum() / 2.0
            self.cost_.append(cost)
        return self


# 繪圖函數
def plot_decision_regins(X, y, classifier, resolutions=0.02):
    marker = ('s', 'x', 'o', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max()
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max()

    print(x1_min, x1_max)
    print(x2_min, x2_max)

    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolutions), np.arange(x2_min, x2_max, resolutions))

    # 預測
    z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    z = z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1], alpha=0.8, c=cmap(idx), marker=marker[idx], label=cl)


file = open("F:/data.csv")
df = pd.read_csv(file, header=None)
print(df.head(10))

y = df.loc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)

X = df.iloc[0:101, [0, 2]].values

ada = AdalineGD(eta=0.0001, n_iter=50)
ada.fit(X, y)
plot_decision_regins(X, y, classifier=ada)
plt.title('Adaline-Gradient descent')
plt.xlabel('Petal length')
plt.ylabel('Flower diameter length')
plt.legend(loc='upper left')
plt.show()

plt.plot(range(1, len(ada.cost_) + 1), ada.cost_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('sum-squared-error')
plt.show()
(3)運行結果圖


樣本數據圖


運行錯誤迭代圖

 

感知器算法分類圖


運行錯誤迭代圖


自適應神經元分類圖

     本文中的數據集下載:data.csv

     本文代碼下載:https://github.com/Messi-Q/The-neural-network/tree/master/venv/Include

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章