1. 程式人生 > >機器學習-實現簡單神經網路(筆記和程式碼實現)

機器學習-實現簡單神經網路(筆記和程式碼實現)

一、神經網路簡介

       神經網路演算法的發展歷史

       起源: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)執行結果圖

樣本資料圖

執行錯誤迭代圖

 

感知器演算法分類圖

執行錯誤迭代圖

自適應神經元分類圖