神經網路

210922上課內容

tags: 自己加油

Keras 包含在tensorflow中,是使用python的工具

深度學習(Deep Learning)(DL)與神經網路(Neural Network)(NN)是指一樣的東西,只是因為歷史淵源而有不同的名稱。
DL是人工智慧(AI),影像辨識的基礎
常見的DL架構有:

  1. 多層感知器MLP(Multilayer Perceptron)
  2. 深度神經網路DNN(Deep Neural Network)
  3. 卷積神經網路CNN(Convolutional Neural Network)、
  4. 遞迴神經網路RNN(Recurrent Neural Network)。

其中,人工智慧(Artificial Intelligence)、機器學習(Machine Learning)、深度學習(DL)的相關關係如下:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

神經網路大概的結構如下圖

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

點稱為"神經元",每個點會有"權重"(weight),也會有偏移值(bies),大致分為三層,Input、Hidden、Output,其中隱藏層在外界是看不到的,每層的每個點必須"完全連結"。而這就是最基礎的DNN深層神經網路

每個input點X會乘上weight,再加上bies,就能得到output點Y

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

筆者補充
DL的相關資訊:
Algorithm(NN、MLP,CNN)#CNN是目前最主要的
Package(tensorflow、Keras)
Language(Python、C++)

建立一個簡單的模型

from tensorflow.keras import models from tensorflow.keras import layers #先建立一個空模型 #Sequential是串列的模型 model_01 = models.Sequential() #4個隱藏的神經元 #啟動函數relu #input個數3 #input dimation3 model_01.add(layers.Dense(units=4,activation='relu',input_dim=3)) model_01.add(layers.Dense(1,activation="sigmoid")) model_01.summary()

圖片有兩種解析度,單位為pixel
色彩,空間
色彩可以用RGB、gray等等

若要把一張150*150的圖形,放進CNN,則每個點都要進input


210929上課內容

上課是用兩個檔案:ch02_002b_csv.ipynb、carats.csv

ML的訓練資料由features與label組成
並且分為三種學習方式
監督式學習
非監督式學習
增強式學習

ML
監督式學習
分類
二元分類
多元分類
回歸分析
非監督式學習
分群
強化學習
Q-learning
#Temporal Difference的一種

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

DL可以回答五種問題:

  1. Is this A or B?

  2. Is this weird?

  3. How much/how many?

  4. How is it organized?

  5. What should I do next?


以下有三個範例:(PPT40-51)

DL範例一

二元分類
對輸入的資料找到合適的表達方法

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

此圖需要找到適合表達黑點白點的XY軸
對於本來定義的XY軸來說,黑白點是沒有對應區域關係的

  1. Raw data

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

  2. Coordinate change

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

程式分析黑白點的關係,得到具效果的新軸X'Y'

  1. Better representation
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

再把圖形翻轉,得到新的圖形
而本圖形可以用(x,y)的方式來表達黑白點的關係

" In this case, we defined the coordinate
change by hand. But if instead we tried
systematically searching for different
possible coordinate changes, and used as
feedback the percentage of points being
correctly classified, then we would be doing
machine learning. "
" Learning, in the context of machine
learning, describes an automatic search
process for better representations. "

DL範例二

Linear Regression
目標1:從所有輸入資料點鐘找到最佳的model
目標2:給定X值,用找到的model,預測Y值

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

此範例中,輸入資料點是藍色點,要找的是紅線(model),公式為y=ax+c

為找出model,我們需要知道:

  1. 什麼是最好(評估方式/損失函數)
  2. 如何朝最好的方向改進(最佳化)
    以上兩點就是機器學習ML

接下來就來看一個此種範例的實例
用鑽石的carats跟price來得到趨勢圖

# -*- coding: utf-8 -*- """ ch02_002b_csv.py 2021.09.11 @author: jack huang """ #簡單讀取 *.csv 檔案資料 #從硬碟中讀取 carats.csv 至Python成為一個 Pandas DataFrame 物件 #step 0: 檢視 'carats.csv' # !dir carats.csv / !type carats.csv #for windows # !ls carats.csv / !cat carats.csv #for mac # *.csv 仍然是一個文字檔,格式化的文字檔 #======================================= #step 1: import 需要的套件 import pandas as pd #import pandas #step 2: 使用 pd.read_csv() 讀取csv檔成為DataFrame物件 df1=pd.read_csv('carats.csv') #pd.read_csv() 預設第一行資料是抬頭(欄位名稱)而不是資料 #step 3: 檢視DataFrame 'df1' df1 df1.head(5) #檢視前5筆資料 df1.tail(5) #檢視最後5筆資料 #step4 :裁取 df1的craats欄位--> 成為 Series df1.carats # or df1['carats'] #練習:裁取 price 欄位 #============================================================= #簡單的「探索式資料分析」(Exploratory Data Analysis, EDA) #資料關聯性探索:了解資料背後的故事、了解資料並進而找出資料趨勢的線索, #也就是資料間的關聯性(Relationship)。 #實務上,我們使用下列方法找出資料間的線性關係(Linear Relationship)(兩個變數間趨勢) #1.散佈圖(Scatter) #2.共變異數(Covariance) #3.相關係數(Correlation Coefficient) #以pandas DataFrame/Series 實作 #correlation and covariance (相關係數及共變異數),corr() / cov() method #pandas.Series.corr() method : http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.corr.html #Series.corr(other, method='pearson', min_periods=None) #Compute correlation with other Series, excluding missing value X=df1.carats #Series Object 'X' y=df1.price #Series Object 'y' #1.散佈圖(Scatter) #以鑽石重量(s_carats)及價格資料(y) 繪製散佈圖檢視兩變數間關係 import matplotlib.pyplot as plt #import 繪圖套件 #以plt.scatter()繪製散佈圖 #magic command %matplotlib plt.scatter(X,y,marker='o',alpha=0.5,s=100,edgecolors='k') #plt.scatter的引數有很多可以設定,參考下面這篇 #https://www.itread01.com/content/1546796009.html plt.grid(True) #格線 plt.title("carats-price") #標題 plt.xlabel("weight (carats)") #x軸標籤 plt.ylabel("price") #y軸標籤 plt.legend(loc=0) #圖例位置, loc=0 (best) #2. Covariance共變異數, Series.cov() method #兩個變數傾向於表現出相似的行為,共變異數為正。 X.cov(y) #df1.carats --> df1.price, 2724.85>0 正相關 #3. Correlation相關性 Coefficient, Series.corr() #當隨機變數間呈現同一方向的變化趨勢時稱為正相關,反之則稱為負相關。 #在數學上的圖形,就是看斜率是否差不多 X.corr(y) #df1.corats --> df1.price, 0.965 (絕對值需要小於1) #當兩個變數的線性關係增強時,相關係數趨於1或-1 #======================================================== #因為自變數 X (df1.carats) 與因變數 y (df1.price) 有很強的 #正相關性 Correlation Coefficient=0.965, 所以雖然資料量很少 #我們還是試著以現有資料塑模(modeling)。 #我們使用Ordinary Least Squares, OLS (https://scikit-learn.org/stable/modules/linear_model.html) #塑模: from sklearn.linear_model import LinearRegression reg=LinearRegression() #modeling #線性迴歸 #least squares method 最小平方法 #大家想學這種東西的話可以讀線性代數,有我可以問 #改變資料維度 (1D-->2D) #本來是點,現在變成線 X2d=X.values.reshape(-1,1) y2d=y.values.reshape(-1,1) reg=reg.fit(X2d,y2d) #fit / train model #訓練好的模型(公式 y=cX+b)係數: 斜率(c), 截距(b) c=reg.coef_[0][0] b=reg.intercept_[0] #我們把模型(線)畫出來 import numpy as np mX=np.linspace(0.25, 2.5, 100) my=mX*c+b plt.scatter(mX,my) #預測: 以此模型迴歸預測 0.86 carat 鑽石的價格 py=reg.predict([[0.86]]) #畫出此預測點 plt.scatter([0.86],py[0],marker='^',s=200,edgecolors='k')

成果圖片

X軸是自變數,代表carats
Y軸是應變數,代表price

老師的程式架構是

  1. 先把XY訂出
    X=df1.carats #Series Object 'X'
    y=df1.price #Series Object 'y'

  2. 畫出第一張圖

  3. 讓點變成線
    增加維度用-1
    X2d=X.values.reshape(-1,1) #向右增加維度
    y2d=y.values.reshape(-1,1)
    #reshape(1,-1) 向左增加斜率

  4. 還要設定線的斜率©, 截距(b),來符合公式 y=cX+b
    c=reg.coef_[0][0]
    b=reg.intercept_[0]

  5. 預測特定carat的price
    意即特定X的Y
    py=reg.predict([[0.86]])
    //0.86是X,也可以是其他數字
    plt.scatter([0.86],py[0],marker='^',s=200,edgecolors='k')
    //得到結果

211006上課內容

AI的核心是ML,ML當紅的演算法DL或NN
ML可分傳統與DL

AI
ML
傳統
正規化
#迴歸
整合DT
Decision Tree
RF
Random Forest
XGB
Extreme Gradient Boosting
LGBM
Light Gradient Boosting Machine
DL
NN
CNN
DNN

Tensor

是處理data的基礎

例如
[20,30] > 維度(2,1)
[[20,30]] >維度(1,2)

筆者補充

Tensor

簡單來說是一個多維度數組(multidimensional array)
在處理data的時候,可以把數據整理成tensor
例如在BGR中,可以把三層的數據整理成3-d tensor

Tensor 有三種屬性

  1. rank:number of dimensions
  2. shape: number of rows and columns
  3. type: data type of tensor's elements
    我們常常看到的數據形狀如:

參考
笔记 | 什么是张量(tensor)& 深度学习
【深度学习-2】TensorFlow基础(一): tensor and operation

在Linear Regression 中,NN的訓練是經過很多次的調整誤差而出來的,這個調整的過程稱為

Learning Rate

一次的圖形要修正多大

過大:無法收斂,圖形一直擺盪(overshoot)
過小:看不出差別,學習很慢
都無法得到最佳函數
第一個圖形是隨機的,之後再調整誤差,接近答案
以下有幾個動畫來更清楚表達learning rate的重要

  1. LR=0.01

因為LR過小,接近答案的速度很慢

  1. LR=0.1

LR較為適中,接近答案很快而且沒有overshoot

  1. LR=0.9

LR偏快,接近答案的過程中出現overshoot

  1. LR=1

LR過快,無法收斂得到答案

參考
機器/深度學習-基礎數學(二):梯度下降法(gradient descent)

筆者補充

Backpropagation(誤差反向傳播)

利用輸出值與答案間的誤差,調整NN
目標是藉由誤差來調整每一個神經元的權重

調整流程如下圖

微分
得到變化率
調整weight
調整output
誤差縮小

參考
DNN(深度神經網路)的全面認識

Learning rate 舉例

做NN的流程

one-hot-encoding(預處理)
舉例
字串無法計算,必須變成數值

先知道要用哪個NN,(知道weight 跟誤差)
ACC AUC RMES >評價的指標
可以參考此文章 機器學習評價指標
模型評定不一定只有準確度:

  1. An optimizer.(設定訓練時的優化方法, 如adam)
  2. A loss function.(設定損失函數, 如 cross_entropy)
  3. A list of metrics.(設定評估模型的方式, 如 accuracy)

筆者補充

機器學習評價指標

有四種分類:

  1. TP:正例預測正確的個數
  2. FP:負例預測錯誤的個數
  3. TN:負例預測正確的個數
  4. FN:正例預測錯誤的個數

ACC是準確率(accuracy)

精確率(precision) 描述的是在所有預測出來的正例中有多少是真的正例

召回率(recall) ,描述的是所有正例我能發現多少

F1值——精確率和召回率的調和均值

參考
機器學習評價指標

筆者補充

學習優化器(Optimizer)

  1. SGD-準確率梯度下降法 (stochastic gradient decent)

找出參數的梯度(利用微分的方法),往梯度的方向去更新參數(weight)

W 為權重(weight)參數,L 為損失函數(loss function), η 是學習率(learning rate), ∂L/∂W 是損失函數對參數的梯度(微分)
Learning Rate為固定值

  1. Momentum

此優化器為模擬物理動量的概念,在同方向的維度上學習速度會變快,方向改變的時候學習速度會變慢

Vt 的參數,可以將他想像成「方向速度」,會跟上一次的更新有關
Learning Rate為固定值

  1. AdaGrad

會依照梯度去調整 learning rate η 的優化器

前期梯度較小的時候,n較小,能夠放大學習率
後期梯度較大的時候,n較大,能夠約束學習率

  1. Adam

可以說就是把Momentum 跟 AdaGrad這二種Optimizer做結合
有做參數的”偏離校正”,使得每一次的學習率都會有個確定的範圍,會讓參數的更新較為平穩
保留了 Momentum 對過去梯度的方向做梯度速度調整,與Adam對過去梯度的平方值做learning rate的調整

參考
[機器學習ML NOTE]SGD, Momentum, AdaGrad, Adam Optimizer

算出的y(label)是機率分布

NN需要做前處理,此範例中每個px的值是0-255
但需要標準化為[0.0-1.0]之間,全部除以255

看過這些基礎知識後,接下來進入第三個範例

DL範例三

用NN做手寫字辨識

目標:分析圖形是甚麼數字
此例中的數據數量:
train :60000
test :10000
train 再切成訓練跟驗證兩種
如果test的資料放到train裡面 >資料洩漏

程式碼是把train切成20%驗證80%訓練
驗證完再對比test中的1000筆資料

要分析pixal > tensor
tensor可以用色彩解析度來做
在此範例中的色彩解析度是用Gray的0-255

每張圖有一個x = images(數字影像)
一個y = labels(真實數字)

公式y=xw+b
w=Weight vector
b=intercept

實例範例

把一個圖片分解成矩陣,影像解析度是28 * 28
粉紅表示是白色的
藍色表示是用灰階來記錄黑色

(x=x_train_normalize,          #feature (X) 數字影像標準化值
            y=y_Train_OneHot,validation_split=0.2, #lebel (y) One-Hot encoding 值
            epochs=10,batch_size=200,verbose=2)   #epochs, 訓練週期為 10

此段程式中的輸入神經元是28 *28 個
輸出神經元是多元分類,有十個,數字0-9
如果是二元分類,則output只有一個神經元,可以用數值大於或小於定值來判斷y

公式y=xw+b中的權重先隨機給(可以用別人訓練好的)

把input(x)展平成多個Neurons

#tf.keras.layers.Flatten(), 將輸入展平為1維,對應神經網路輸入層神經元個數 28x28=784
#tf.keras.layers.Dense(), 完全連結函數
#tf.nn.relu, relu 啟動函數
#tf.nn.softmax, softmax 啟動函數

#檢查model是否建好
#model.summary()

Keras建模有兩種

Sequential Model

  1. 可以理解爲堆疊,通過堆疊許多層,構建出深度神經網絡
  2. 可以構建非常複雜的神經網絡,包括全連接神經網絡、卷積神經網絡(CNN)、循環神經網絡(RNN)等等
  3. 建立的模型只能是單輸入單輸出的模型
  4. Sequential模型的核心操作是添加layers(圖層),例如:

卷積層
最大池化層
全連接層
dropout
Flattening layer(展平層)

操作流程如下

參考理解keras中的sequential模型

Functional API Model

可以建立單輸入單輸出、多輸入單輸出、單輸入多輸出、多輸入多輸出的模型
結構可以有分叉,適合複雜的模型建立

參考Day 06:Keras 模型結構

結論

如果是一層層順序執行的簡單模型,就使用Sequential model
反之,就使用Functional API model

211013上課內容

神經網路的數學基礎

  1. tensor
  2. 張量
  3. 梯度下降

NN一開始是想要使用模擬人類的方式來做資料間的連接
看下圖可以知道:

  1. input Neurons * weight
    w = {w1,w2,w3,}
    input x = {x1,x2,x3,}
    NN的運算是 {x1,x2,x3,} * {w1,w2,w3,}兩矩陣相乘

  1. 連結線的粗細代表不同的bias
  2. 一般完全連接層,會假設input是無結構的

做影像辨識的資料比較單調,只有pixel一種特徵

  1. 可以從圖中看到有"啟動函數"A
    則公式可以加入A,變成 y = A(Σwx)

  2. 每個Neurons有偏好值bias
    則可以加入bias,變成 y = A(Σwx+b)

根據以上可以得到完整公式
y = A(Σwx+b)

筆者補充

CNN的分層

1.卷積層 (Convolution layer)
2.池化層 (Pooling layer)
3.全連接層 (Fully Connected layer)


  1. Convolution layer

1.由許多不同的 kernel 在輸入圖片上進行卷積運算
2.步驟是:滑動 + 內積,利用 filter 在輸入圖片上滑動並且持續進行矩陣內積


  1. 3X3矩陣稱為kernal、filter
  2. 得到的圖片稱為feature map
  1. Pooling layer
  1. 當我們在做圖片的特徵萃取的過程中,圖形的縮放應該不會影響到我們的目的
  2. 經由這樣的 scaling 我們可以再一次的減少神經網路的參數。
  3. 常用的 pooling 方式有 Max pooling 與 Average pooling
  4. kernal 的滑動不會互相覆蓋
  5. 運算會是取max或average(max的效果比較好)
  1. Fully Connected layer
  1. 把我們經過數個卷積、池化後的結果進行分類
  2. 注意全連接層會破壞圖片的空間結構
    但經過數個池化層後,每個節點都能包含空間結構的資訊在裡面,這個時候進行全連接層的分類就不會有破壞空間結構的問題

卷積層的特點

  1. 每一層卷積層的 filter 不會只有一個

下圖是經過很多filter來得到結果的NN

  1. 彩色的圖片同時會有 RGB 三個 channel

三個channel展開後會是這樣:

  1. 經過卷積層過後的 feature map 會變得比原尺寸小

可以使用 padding 的方法 ( 於輸入圖片的周圍補上一圈 0 ),來避免 feature map 縮小的狀況

  1. filter 滑動的步伐 (Stride) 不一定必須是 1

滑動的步伐加大,那麼出來的 feature map 尺寸會相對縮得更小
下圖是stride為2的狀況

  1. 提高 Receptive Field

Receptive field (中文譯為區域性感受野)指的是我們在 feature map 中的一個像素內能看到輸入圖像區域

  1. 可以保留圖片中的空間結構,並從這樣的結構中萃取出特徵
  2. 利用權重共享的方式減少參數

意即我們使用同一個kernal來做滑動,所以權重不變

池化層的特點

  1. 藉由對輸入圖片的 subsampling 來減少參數,減少計算成本
  2. 具有特徵不變性

下方舉例,pooling後的圖形特徵是一樣的

  1. 提高 Receptive Field

參考卷積神經網路 (Convolutional Neural , CNN)

啟動函數activation function

如果Input是一元,啟動函數可以用:

  1. Sigmoid activation function (Logistic Function)
  2. Relu activation function (Rectified Linear Unit)

sigmoid x range from -unlimit to unlimit
y range from 0 to 1

relu from 0 to x

如果Input是多元,啟動函數可以用:

  1. softmax

  2. maxout

所有隱藏層都是使用同一個activation function

筆者補充
activation function
簡單來說是x經過f(x)換算,得到一個非線性的結果
f(x)會是relu或是sigmoid

Layer

ML -> DL -> NN -> neuron + layer
layer 之間必定完全連結
屬於同一層的神經元之間沒有任何連接
有幾層及每一層有幾個神經元是依待解決的問題來決定。
其他種神經模型可以參考:
AI 入門必備懶人包:圖解 27 種神經模型,讓你秒懂差在哪

接下來實作layer

使用tensorflow
keras包含所有相關的套件,例如tensorflow

呼叫keras 建模 (上面有補充)

  1. sequential

一層一層疊上來

  1. API

把函數當作參數做傳遞
call ack

from tensorflow.keras import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Flatten #dense類別 #要完全連結 model_test = Sequential() #模型名稱model_test #用Sequential 架設一個空的底座模型 #疊第一層 model_test.add(Flatten(input_shape = (4,))) #input layer = 4 #這裡應該用平展層flatten model_test.add(Dense(units=3,activation='relu')) #三個隱藏層 #此處需要activation function #使用relu #使用緊密層 #輸出層 model_test.add(Dense(units=1,activation='sigmoid')) #output neuron = 1 model_test.summary() #展示建好的model

最後的輸出

決定各層的維度與數量

  1. 輸入層的維度是一維flatten

一開始的值是隨機
或用其他人訓練的模型

  1. 隱藏層的維度是超參數 hyperparameters >執行後才知道
  2. 輸出層的數量是看自身問題 >二元分類或多元分類

二元分類使用sigmod函數,判斷在圖形的那個部分
多元分布使用高斯分布或其他函數圖形
softmax

如圖,可以用不斷修正來得到最佳的weight 跟 bias
全部都是最佳的時候,就能得到最佳的結果

成本函數

評估目標跟得到的結果的差距
分類交叉墒

最佳化函數optimizer

評估成本函數跟結果的差距
目標是越來越小
讓成本函數優化的演算法稱為最佳化演算法
例如梯度下降

Machine Learning 就是學習出最佳的權重(weight,bias)

Neural Network的三個特徵

  1. 架構

neurons 之間的連接方式
前饋式MLP
遞迴式DNN
單層CNN
多層RNN

  1. 學習過程

back-propagation
energy level
目標是求出最佳的Weight 、 bias

  1. 啟動函數

甚麼情況下neuron 會被啟動
用何種輸出傳遞給下一個neuron
讓hidden layer可以用非線性的方式工作

功課

211020 上課進度

batch-size

每丟幾個資料,做反向傳播

筆者補充
batch-size
代表抽樣的數目、樣本數大小(size, number)
透過batch從訓練目標中取樣,來加快ML模型訓練的速度。(此參數在訓練前設定,為hyper-parameter)
最佳值是「因題目而異」的
通常batch sizes會介於10~1000個樣本之間

參考
【Day 23】 Google ML - Lesson 9 - 加速ML模型訓練的兩大方法(如何設定batch/檢查loss頻率)、batch size, iteration, epoch的概念和比較

筆者補充

前向傳播

最基礎的深度學習模型會有輸入層、隱藏層與輸出層至少三層的深度,透過各層之間的單位相連接,可以得到由權重矩陣 W 與誤差矩陣 B 所組成的係數,這組係數經過訓練之後,可以將輸入的特徵矩陣 X 映射為目標矩陣 Y^。每層都是由啟動函式、前一層的輸出、當層的權重矩陣與誤差矩陣結合,然後成為下一層的輸入。

反向傳播

深度學習模型完成一次前向傳播,特徵矩陣 X 就會依賴當下的權重矩陣 W(i) 和誤差矩陣 B(i) 跟隨著結構由輸入層、隱藏層移動到輸出層成為 y^,這時就能夠計算 y 與 y^ 之間的誤差量值

裡面有很多數學,有興趣研究的可以參考
新手村逃脫!初心者的 Python 機器學習攻略 1.0.0 documentation

當用到的模型,輸入層樣本數不符合自己需求
例如需要樣本數是1000,但自己只有28 * 28 個Input
可以縮放(resize)圖片來滿足模型輸入層

Keras dataset

收錄一些有名的資料集
Keras dataset

epoch
輪、代


Param 參數
200960 = w * x + b= 784 * 256 +256
input 沒有bias
2570 = 要訓練的個數 = 256 * 10

目標

  1. 建立模型
  2. 完成模型訓練
  3. 評估模型的準確率
#節錄自老師的範例ch07_901_MLP_.ipynb, 2021.09.20
#1.以tf.keras建立 DNN模型
#2.訓練模型、評估模型準確率
#3.以訓練完成的模型辨識 MNIST 手寫數字
#step1 讀取並預處理資料
#tf2.x 中 tf.keras module 只需處理 mnist 中feature值(minmax)
#無需處理 label (onehot encoding), model 會自行處理
#但為說明分類交叉墒,我們還是自行處理 onehot encoding

#step1.1 匯入所需模組
import tensorflow as tf
import numpy as np

#step1.2 從tf.keras.dataset 讀取 mnist 
mnist = tf.keras.datasets.mnist

#step1.2.1 以mnist.load_data() method 讀取資料,(train/test)
(x_train_image,y_train_label),(x_test_image,y_test_label)=mnist.load_data()

#檢視資料
#x_train_image.shape#有六萬張圖
#x_train_image[0]
y_train_label[0]#5

print('x_train_image.shape :',x_train_image.shape)
print('y_train_label.shape :',y_train_label.shape)
print('x_test_image.shape :',x_test_image.shape)
print('y_test_label.shape :',y_test_label.shape)

#step1.4 將1.3的features值(X)做minmax標準化處理
#    (0.0~255.0)-->(0.0~1.0)
x_train_normalize=x_train_image / 255.0
x_test_normalize=x_test_image / 255.0

#step1.5 將label值(y)(0,1,~9) 作 One-hot encoding 編碼, 
#使用 tf.keras.utils.to_categorical() function
y_Train_OneHot=tf.keras.utils.to_categorical(y_train_label)
y_Test_OneHot=tf.keras.utils.to_categorical(y_test_label)

#step2.使用 tf.keras Sequential 方式建立深度神經網路模型(DNN) 
#建立MLP/DNN模型, 輸入層(X),784個神經元;  
#隱藏層(h),256個神經元; 輸出層(y),10個神經元 

#step 3. 以tf.keras.models.Sequential 建模
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(256, activation=tf.nn.relu,
                        kernel_initializer='random_uniform',
                        bias_initializer='zeros'),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax,
                        kernel_initializer='random_uniform',
                        bias_initializer='zeros')
])

#step 3.1 檢視 Sequential model 'model' 的摘要
print(model.summary())

import matplotlib.pyplot as plt
%matplotlib inline
img=plt.imread('model_20210807.png')
plt.imshow(img)

#====================================================================
#建立深度學習模型後,就可以使用反向傳播演算法(Back Propagation)進行訓練
#step4. 進行訓練

#step4.1 設定訓練參數
#        以 model.compile(), 設定模型訓練方式
#        Compilation:
#        Before training a model, you need to configure the learning process, 
#        which is done via the compile method. It receives three arguments:
#            1.An optimizer.      (設定訓練時的優化方法, 如adam)
#            2.A loss function.   (設定損失函數, 如 cross_entropy)
#            3.A list of metrics. (設定評估模型的方式, 如 accuracy)
model.compile(loss='categorical_crossentropy',
              optimizer='adam' ,metrics=['accuracy'])
              
#step4.2 設定訓練超參數後開始訓練, 以model.fit()
#    並將訓練過程及結果存至 dict 'train_history'    
train_history=model.fit(x=x_train_normalize,          #feature (X) 數字影像標準化值
            y=y_Train_OneHot,validation_split=0.2, #lebel (y) One-Hot encoding 值
            epochs=10,batch_size=200,verbose=2)   #epochs, 訓練週期為 10

#檢視 train_history.history 屬性的資料結構
train_history.history.keys()

#toolFunction2020
#from local storage upload 'toolFunction2020.py' to VM
from google.colab import files
uploaded = files.upload()

#step4.3 顯示(繪圖)訓練過程
#        讀取 train_history 中 loss 與 accuracy, 繪圖
import toolFunction2020
%matplotlib inline
toolFunction2020.show_train_history(train_history,'accuracy','val_accuracy')

#畫出 loss 誤差值
toolFunction2020.show_train_history(train_history,'loss','val_loss')


#到目前為止,我們只是以 (x_train_image,y_train_label) (60000筆),依8:2 (train(8):test(2)) 做訓練模型評估
#後續, 我們會以另組獨立資料 (x_test_image,y_test_label) (10000筆) 評估模型準確率

#step4. 以獨立的 10000 筆測試資料 (x_test_image,y_test_label) 評估模型準確率
#       使用 Sequential.evaluate() method
score=model.evaluate(x_test_normalize,y_Test_OneHot)
print('accuracy=',score[1])

圖片

model資訊

顯示(繪圖)訓練過程
讀取 train_history 中 loss 與 accuracy, 繪圖

印出誤差值loss

以獨立的 10000 筆測試資料 (x_test_image,y_test_label) 評估模型準確率
並顯示準確率

脈絡

以tf.keras建立 DNN模型
從tf.keras.dataset 讀取 mnist
做minmax標準化處理
One-hot encoding 編碼
以tf.keras.models.Sequential 建模
反向傳播演算法Back Propagation進行訓練
以獨立的測試資料評估模型準確率

211027 上課進度

from tensorflow.keras.utils import to_categorical
import numpy as np
from tensorflow.keras.datasets import mnist
(x_train_image,y_train_label),(x_test_image,y_test_label)=mnist.load_data()
x_Train=x_train_image.reshape(60000,784).astype('float32')
x_Test=x_test_image.reshape(10000,784).astype('float32')
x_Train_normalize=x_Train/255
x_Test_normalize=x_Test/255
y_Train_OneHot=to_categorical(y_train_label)
y_Test_OneHot=to_categorical(y_test_label)
from keras.models import Sequential
from keras.layers import Dense
s_model=Sequential()

s_model.add(Dense(units=100,input_dim=784,kernel_initializer='normal',activation='relu'))       
#設定隱藏層神經元個數100
#設定輸入層神經元個數784
#使用 normal distribution 亂數,初始化 weight及bias
#activation function 'relu'




一個hidden layer時
model.summary(

顯示(繪圖)訓練過程

畫出 loss 誤差值

211103上課進度


把numpy轉成One-Hot型態
也就是轉成index的模式
例如numpy
[1,2,3]
轉成one-hot
[[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]]

參考[Python] 在 Numpy 中將數值轉成 One-Hot 型態

用獨立的10000筆資料測試時,會給一個預設的batch size = 32
因此會有313這個數字 = 10000/32

預測訓練結果

#step1 執行預測, 使用Sequential.predict_classes() method
#參數為 x_Test

prediction = model.predict(x_test_image)

#用argmax()把最大值取出,存放到ndarray "prediction3"

import numpy as np
prediction2 = [x.argmax() for x in prediction]
prediction3 = np.array(prediction2)

#step2. 顯示混淆矩陣 (confusion matrix or error matrix)

#使用 pandas crosstab

import pandas as pd
pd.crosstab(y_test_label,prediction3,rownames=['labels'],colnames=['predict'])

confusion matrix

confusion matirx * unit matrix = 辨識正確的數量
其餘數字,越大表示錯越多

#step3 建立真實 label 與 預測 predict dataframe 'df',方便查詢
df=pd.DataFrame({'label':y_test_label,'predict':prediction3})

此例子中,5被認成3的錯誤數量有23筆
#以布林陣列 查詢 label=5, 但 predic=3
df[(df.label5)&(df.predict3)]
得到下列:

#step4. 查看第 1003 筆, 看為什麼錯?
toolFunction2020.plot_images_labels_prediction(x_test_image,y_test_label,prediction,idx=5972,num=1)

可以看到確實有點像3

隱藏層的層數及unit數量

model_01為hidden layer =1 、unit =500
model_01 = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(500,activation=tf.nn.relu),
tf.keras.layers.Dense(10,activation=tf.nn.softmax)
])
model_01.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
history1=model_01.fit(x=train_images,y=train_labels,validation_split=0.2,epochs=10,batch_size=200,verbose=2)
score1=model_01.evaluate(test_images, test_labels)
print('accuracy=',score1[1])


accuracy= 0.8820000290870667

%matplotlib inline
toolFunction2020.show_train_history(history1,'accuracy','val_accuracy')

訓練的曲線


model_02為hidden layer =5 、unit =100
model_02=tf.keras.Sequential([tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(100,activation=tf.nn.relu),
tf.keras.layers.Dense(100,activation=tf.nn.relu),
tf.keras.layers.Dense(100,activation=tf.nn.relu),
tf.keras.layers.Dense(100,activation=tf.nn.relu),
tf.keras.layers.Dense(100,activation=tf.nn.relu),
tf.keras.layers.Dense(10,activation=tf.nn.softmax)
])
model_02.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
history2 = model_02.fit(x=train_images,y=train_labels,validation_split=0.2,epochs=10,batch_size=200,verbose=2)
score2=model_02.evaluate(test_images, test_labels)
print('accuracy=',score2[1])


accuracy= 0.8781999945640564

%matplotlib inline
toolFunction2020.show_train_history(history2,'accuracy','val_accuracy')

訓練的曲線


不管是何種方法,目標都是讓辨識率提高

筆者補充
做一些喪心病狂的實驗
10層 * 1000units

model_03=tf.keras.Sequential([tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(1000,activation=tf.nn.relu),
tf.keras.layers.Dense(10,activation=tf.nn.softmax)
])
model_03.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])

accuracy= 0.8676000237464905

%matplotlib inline
toolFunction2020.show_train_history(history3,'accuracy','val_accuracy')

跟前面的圖形比較可以發現,已經非常接近train的答案,可以知道提高layer跟units的數量,對於正確率是有幫助的,但訓練的時間非常久,因此我們可以採用其他方式繼續優化。

NN優化的方式

筆者補充

  1. 正則化
  2. 增加神經網路層數
  3. 使用正確的代價函式
  4. 使用好的權重初始化技術
  5. 人為拓展訓練集
  6. 棄權技術

以下是逐漸優化的過程舉例
  1. 普通的全連線神經網路

1.我們使用一個隱藏層,包含100個隱藏神經元
2.輸入層是784
3.輸出層是one-hot編碼的形式
4.最後一層是Softmax層
5.60次迭代
6.學習速率η=0.1
7.隨機梯度下降的小批量資料大小為10
8.沒有正則化
在測試集上得到的結果是97.8%


  1. 使用卷積神經網路 僅一個卷積層

1.輸入層是卷積層,一個5* 5的卷積核,一共20個特徵對映。
2.最大池化層選用2* 2的大小。
3.後面是100個隱藏神經元的全連線層。

在這個架構中,我們把卷積層和chihua層看做是學習輸入訓練影象中的Receptive Field
全連線層則是一個更抽象層次的學習,從整個影象整合全域性資訊。也是60次迭代,批量資料大小是10,學習率是0.1。
經過三次執行取平均後,準確率是98.78%

  1. 使用卷積神經網路 — 兩個卷積層
    我們接著插入第二個卷積-混合層,把它插入在之前的卷積-混合層和全連線層之間,同樣的5* 5的Receptive Field,2* 2的池化層。
    99.06%的準確率。

  2. 使用卷積神經網路 — 兩個卷積層+線性修正單元(ReLU)+正則化

1.換成線性修正啟用函式ReLU f(z)=max(0,z)
2.60個迭代期
3.學習速率η=0.03
4.使用L2正則化,正則化引數λ=0.1

99.23%的準確率,超過了S型啟用函式的99.06%.
ReLU的優勢是max(0,z)中z取最大極限時不會飽和,不像是Sigmod函式,這有助於持續學習。

  1. 使用卷積神經網路 — 兩個卷基層+線性修正單元(ReLU)+正則化+拓展資料集
    拓展訓練集資料的一個簡單方法是將每個訓練影象由一個畫素來代替
    其他的方法也有改變亮度,改變解析度,圖片旋轉,扭曲,位移等。
    我們把50,000幅影象人為拓展到250,000幅影象。因為我們是在訓練5倍的資料,所以減少了overfitting的風險。
    99.37的訓練正確率。

overfitting(過擬合、過度學習,過度擬合)

過度準確地擬合了歷史數據(精確的區分了所有的訓練數據),而對新數據適應性較差,預測時會有很大誤差。
改進方式有:

  1. 增加數據量
  2. 運用regularization正則化
    在線性代數中,筆者的理解是,regularization就是所有的向量完全不重疊,所以每個向量在ML時都能夠提供最佳的輸出

    如上圖,這是一個簡單的regularization base,(從陳擎文老師的投影片切的)
  3. Dropout
    在訓練的時候,隨機忽略掉一些神經元和神經聯結 ,使這個神經網絡變得”不完整”,然後用一個不完整的神經網絡訓練一次。
    到第二次再隨機忽略另一些, 變成另一個不完整的神經網絡。
    有了這些隨機drop掉的規則, 每一次預測結果都不會依賴於其中某部分特定的神經元。
    參考AI - TensorFlow - 過擬合(Overfitting)

  1. 使用卷積神經網路 — 兩個卷積層+線性修正單元(ReLU)+正則化+拓展資料集+繼續插入額外的全連線層
    繼續上面的網路,我們拓展全連線層的規模,300個隱藏神經元和1000個神經元的精度分別是99.46%和99.43%.
    我們插入一個額外的全連線層

這次取得了99.43%的精度。拓展後的網路並沒有幫助太多。

  1. 使用卷積神經網路 — 兩個卷基層+線性修正單元(ReLU)+拓展資料集+繼續插入額外的全連線層+棄權技術
    棄權的基本思想就是在訓練網路時隨機的移除單獨的啟用值,因此不太依賴於訓練資料的特質。
    我們嘗試應用棄權技術到最終的全連線層(不是在卷基層)。這裡,減少了迭代期的數量到40個,全連線層使用1000個隱藏神經元,

棄權的簡單舉例就是Dropout
使用棄權技術,達到99.60%的準確率。

  1. 使用卷積神經網路 — 兩個卷基層+線性修正單元(ReLU)+正則化+拓展資料集+繼續插入額外的全連線層+棄權技術+組合網路
    組合網路類似於隨機森林或者adaboost的整合方法,建立幾個神經網路,讓他們投票來決定最好的分類。
    採用這個方法,達到了99.67%的準確率。

總結
卷積神經網路 的一些技巧總結如下:

  1. 使用卷積層極大地減小了全連線層中的引數的數目,使學習的問題更容易
  2. 使用更多強有力的規範化技術(尤其是棄權和卷積)來減小overfitting,
  3. 使用修正線性單元ReLU而不是S型神經元,來加速訓練-依據經驗,通常是3-5倍,
  4. 使用GPU來計算
  5. 利用充分大的資料集,避免overfitting
  6. 使用正確的代價函式,避免學習減速
  7. 使用好的權重初始化,避免因為神經元飽和引起的學習減速
加入卷積層Convolutional layer
增加Convolutional layer
加入線性修正單元ReLU
正則化regularization
拓展資料集
加入更多全連線層
棄權技術drop out
組合網路

參考
神經網路的引數優化方法

211115上課進度

期中考
總之就是上課一直在重複的東西要考
Data Sets 是 MNIST 的手寫字辨識
或是Fashion Mnist

  1. Data sets 的 x是多少,shape,維度

  2. 會指定幾個隱藏層,幾個units

  3. 會給題目,是多元還是二元分類

差別是啟動函數

多元分類用softmax
二元分類用sigmod
損失函數
多元分類是分類交叉墒sparse_categorical_crossentropy
二元分類是二元交叉墒binary_crossentropy

  1. 會給epach
  2. 會給訓練需要設定的值
  3. 跑完的模型(h5文字檔)存下來,要給老師

future 屬性可以加入相容性,避免因為GPU執行不了新版本套件,而衍伸的問題

從原始資料裁mnist > 可以看ch20_tf001a_.ipynb

3 5 因為認定多元分類

211117上課進度(期中考)

  1. 載入 MNIST 資料集後將 '7’ 與 ‘9’ 的資料取出來並將資料的數量及維度印出 (25%)

  2. 以 tf.keras 建立一個簡單的神經網路模型,模型中包含兩層隱藏層(每個隱藏層包含200個神經元),設定模型各項參數後,列印出模型(35%)

  3. 設定模型訓練參數 (epochs=10,batch_size=72,valid=0.2)後,訓練模型並將訓練過程損失圖(loss diagram)畫出 (25%)

  4. 以測試資料集(test dataset)評估模型準確度(accuracy) (15%)

211124上課進度

overfitting

模型太過依賴訓練資料
還有underfitting
需要找出sweet point

  1. 神經網路如果沒有設定,必定overfitting

bia值的意義是讓神經元很好的啟動
換句話說此神經元很好通過,input會依賴此神經元
最後會造成overfitting
解決方法是dropout,讓此種神經元不產生
https://www.gushiciku.cn/pl/gfae/zh-tw

  1. acc在特定的epach後就沒有用了

CNN

只要資料形式可以轉為ndarry,CNN必定為首選
例如圖形、訊號、聲音
在DNN前面加入至少一層的全連結層與池化層

piple line 自動找出最佳化的方向(batch-size)

hidden layer unit dropout batch_size acc
3 1000 0.5 200 0.9785000085830688
3 1000 0.2 200 0.9761999845504761
3 1000 0.7 200 0.9757999777793884
3 1000 0.5 50 0.9772999882698059

211208上課進度

設定DNN時,我們需要考慮的有:

如何選定「隱藏層」的數量
每個「隱藏層」神經元的數量
該使用何種「啟動函數」
該使用何種「損失函數」
改用何種「最佳化演算法」
其中有些數值是根據題目而定
有些數值(超參數)就需要使用其他方法來系統化的得到

超參數優化

超參數包括:

Number of hidden layers
Number of neurons per hidden layer
Dropout layer and Dropout rate
Learning rate
batch size

優化的方式有均格搜尋grid search
用for loop 找最佳
使用以下方法來找最佳hyper parameters

  1. 設定基準線(Baseline)

可以使用Random Forest

baseline

  1. 研究生下降(Graduate student descent)

人工依序測試

巢狀for loop 搜尋

如圖,for 變數bs in range(10,200,20)跑迴圈
訂一個空的list記錄分數,如果分數大於0,就更新bestBatchSize
將batch size從10測試到200,每次增加20,hidden number=256
最後將最佳的BatchSize印出

batchsize跟score的相關性如下圖

在這區間(BatchSize = 20 ~200),結果並非正相依或負相依。
雖然本實驗最佳結果出現在BatchSize=130,但是因為我們的網格大小為20,仍有鬆散網格的陷阱。

  1. 隨機超參數搜尋


跟random search 相比,grid search 可能會落入鬆散網格的陷阱,錯失了最佳設定,所以random search 也是值得使用的search。
Grid search 流程

1.先對隨機值進行抽樣
2.將抽樣值放入串列中
3.以2.的值作均格搜尋

兩條線很接近代表overfitting很小

課堂練習
將BatchSize及hiddenNum都進行均格搜尋

結果如下

筆者補充
在作CNN的時候有時候會有ERROR如下:
ValueError: Input 0 of layer sequential is incompatible with the layer
搜尋之後發現可能是color channels的問題

  1. CNN要求輸入是4維張量,與三維相比多了一個channel number,shape是(張數,圖片長,圖片寬,通道數),RGB channel number = 3
  2. 使用的數據集mnist則是灰階圖片,使用三维的ndarray儲存資料,shape是(60000,28,28),因為灰階channel number =1,所以沒有寫
    所以將Input shape 改為 (60000,28,28,1)就可以了

    參考
    使用CNN时报错,ValueError: Input 0 of layer sequential is incompatible with the layer

或是前面圖片格式的問題
將(60000,784)

改為(60000,28,28)

兩個都有可能

211215

卷積運算(上面有)
為預防卷積完的Feature縮小,使用padding,在旁邊加一圈0
卷積是共用權重的概念密切的資訊所決定。以「視覺」感官而言,「鄰近的像素」應該是關係最密切的,它們的集體資訊也會彼此相關。
「深度學習」的核心觀念是:系統需要自己去學習。
在「深度學習」中,我們需要做的是:

  1. 設定層的架構(卷積、池化、dropout、)順序與次數。
  2. 層的大小、步輻、填補、濾鏡數量與大小
  3. 在「深度學習」中,使用「監督式學習」和「反向傳播演算法」來學習設定過濾器的權重(filterweight)
  4. 濾鏡的深度(d),通常是2的指數次方,例如32,64,確保池化層後,可保有整數維度

套上filter
blur filter =[[1/9,1/9,1/9],[1/9,1/9,1/9],[1/9,1/9,1/9]]

211222

神經網路運算時間包含

  1. 訓練時間

通常放在GPU跑

  1. 模型預測時間

Pooling沒有weight的問題

Cifar-10 data set

  1. shape=(60000,32,32,3)
  2. train data 有50000個,test data 有10000個
  3. label分為10類: 飛機、汽車、鳥、貓、鹿、狗、青蛙、船、卡車。每個分類各有6000個圖像

檢視第一筆資料的ndarray,三個array一組(因為channel=3,是RGB),數字是0-255

接下來作one-hot-encoding,用np_utils.to_categorical() method,此函數是可以將數字轉為0,1表示

211229

RNN
Token->estimator評估器->做modeling->fit->predition

220105

從頭複習,往上看
監督式學習與非監督式學習的差異 > 標籤
加入hidden layer的原因 > 如果神經網路只有I/O layer,函數會是linear,hidden layer 使其可以非線性

搜尋optimizer相關的資訊用
model.optimizer.get_config()

可以查到例如learning_rate
或是使用的函數

fashion mnist為資料,用CNN,至少三層捲基池化(會指定參數),十分類,要求損失圖或準確圖
,評估準確度

給均格做搜尋

220112 期末考

題目: 使用 fashion-mnist (https://github.com/zalandoresearch/fashion-mnist ) 資料集 做多元分類 (分辨 服飾衣物配件類別)

  1. 載入 fashion-mnist資料集後檢視並說明該資料集(shape,size,datatype,)並檢視影像資料(plot img) (20%)
    載入資料集

說明

檢視

  1. 以 tf.keras 建立一個簡單的神經網路模型(DNN),模型中包含1層隱藏層(隱藏層包含200個神經元)不使用任何正規化參數(不使用dropout layer),設定模型各項參數後,列印出模型(20%)

  2. 設定模型訓練參數 (epochs=10,batch_size=72,valid=0.2)後,訓練模型並將訓練過程損失圖(loss diagram)畫出並以測試資料集(test dataset)評估模型準確度(accuracy) (20%)
    損失圖

評估

  1. CNN(Convolutional Neural Networks), 將上述(fashion-mnist) 以CNN模型做分類深度學習模型
    a. 建立一個有兩個卷積(conv2d)、池化(pooling)的CNN多元分類器(各參數自行設定,但須註解說明)後列印出模型(20%)
    模型

b. 以fishion-mnist 資料集/CNN 重作(2,3) (20%)
Cnn模型印出

損失圖

評估

程式連結
https://colab.research.google.com/drive/1gpmEbWUPoITGrcpi4FGuszovS9BMkVm2?usp=sharing