Day21 - 人工智慧 II.

斜槓學習 – 零基礎成為 AI 解夢大師秘笈

本文作者:Ovien

系列文章簡介

自由團隊將從0到1 手把手教各位讀者學會(1)Python基礎語法、(2)Python Web 網頁開發框架 – Django 、(3)Python網頁爬蟲 – 周易解夢網、(4)Tensorflow AI語言模型基礎與訓練 – LSTM、(5)實際部屬AI解夢模型到Web框架上。

學習資源

AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源

Can a Single Neuron Learn a Task? 這句話是科學家在40~50年代提出的問題。

在1958年,由 Frank Rosenblatt 所推出的 perceptron,訓練簡單ANN(Artificial Neural Network),公式如下:

圖示如下:

對比 MP model,Perceptron 有著更多優勢:

  • 輸入可以為任何真實數字

  • 加入了權重W可以透過改變權重來學習輸入與輸出的關係

  • 兩者的輸出都侷限在 [0,1] 之間(boolean value)

特別是加了W權重之後,模型可以透過學習得知每個輸入的重要性;可以看到 perceptron 有著不同特徵值輸入和多個神經元的感知器,簡單來說 perceptron 是基於 MP neuron model 所推出的模型,包含一個 combiner 與 threshold,combiner是將輸入與權重的結果進行結合,在今天深度學習領域中,我們稱之為向前傳播(Forward propagation)。

W要如何去定義、找到最佳的值呢? 就必須靠接下來介紹的向後傳播(Back propagation) 

Back propagation

我們的演算法將分為兩個步驟

  1. 先將每次的預測與答案使用 loss function來求出之間的差距


    loss為正,因為y_ty_p還小,需要降低y_p
    loss為負,因為y_ty_p還大,需要提高y_p

    • y_p為預測的值

    • y_t為答案的值

    • loss function : 一個模型輸出與答案之間的差距,當今天預測與答案之間有落差時,要能夠表示出這之間的差距,所以不同的task會有不同的loss function公式

  2. 接下來將執行上面的第二、三句話,我們要如何讓y_p可以根據loss提高或降低呢,必須將腦筋動到一直沒用到的W


    由上述的公式可以達到,由loss的值作判斷,再決定這次的更新是增加或是減少

    • t : 表示當前在做第t筆資料

    • e(t) : 決定這次的Wi是增加或降低

    • α : 為學習率(learning rate),不讓Wi一次調太多,而超出最佳的解,類似Wi在找出最佳參數時所走的步伐大小,通常值<<<<<1

整合向前與向後傳播的過程

  1. Initialization : 設定權重W和門檻θ,範圍將落在0.5到-0.5隨機選出

  2. Activation : 將每個X丟進數學式並求出y_p

  3. Weight training : 算出loss並調整每個W

  4. Running epochs : 持續做步驟2和步驟3直到W找到最佳的參數,使正確率提高

實作

這次我們將實作XOR,挑戰上次未完成的準確率100%!!

先引入套件,一樣是我們的老朋友numpy以及可以讓數據視覺化的工具matplotlib

import matplotlib.pyplot as plt
import numpy as np

接下來宣告我們的資料

X_tr = np.array([[0,0] , [0,1] , [1,0] , [1,1]])
X_te = np.array([[0,1] , [1,1] , [0,0] , [1,0]])
Y_xor = np.array([0,1,1,0])

接下來,我們將遵循上述的向前、向後傳播的四個步驟(請參照程式內的註解)

class Perceptron:
  def __init__(self):
    self.w = None    
    self.b = None  
    def model(self,x):    

    # 用內積dot來計算w和x,回傳是否大於b
    return np.dot(self.w ,x) >= self.b
    
  def predict(self,X): 
    # 將預測的結果放進陣列
    Y = []    
    for x in X:
      result = self.model(x)
      Y.append(result)    
    return np.array(Y)
    
  def acc_score(self,y_p,y_t):
    c = 0
    for i,j in zip(y_p,y_t):
      if i == j:
        c += 1
    return (c / len(y_t))
    # or y_p
  
  def fit(self , X,Y,epochs=10,lr=1):
    # 初始化權重w -0.5 ~ 0.5 ,並宣告 X.shape[1]個 (2個)
    self.w = np.random.uniform(-1,1,X.shape[1])    
    self.b = 2
    accuracy = {}
    max_accuracy = 0
    
    # 有時候跑完整份資料集並不會讓w找到最佳參數,因此我們會多跑幾輪(epochs)
    for i in range(epochs):
      for x,y_t in zip(X,Y):
        y_p = self.model(x)
        
        # 如果答案為1,但預測為0,則提高 w
        if y_t == 1 and y_p == 0:
          print(self.w)          
          self.w = self.w + lr * x
          print(self.w)        
          
        # 反之降低 w  
        elif y_t == 0 and y_p == 1:
          print(self.w)          
          self.w = self.w - lr * x
          print(self.w)
        print('')
      
      print('第{}輪: {}'.format(i ,self.w))
  
      accuracy[i] = self.acc_score(self.predict(X),Y)      
      # 將正確率較高的w和b保存
      if (accuracy[i] > max_accuracy):
        max_accuracy = accuracy[i]
        wetw = self.w
        wetb = self.b        
        if (accuracy[i] == 1):        
          break
    self.w = wetw    
    self.b = wetb    
    
    # 視覺化數據
    plt.plot(np.array(list(accuracy.values())).astype(float))
    plt.xlabel("Epoch")
    plt.ylabel("Accuracy")
    plt.ylim([0,1])
    plt.show()
perceptron = Perceptron()
perceptron.fit(X_tr,Y_or,50,lr=0.05)

輸出

加入了W來實作,讓W找到自己的最佳數字,有沒有覺得很酷啊!

其實也可以更新b(threshold),更新條件與W一樣,只是增加與減少的關係與W相反

想更深入認識 AI . FREE Team ?

自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/

文章同步發布於:第十二屆 IT 挑戰賽部落格

(繼續閱讀下一篇教學...)