羅德興老師的教學歷程檔案 - 112-1 人工智慧 AI - 單元 1
 

企業資訊與管理系
助理教授/日導
羅德興


歷程檔案 Portfolio

    單元 1

    人工智慧 AI 與 PYTHON 實作


    [download]
    https://docs.google.com/document/d/1VEp_BQSaFoA4VgicmgPl4M2tpyrTh9wd/edit?usp=sharing&ouid=114206082813646786851&rtpof=true&sd=true





    1-2:   
    人工智慧 AI
    深度學習 Deep Learning
    類神經網路 MB


                  核心概念:

    1.      深度學習

    2.      神經網路:

            NN

            ‚CNN

            ƒRNN

    1-3:

            AI不過就是問個好問題

            

            100%機會會實現: 自動駕駛

            近期內不可能哆啦A

     

            幫我們解決我們想解決的問題

            問題化為函數:  xƒy

     

            舉例: 在野外看到一隻動物,會想知道是甚麼動物?

     

           收集問題和答案

       

     

        但我們只會有部分的解答,不會有全部的解答!! 為甚麼呢??

     

    因為如果有人再去拍一張新的圖片,那張照片不會再我們的資料庫裡面,為了避免此狀況,所以我們可以利用人工智慧進行深度學習,讓她進行良好的判斷,得到正確的答案。

    1-4

       數學建模:

                1.我們先問一個問題:

                    舉例: 在野外看到一隻動物,我想知道是甚麼?

                               描述: 一張含有 文字, 玩具, 美工圖案 的圖片

自動產生的描述

                2.化成函數的形式:

                   描述: 一張含有 文字 的圖片

自動產生的描述

                3.準備訓練資料:

            

                4.架構我們的神經網路:

                    ():

                       標準NN             …強化學習

                       ‚CNN                       †生成對抗模式(GAN)

                       ƒRNN                 ‡膠囊

                       „VAE

                    ():

                        我們架好了神經網路,就剩一些參數要調。

                                      θ = { Wi , bi }

                        決定好這些參數值,就會出現一個函數。

                                        ƒθ

                   5.學習:

                     利用我們現在造出的函數,去測試看看當輸入台灣黑熊圖片時,輸出是否也是台灣 

                     黑熊,當我們再輸入台灣藍鵲的圖片時,輸出是否也是台灣藍鵲,我們希望它離我

                     們的正確答案是越近越好,那我們怎麼測量越近越好這件事情呢?

     

                     事實上我們會用到一個函數L(θ),這個函數是用來測量我們神經網路輸出的答案和

                     正確的答案相比較距離是多少,差距越小我們就會說他學得越好,差距越大就是學

                     得不好,所以我們就希望把差距拉得越小越好,那我們要如何把差距拉得越小呢?

     

                     基本上就是用gradient descent,因神經網路的特性叫backpropagagtion

    1-5

        一、可能用AI解決的問題:

              1.舉例我想知道某支股票下個開盤日的收盤價。

                         (將我們的問題變成一個函數)

                               

                      日期X ƒ →某股票X當天的收盤價

              (雖然可以將這個問題化為函數,但是日期X”基本上和收盤價是沒有相關的,

              這樣很難預期我們的AI會有所突破,不確定AI能否幫我們把函數推導出來)

                               

                       Xt-1, Xt-2, Xt-3, Xt-4, Xt-5   ƒ → Xt

                         (因此我們可以換一個問法,換用前一週的情況來預測下一期)

     

              2.舉例我想知道某位MLB選手2018球季可以打幾支全壘打?

                      ()把前一年某位打者的所有的資料(例如:上場幾次、年齡、打了幾次全壘打等等)       

                          輸入進去。

                     
                      (
    )開始預測:

                           t-1年資料 ƒ t年全壘打數

                       (會覺得光是看一年的資料來預測會不準確,應該多看幾年才能正確判斷,

                                       這時使用”RNN”就會自動多看幾年)

                                            

                           t-1年資料 ƒ (RNN) t年全壘打數

             3.對話機器人:

                   目前的字  ƒ (RNN) 下一個字

     

             4.玩遊戲:

                   看到遊戲畫面之後→  ƒ (CNN+NN) 最好的動作

                    (可能會有很多動作都可以,我們可以換一個問法)

                                      

                        給他一個動作 + 狀態   Q  評分

                     (可見同一個問題,可以用不同方式去問這個問題)

             5.舉例: 我喜歡這個字型有缺字,我想要這個字!

               

    1-6

        AI核心技術 :

                    1.神經網路的原理 :基本概念

                     (輸入要多少個?輸出要多少個?)

              

                     2.三大神經網路:

                            標準NN (Fully Connected Neural):

                                  1980年代就火紅的model

     

                    

    Input layer (輸入層)                      ƒ(隱藏層)                      output layer(輸出層)

                         神經元(神經網路就是由很多個神經元所構成)

                   

                       (所謂的深度學習就是有三層或三層以上的隱藏層)

          (所謂建構神經網路其實就是決定我們要幾層的隱藏層,每一層隱藏層要用幾個神經元)

                   

                               (每一個神經元動作都是一樣的)

                     在數學上表示 ( 加權和 ) :

                                         


                           激活函數  ( 總刺激  +  調整值(偏執bias) ) = 輸出

                    

                                    Activation Function=激活函數

          Sigmoid = 模擬人類的神經元的樣子 : 接收總刺激很小的話=0  接收總刺激很小的話=1

          ReLU = 現在神經網路的王牌 : 小於0的時候就是0   大於0就是原本輸入的那個數字

     

     

     

                         

                         

                         

                         

    1-7

       神經網路訓練法:

               把我們的「考古題」一次次拿給神經網路學習,學習法叫backpropagation

              

               固定結構神經網路的函數空間:

                    當一個神經網路結構決定、Activation functions也決定,那可以調的就是weights,biases

                    我們把這些參數的集合叫θ,每一個θ就定義一個函數,我們把它看成一個集合

                               {Fθ}

           我們就是要找θ*,使得Fθ*和目標函數最接近

                        (最好的權重和最好的偏值)

              “最接近是甚麼意思?

      (就是”loss function”的最小值,”loss function”=測量神經網路輸出的答案和正確答案到底有差多遠)

     

           假設我們有訓練資料:

                    {(x1,y1), (x2,y2), … , (xk,yk)} 

           (當輸入值為x1 ,正確答案為y1; 當輸入值為x2 ,正確答案為y2)

             為了讓神經網路輸出的資料可以接近正確答案,需要知道距離還有多遠,

             我們最常使用loss functions :

           假設:

    X

    網路輸出

    (1)

    真正的

    (2)

    誤差

    (2)-(1)=(3)

    平方和

    (3)

    1

    2

    3

    1

    1

    2

    5

    2

    -3

    9

    3

    6

    8

    2

    4

    4

    7

    2

    -5

    25

    5

    6

    6

    0

    0

    6

    4

    8

    4

    16

    7

    8

    9

    1

    1

    總誤差

    56

               

                   知道總誤差之後再使用以下函數去調整:

                          learning rate       

                    記得L ( 網路輸出 : 調整我們的權重和偏值之後,固定一組權重和偏值就會產生函數,函數跟我們正確答案做相比,算出的距離,就會發現L的變數就是 W1, W2, b1權重和偏值)W1, W2, b1,…...的函數。

                  但因為變數實在是太多了,為了簡化,我們先把L想成只有一個變數W

                                    

                                    

                                     

                      
                     

                       

                                 

                                 

                                 

                                 

                                 

                                 

                                 

     

     

                                  

    1-8

       梯度下降法 :

                  例子 :

                        L(w1, w2, b1)=( b1+2w1-w2-3)2

                    假設這時我們在:

                        w1=1 , w2 =-1, b1 = 2

               一樣往(局部)極小移動。

                   假設只有一個變數w1:

                           Lw1(w1) = ( w1 ,-1,2) = 4w12

                     假設只有一個變數w2:

                   Lw2(w2) = ( 1 , w2,2) = (-w2+1)2

                   假設只有一個變數b1:

                   Lb1(b1) = L( 1 , -1 , b1) =

                         於是我們又會調整w1 , w2 , b,L慢慢走向(局部)極小 :

          W1W1       W2W2

                    b1b1

            

             偏微分:

                 我們有L (w1, w2, b1)這三個變數的函數,當我們只把w1當變數,

                 其他w2, b1當常數微分 :

                                        

                            同理我們只把w2當變數 :

                                         

                同理我們只把b1當變數 :

                                         

             梯度(gradient):

                          函數Lgradient就變成:

                               

     

                          也可以這樣顯示:

                                 =

                          我們調整w1, w2, b1的方法就變成:

                                         -

                      這學習方法就叫做 Gradient Descent ( 梯度下降 )


    程式範例:第一支 手寫文字識別 類神經網路 (NN) 程式
    (download)
    (LINK)

    # 1. 讀入套件
    # 這裡我們讀入一些套件, 今天暫時不要理會細節。

    %matplotlib inline

    # 標準數據分析、畫圖套件
    import numpy as np
    import matplotlib.pyplot as plt

    # 神經網路方面
    from tensorflow.keras.datasets import mnist
    from tensorflow.keras.utils import to_categorical
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense
    from tensorflow.keras.optimizers import SGD

    # 互動設計用
    from ipywidgets import interact_manual
    # 2. 讀入 MNIST 數據庫
    '''
    MNIST 是有一堆 0-9 的手寫數字圖庫。
    有 6 萬筆訓練資料, 1 萬筆測試資料。
    它是 "Modified" 版的 NIST 數據庫, 
    原來的版本有更多資料。
    這個 Modified 的版本是由 LeCun, Cortes, 及 Burges 等人做的。
    可以參考這個數據庫的原始網頁。

    MNIST 可以說是 Deep Learning 最有名的範例, 
    它被 Deep Learning 大師 Hinton 稱為「機器學習的果蠅」。

    2.1 由 Keras 讀入 MNIST
    Keras 很貼心的幫我們準備好 MNIST 數據庫, 
    我們可以這樣讀進來 (第一次要花點時間)。
    '''

    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    # Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
    11493376/11490434
    # 我們來看看訓練資料是不是 6 萬筆、測試資料是不是有 1 筆。

    print(f'訓練資料總筆數為 {len(x_train)} 筆資料')
    print(f'測試資料總筆數為 {len(x_test)} 筆資料')

    '''
    2.2 數據庫的內容
    每筆輸入 (x) 就是一個手寫的 0-9 中一個數字的圖檔, 
    大小為 28x28。而輸出 (y) 當然就是「正確答案」。
    我們來看看編訓練資料的 x 輸入、輸出的部份分別長什麼樣子。
    '''

    def show_xy(n=0):
        ax = plt.gca()
        X = x_train[n]
        plt.xticks([], [])
        plt.yticks([], [])
        plt.imshow(X, cmap = 'Greys')
        print(f'本資料 y 給定的答案為: {y_train[n]}')
    interact_manual(show_xy, n=(0,59999));
    def show_data(n = 100):
        X = x_train[n]
        print(X)
    interact_manual(show_data, n=(0,59999));

    '''
    2.3 輸入格式整理
    我們現在要用標準神經網路學學手寫辨識。
    原來的每筆數據是個 28x28 的矩陣 (array), 
    但標準神經網路只吃「平平的」, 
    也就是每次要 28x28=784 長的向量。
    因此我們要用 reshape 調校一下。
    '''

    x_train = x_train.reshape(60000784)/255
    x_test = x_test.reshape(10000784)/255

    # 2.4 輸出格式整理¶
    '''
    我們可能會想, 我們想學的函數是這樣的型式:

    f^:R784→R
    其實這樣不太好! 為什麼呢? 比如說我們的輸入 x 是一張 0 的圖, 因為我們訓練的神經網路總會有點誤差, 所以可能會得到:

    f^(x)=0.5
    那這意思是有可能是 0, 也有可能是 1 嗎!!?? 可是 0 和 1 根本不像啊。換句話說分類的問題這樣做其實不合理!

    於是我們會做 "1-hot enconding", 也就是

    1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0]
    5 -> [0, 0, 0, 0, 0, 1, 0, 0, 0]
    等等。因為分類問題基本上都要做這件事, Keras 其實已幫我們準備好套件!
    '''
    y_train = to_categorical(y_train, 10)
    y_test = to_categorical(y_test, 10)

    # 我們來看看剛剛某號數據的答案。

    n = 87
    y_train[n]
    # array([0., 0., 0., 0., 0., 0., 0., 0., 0., 1.], dtype=float32)

    # 和我們想的一樣! 至此我們可以打造我們的神經網路了。

    '''
    3. 打造第一個神經網路
    我們決定了我們的函數是

    f^:R784→R10
    這個樣子。而我們又說第一次要用標準神網路試試, 所以我們只需要再決定要幾個隱藏層、每層要幾個神經元, 用哪個激發函數就可以了。

    3.1 決定神經網路架構、讀入相關套件
    假如我們要用 ReLU 當激發函數, 要設計神經網路, 只差要指定多少個隱藏層、每層多少個神經元就好了!

    設計完了基本上就是告訴 TensorFlow, 我們的想法就可以了!
    '''
    #@title 設計你的神經網路
    隱藏層數 = 3 #@param{type:"integer"}
    神經元1 = 0 #@param{type:"integer"}
    神經元2 = 0 #@param{type:"integer"}
    神經元3 = 0 #@param{type:"integer"}

    '''
    3.2 建構我們的神經網路
    和以前做迴歸或機器學習一樣, 我們就打開個「函數學習機」。標準一層一層傳遞的神經網路叫 Sequential, 於是我們打開一個空的神經網路。
    '''
    model = Sequential()

    '''
    我們每次用 add 去加一層, 從第一個隱藏層開始。
    而第一個隱藏層因為 TensorFlow 
    當然猜不到輸入有 784 個 features, 
    所以我們要告訴它。
    '''

    model.add(Dense(20, input_dim=784, activation='relu'))

    # 第二層開始就不用再說明輸入神經元個數
    # (因為就是前一層神經元數)。

    model.add(Dense(20, activation='relu'))
    model.add(Dense(20, activation='relu'))

    '''
    輸出有 10 個數字, 所以輸出層的神經元是 10 個! 而如果我們的網路輸出是

    (y1,y2,…,y10)
    我們還希望

    ∑i=110yi=1
    這可能嗎, 結果是很容易, 就用 softmax 當激發函數就可以!!
    '''
    model.add(Dense(10, activation='softmax'))

    '''
    至此我們的第一個神經網路就建好了!

    3.3 組裝
    和之前比較不一樣的是我們還要做 compile 才正式把我們的神經網路建好。你可以發現我們還需要做幾件事:

    決定使用的 loss function, 一般是 mse
    決定 optimizer, 我們用標準的 SGD
    設 learning rate
    為了一邊訓練一邊看到結果, 我們加設

    metrics=['accuracy']

    本行基本上和我們的神經網路功能沒有什麼關係。
    '''
    model.compile(loss='mse', optimizer=SGD(learning_rate=0.087), metrics=['accuracy'])

    '''
    4. 檢視我們的神經網路
    我們可以檢視我們神經網路的架構, 可以確認一下是不是和我們想像的一樣。

    4.1 看 model 的 summary
    '''

    model.summary()

    '''
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    dense (Dense)                (None, 20)                15700     
    _________________________________________________________________
    dense_1 (Dense)              (None, 20)                420       
    _________________________________________________________________
    dense_2 (Dense)              (None, 20)                420       
    _________________________________________________________________
    dense_3 (Dense)              (None, 10)                210       
    =================================================================
    Total params: 16,750
    Trainable params: 16,750
    Non-trainable params: 0
    _________________________________________________________________
    很快算算參數數目和我們想像是否是一樣的!
    '''

    '''
    5. 訓練你的第一個神經網路
    恭喜! 我們完成了第一個神經網路。現在要訓練的時候, 你會發現不是像以前沒頭沒腦把訓練資料送進去就好。這裡我們還有兩件事要決定:

    一次要訓練幾筆資料 (batch_size), 我們就 100 筆調一次參數好了
    這 6 萬筆資料一共要訓練幾次 (epochs), 我們訓練個 10 次試試
    於是最精彩的就來了。你要有等待的心理準備...

    '''
    model.fit(x_train, y_train, batch_size=100, epochs=10)

    '''
    Epoch 1/10
    600/600 [==============================] - 4s 2ms/step - loss: 0.0892 - accuracy: 0.1038
    Epoch 2/10
    600/600 [==============================] - 1s 2ms/step - loss: 0.0855 - accuracy: 0.1593
    Epoch 3/10
    600/600 [==============================] - 1s 2ms/step - loss: 0.0808 - accuracy: 0.3638
    ......
    <tensorflow.python.keras.callbacks.History at 0x7ff210050a50>
    '''

    '''
    6. 試用我們的結果
    我們來用比較炫的方式來看看可愛的神經網路學習成果。對指令有問題可以參考《少年Py的大冒險:成為Python數據分析達人的第一門課》。
    '''
    loss, acc = model.evaluate(x_test, y_test)

    '''
    313/313 [==============================] - 1s 2ms/step - loss: 0.0150 - accuracy: 0.9029
    '''

    print(f"測試資料正確率 {acc*100:.2f}%")


    # 測試資料正確率 90.29%

    from ipywidgets import interact_manual

    # 我們 "predict" 放的是我們神經網路的學習結果。做完之後用 argmax 找到數值最大的那一項。

    predict = np.argmax(model.predict(x_test), axis=-1)
    predict
    # array([7, 2, 1, ..., 4, 8, 6])
    # 不要忘了我們的 x_test 每筆資料已經換成 784 維的向量, 我們要整型回 28x28 的矩陣才能當成圖形顯示出來!

    def test(測試編號):
        plt.imshow(x_test[測試編號].reshape(28,28), cmap='Greys')
        print('神經網路判斷為:', predict[測試編號])
    test(87)
    # 神經網路判斷為: 5

    interact_manual(test, 測試編號=(09999));

    # 到底測試資料總的狀況如何呢? 我們可以給我們神經網路「總評量」。

    score = model.evaluate(x_test, y_test)
    # 313/313 [==============================] - 1s 2ms/step - loss: 0.0150 - accuracy: 0.9029
    print('loss:', score[0])
    print('正確率', score[1])

    '''
    loss: 0.015002136118710041
    正確率 0.902899980545044

    7. 用 Gradio 來展示
    '''
    print ('展示機器學習成果...... \n')
    !pip install gradio

    '''
    pip is a command tool.
    輕鬆展示機器學習成果
    14.1 gradio模組:神奇網頁互動界面
    14.2 gradio使用現有機器學習模型
    14.3 gradio使用自己訓練的模型

    '''

    '''Collecting gradio
      Downloading https://files.pythonhosted.org/packages/c4/c7/0606fd431bd963ba704d8f71b7404ef778236d6f7f7981a36157ba68e6c5/gradio-2.0.10-py3-none-any.whl (2.4MB)
         |████████████████████████████████| 2.4MB 25.4MB/s 
    ......     
    '''

    import gradio as gr
    def recognize_digit(img):
      img = img.reshape(1,784)
      prediction = model.predict(img).flatten()
      labels = list('0123456789')
      return {labels[i]: float(prediction[i]) for i in range(10)}

    gr.Interface(fn=recognize_digit, inputs="sketchpad", outputs="label").launch()

    '''
    Colab notebook detected. To show errors in colab notebook, set `debug=True` in `launch()`
    This share link will expire in 24 hours. If you need a permanent link, visit: https://gradio.app/introducing-hosted (NEW!)
    Running on External URL: https://32792.gradio.app
    Interface loading below...
    '''

     
    全部共 0則留言
    登入帳號密碼代表遵守學術網路規範


    文章分類 Labels


    最新文章 Top10

    中華科技大學數位化學習歷程 - 意見反應