羅德興老師的教學歷程檔案 - 112-1 人工智慧 AI - 單元 1 |
|
|
單元 1人工智慧 AI 與 PYTHON 實作[download] https://docs.google.com/document/d/1VEp_BQSaFoA4VgicmgPl4M2tpyrTh9wd/edit?usp=sharing&ouid=114206082813646786851&rtpof=true&sd=true 1-2: 核心概念: 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(輸出層) 神經元(神經網路就是由很多個神經元所構成) (所謂的深度學習就是有三層或三層以上的隱藏層) (所謂建構神經網路其實就是決定我們要幾層的隱藏層,每一層隱藏層要用幾個神經元) (每一個神經元動作都是一樣的) 在數學上表示 ( 加權和 ) : (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 : 假設:
知道總誤差之後再使用以下函數去調整: 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 , b1 ,讓L慢慢走向(局部)極小 : W1←W1 W2←W2 b1←b1 偏微分: 我們有L (w1, w2, b1)這三個變數的函數,當我們只把w1當變數, 其他w2, b1當常數微分 : 同理我們只把w2當變數 : 同理我們只把b1當變數 : 梯度(gradient): 函數L的gradient就變成:
也可以這樣顯示: = 我們調整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(60000, 784)/255 x_test = x_test.reshape(10000, 784)/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, 測試編號=(0, 9999)); # 到底測試資料總的狀況如何呢? 我們可以給我們神經網路「總評量」。 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... '''
|
|
中華科技大學數位化學習歷程 - 意見反應 |