Posted on

機器學習所需的前置知識

前置知識介紹

學習機器學習的前置知識包括:

  • 數學基礎:學習機器學習需要具備良好的數學基礎,尤其是線性代數、微積分和概率論的基礎知識。
  • 編程基礎:學習機器學習需要具備編程能力,至少應該熟悉一種編程語言,如 Python、C++ 或 Java。
  • 算法基礎:了解常用的算法和數據結構,如排序算法、搜索算法、哈希表和二叉樹,將有助於學習機器學習中的算法。
  • 機器學習基礎:了解機器學習的基本概念,如訓練集、測試集、模型和過擬合,有助於加深對機器學習的理解。
  • 心理學基礎:了解心理學基礎知識,如信息加工理論和注意力機制,可以幫助我們更好地理解機器學習的應用。

當然,機器學習是一門涉及多個領域的學科,學習時可能還需要具備其他領域的知識,如統計學、計算機科學和人工智能等。

此外,學習機器學習時還需要具備一定的學習能力和探究精神,能夠獨立思考問題並尋找解決方案。建議您先了解機器學習的基本概念,並通過實踐來加深理解。可以嘗試解決一些練手的機器學習問題,或者參加一些在線的機器學習課程或比賽,來提升自己的機器學習能力。

微積分

微積分是計算數學的一個分支,主要研究連續的函數的求積、導數、極限的概念。在機器學習中,微積分的概念有助於我們理解和掌握梯度下降 (gradient descent) 算法,以及訓練神經網路的過程。

線性代數

線性代數是計算數學的一個分支,主要研究向量和矩陣的概念。在機器學習中,線性代數的概念有助於我們理解和掌握神經網路的運算過程,以及從數據中學習到有用信息的方法。

在線性代數中,還有許多其他概念,例如:

  • 線性相關:多個向量是線性相關的,當且僅當它們可以由其他向量的線性組合表示。
  • 基:向量空間的基是一组向量,它们的线性组合可以表示向量空间中的任何向量。
  • 秩:向量空間的秩是指最多可以由多少个向量的线性无关组合表示出来。
  • 線性無關:多個向量是線性無關的,當且僅當它們不能由其他向量的線性組合表示。
  • 內積:向量的內積是指兩個向量的點積,可以用來度量兩個向量之間的夾角。
  • 特徵向量:特徵向量是指線性轉換的特徵

信息加工理論和注意力機制

信息加工理論是心理學中一種用於描述人類心理信息加工過程的理論。它描述了人類大腦如何接收、處理、儲存和使用信息的過程。

根據信息加工理論,人類的大腦有三個基本的信息加工系統:感覺系統、認知系統和記憶系統。感覺系統負責接收外界信息,如視覺、聽覺、觸覺等,並將這些信息轉化成電信號傳遞給認知系統。認知系統負責對接收到的信息進行分析、比較、推理和決策,並將結果轉化成電信號傳遞給記憶系統。記憶系統負責存儲信息,並在需要時將信息重新取出。

注意力機制是指人類大腦如何選擇哪些信息應該被注意,哪些信息應該被忽略的過程。注意力是人類大腦加工信息的一種重要機制,它可以幫助我們過濾掉不重要的信息,專注於重要的信息。注意力可以由內部因素 (如情緒、動機和目標) 和外部因素 (如視覺、聽覺和触覺信息) 共同影響。

注意力機制在機器學習中也有重要作用。例如,在解決複雜的機器學習問題時,我們可能會面臨大量的信息和訓練數據,這時候需要注意力機制來幫助我們把重點放在最重要的信息和數據上。此外,注意力機制還可以用於解決模型過擬合問題,即讓模型更加關注訓練數據中的重要信息,而忽略噪聲和不重要的信息。

在機器學習中,注意力機制通常是通過注意力機制層 (attention layer) 實現的。注意力機制層是一種神經網絡層,它可以根據輸入數據的不同特徵,動態地分配注意力,從而更加精確地提取重要信息。注意力機制層已廣泛應用於機器翻譯、自然語言處理和計算機視覺等領域。

Posted on

深度學習模型-MLP、CNN與 RNN

常見的深度學習模型

三種深度學習模型,包含:
• MIP:多層感知器( Multilayer Perceptron)
• CNN :卷積神經網路(Convolutional Neural Network )
• RNN:循環神經網路(Recurrent Neural Netw ork)

MLP、CNN與RNN的差異

多層感知器(簡稱 MLP)就是一個全連接網路。在某些文獻裡,它被稱為深度前饋(feedforward)網路或前饋神經網路。從目標應用來認識這些網路有助於我們理解這些進階深度學習模型的設計原理。MIP 常用於簡易的算術與線性迴歸問題。不過,MLP 在處理順序型與多維度資料樣式上的效能不是太好。它在先天設計上很難去記得順序型資料的樣式,並且需要相當大量的參數才能處理多維度資料。

RNN 很常用於順序型的輸入資料,因為其內部設計能讓網路去發掘歷史資料的相依性,這對於預測來說相當有用。

而對於圖片或影片這類多維度資料,CNN 在擷取用於分類、分割、生成或其他目的特徵圖都相當不錯。在某些狀況下,型態為1D卷積的 CNN 也可用於能接受順序型輸入資料的網路。然而在多數深度學習模型中,會把 MLP、RNN 與CNN 結合起來讓它們發揮各自所長。

MLP、CNN與RNN輸入的模型維度

在將資料傳入模型前會需根據模型類型來調整形狀

Keras把 MLP 層稱為 Dense,代表密集連接層。第一與第二MLP 層完全相同,各有256個單元,接著,是relu觸發與 dropout。之所以選用256單元是因為 128、512與 1,024 單元的效能較差。網路在128 單元時會很快收斂,但測試準確度也較低。
而把單元數拉高到 512 或1,024 並不會大幅提升測試準確度。

單元數量稱為超參數 (hyperparameter),它控制了網路的容量(capacity)。容量是指網路可模擬出的函數複雜度。例如對於多項式來說,超參數就是其次方數。只要次方數增加,函數容量也會增加。
如以下模型,在此使用Keras 的Sequential Model API 來實作一個分類器模型。
當模型只需要一個輸入、一個輸出,且只需要由順序排列層來處理時,這樣已經很足夠。

由於 Dense 層屬於線性操作,所以就算有一連串的 Dense 層也只能做到模擬線性函數。現在的問題在於 MNIST 數字分類在本質上就是非線性過程。在Dense層之間插入relu觸發可讓MLP 得以針對非線性應對來建模。relu 或稱為修正線性單元(Rectified Linear Unit, ReIU)是一種簡易的非線性函數,它很像是個過濾器,只讓正值輸入通過且保持不變,其他則全部變為零。數學上來說,relu可用以下方程式來表示

正規化

神經網路傾向於記住自身的訓練資料,尤其是當容量充足的時候。在這樣的狀況下,網路碰到測試資料時就會一塌糊塗。這就是網路無法一般化的典型症狀。模型會運用正規化層或正規化函數來避免這個傾向,常見的正規化層也稱為 dropout。

dropout 的概念很簡單。指定 dropout 率(在此設定 dropout=0.45)・Dropout
層就會隨機移除這個比例的單元數,不讓它們參與下一層・例如,第一層有256個
單元,隨後應用 dropout=0.45。這樣一來,層1就只會有 (1 – 0.45) * 256 units =
140個單元會參與層 2。

常見給神經網路選擇的觸發函數

輸出層的觸發函數選擇

1inear、sigmoid 與 tanh・linear 觸發的是 identity 函數,它就是把輸入複製到輸出而已。sigmoid函數也稱為logistic sigmoid,它可用於預測 tensor 的元素須獨立映射到 0.0與1.0之間的情形。預測tensor 所有的元素總和不需要為1.0,這是與softmax 最大的不同。例如,sigmoid可用於情緒預測(0.0為差,1.0為優)的最後一層,或影像產生(0.0為0,1.0則為255 像素值)。

tanh 函數可將其輸入映射到-1.0到1.0之間,這個性質在輸出值需要有正負值時尤其重要。tanh 函數常用於循環神經網路的內部層,但也可用於輸出層觸發。如果用tanh 來取代輸出觸發中的sigmoid,那麼資料就需要先適當縮放才行。

Posted on

訓練模型-model.fit()的參數設定

model.fit的參數

請見官網介紹: https://www.tensorflow.org/api_docs/python/tf/keras/Model#fit

fit(
    x=None,
    y=None,
    batch_size=None,
    epochs=1,
    verbose='auto',
    callbacks=None,
    validation_split=0.0,
    validation_data=None,
    shuffle=True,
    class_weight=None,
    sample_weight=None,
    initial_epoch=0,
    steps_per_epoch=None,
    validation_steps=None,
    validation_batch_size=None,
    validation_freq=1,
    max_queue_size=10,
    workers=1,
    use_multiprocessing=False
)

通常label單類別最後使用softmax當作activation,多類別用sigmoid。在使用model.fit之前可用下列指令來查看模型的資訊:

model.summary()

Batch size

Batch size是在訓練神經網絡時,一次輸入給模型的訓練樣本數量。批量大小可以影響訓練的速度和效果,決定了模型在訓練過程中每次更新權重時使用的樣本數量。

在訓練神經網絡時,每一次將一個批次的訓練數據輸入模型並根據輸出調整模型參數的過程稱為一次迭代。

批量大小可以影響訓練的速度和效果。通常而言,批量大小越大,訓練速度越快,但是需要更多的內存。相反,批量大小越小,訓練速度越慢,但是需要的內存較少。

另外,批量大小也有助於控制梯度爆炸和消失的問題。如果批量大小太小,梯度可能會非常波動,導致訓練不穩定。如果批量大小太大,梯度可能會非常小,導致模型學習速度變慢。

因此,批量大小是一個需要平衡的超參數。通常,人們會根據自己的硬件配置和訓練目標來調整批量大小。

甚麼是更新權重

在神經網絡中,權重是用於計算網絡輸出的參數。每個神經元都有自己的權重,這些權重决定了該神經元對輸出的貢獻。

在訓練神經網絡時,權重是通過反向傳播算法來學習和調整的。在每次訓練迭代中,網絡將會根據輸入和預期輸出計算損失,然後使用反向傳播算法來調整權重,使得損失最小化。

在神經網絡中,權重是一種超參數,這意味著它們是由人為設定的,並不是通過訓練來學習的。超參數包括學習率、批量大小、正則化強度等,它們都對模型的訓練和性能有重要影響。

Epoch

Epoch是指訓練過程中對整個訓練數據集進行一次完整的訓練循環。例如,假設你有1000個樣本的訓練數據集,批量大小為100,那麼你需要10次迭代才能完成一個 epoch。

在訓練神經網絡時,你可能會進行多個 epoch,以提高模型的精度。在每個 epoch 中,模型將會看到所有的訓練數據,並根據輸出調整模型參數。在許多情況下,經過足夠多的 epoch 後,模型的精度將會趨於穩定,並停止進一步提高。

Posted on 1 Comment

卷積神經網路CNN介紹

卷積神經網路CNN

卷積神經網路(Convolutional Neural Network,簡稱 CNN)是一種專門用於圖像處理的神經網路。它包含許多卷積層和池化層,可以捕捉圖像中的空間關係和細節。

  • 卷積層: Conv2D (tf.keras.layers.Conv2D),使用一個卷積核來提取圖片特徵
  • 池化層: MaxPooling2D (tf.keras.layers.MaxPooling2D),通過計算輸入圖像的不同區域的最大值或平均值來進行池化

卷積層(Conv2D)

使用一個卷積核來提取圖片特徵。
以下為其參數設定的介紹: 卷積層(Conv2D)參數設定

卷積層中的每個神經元都有一個濾波器(也稱為卷積核),用來提取圖像的特徵。每個濾波器都有一個指定的大小和深度,並且會在輸入圖像的不同區域進行卷積運算。例如,如果濾波器的大小為 3×3,且深度為 16,則每個濾波器都會提取 3×3 的區域中深度為 16 的特徵。

以下為其計算方法的簡單範例

當有部分的卷積核超出圖片範圍時,有兩種方法去解決:
1. 忽略它: 將padding設定為valid

2. 將整個圖像周圍填充0: 將padding設定為same

池化層(MaxPooling2D)

池化層則是將輸入圖像的大小縮小的層,它的主要功能是對圖像的特徵進行下采樣 (downsampling),降低網絡的計算量並減少過擬合 (overfitting) 的風險。它通過計算輸入圖像的不同區域的最大值或平均值來進行池化。通過池化,可以將圖像中的高維度特徵轉化為低維度特徵、降低計算複雜度,同時還能保留圖像中重要的特徵。

最大值池化層和平均值池化層是兩種常用的池化方法。

最大值池化層對卷積過的特徵圖 (convolutional feature map) 進行下采樣時,會將其中每個子區域 (sub-region) 取出其中的最大值,這樣可以保留最重要的特徵,可以適用於辨識邊緣、輪廓、細節的圖像。

平均值池化層對卷積過的特徵圖進行下采樣時,會將其中每個子區域取出其中的平均值。平均值池化更能保留圖像整體特徵,適用於辨識整體顏色、紋理、形狀等。

記得不同情境需求評估適用池化層種類,並且池化層種類通常與當時訓練資料有關。

下面為一個最大池化層的實作步驟解釋:

池化層有兩個重要參數: pool_sizestrides,分別代表步長和池化的大小,上圖的示例為步長2且池化大小為(2,2)的最大池化層的範例。

如何對彩色圖片做卷積處理

因為彩色圖片為一個RBG圖片

若是黑白圖片為(25,25,1),則相同大小的彩圖形狀會是(25,25,3),因此卷積核的形狀也會從(3,3)變為(3,3,3)

每一個圖層都要算三次然後再加總,總共要三個圖層,因此複雜度從黑白->彩色會增加9倍以上

Posted on 1 Comment

卷積層(Conv2D)參數設定

卷積層(Conv2D)介紹

以下為官方介紹連結:
https://keras.io/api/layers/convolution_layers/convolution2d/

參數介紹

參數

常用參數

  • filters:指定層中濾波器(也稱為卷積核)的數量。通常,增加濾波器的數量可以提高模型的表現,但也會增加計算複雜度。
  • kernel_size:指定濾波器的大小。濾波器的大小越大,模型可以捕捉到的特徵就越大,但也會增加計算複雜度。
  • strides:指定濾波器在輸入數據集上的步長。步長越大,模型就會捕捉到越少的特徵,但也會減少計算複雜度。
  • padding:指定是否對輸入數據集進行 padding。如果選擇 padding,則會在輸入數據集的周圍填充一圈 0,以便濾波器可以捕捉到輸入數據集的邊界特徵。

在設定這些參數時,需要考慮模型的複雜度和需要的特徵。例如,如果輸入數據集很大,且需要捕捉較大的特徵,那麼可能需要使用較大的濾波器和較大的步長。如果輸入數據集較小,且需要捕捉較多的細節,那麼可能需要使用較小的濾波器和較小的步長。

還可以嘗試使用不同的 padding 方式來控制輸入數據集的大小。例如,如果你使用「same」padding,則輸出數據集的大小將與輸入數據集的大小相同;如果你使用「valid」padding,則輸出數據集的大小將比輸入數據集的大小小。

Posted on

如何提高機器學習的準確率

提高準確率的方向

可以考慮用以下幾個方式來提高準確率:

  • 增加訓練數據:模型訓練的資料越多,模型就有更多的資訊來學習,因此準確率往往會提高。
  • 調整超參數:你可以調整超參數(例如學習率、損失函數、正則化項等)來提高模型的準確率。
  • 改變模型結構:你可以增加或刪減模型中的層數、增加每層的神經元數量,或者使用不同的激活函數來改變模型的結構。
  • 訓練更長時間:模型訓練的時間越長,模型就有更多的時間來學習,因此準確率往往會提高。
  • 使用不同的模型:你可以試試不同的模型結構,例如殘差網路或卷積神經網路,看看哪個模型的準確率更高。

數據資料的準備

請見我的另一篇文章: 準備數據集資料的方針

調整超參數

超參數是指在訓練模型時不能由模型自動學習的參數。它們通常會影響模型的性能,因此在訓練模型時需要手動設置。

一些常見的超參數包括:

  • 學習率:決定了模型在訓練過程中更新權重的速度。
  • 損失函數:決定了模型在訓練過程中最小化的目標函數。
  • 正則化項:決定了模型在訓練過程中對過擬合的懲罰力度。
  • 批量大小:決定了模型在訓練過程中每次更新權重時使用的樣本數量。

設置超參數的方法有很多,其中常見的方法包括網格搜索隨機搜索

網格搜索是指對每個超參數設置一組固定的值,然後枚舉所有可能的組合來尋找最佳超參數。
隨機搜索則是隨機設置超參數的值,然後找出準確率最高的超參數組合。

也可以使用自動調參工具,例如 Hyperopt Optuna,來幫助你設置超參數。這些工具可以自動幫你調整超參數,以便找到最佳的超參數組合。

使用TensorFlow Tuner 對一個模型的參數進行調優

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# Define the model
def build_model(hp):
    model = keras.Sequential()
    model.add(layers.Dense(units=hp.Int('units', min_value=32, max_value=512, step=32), activation='relu', input_shape=(784,)))
    model.add(layers.Dense(10, activation='softmax'))
    model.compile(
        optimizer=keras.optimizers.Adam(hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])),
        loss='categorical_crossentropy',
        metrics=['accuracy'])
    return model

# Define the tuner
tuner = keras.tuner.RandomSearch(
    build_model,
    objective='val_accuracy',
    max_trials=5,
    directory='my_dir',
    project_name='MNIST')

# Load the MNIST dataset
(x_train, y_train), (x_val, y_val) = keras.datasets.mnist.load_data()

# Normalize the data
x_train = x_train.reshape(-1, 784).astype('float32') / 255
x_val = x_val.reshape(-1, 784).astype('float32') / 255

# Start the tuning
tuner.search(x_train, y_train, epochs=2, validation_data=(x_val, y_val))

# Print the best model
best_model = tuner.get_best_models(num_models=1)[0]
best_model.summary()

使用網格搜索調整超參數

網格搜索是一種超參數調整方法,它可以幫助我們找到最佳的超參數組合。網格搜索的基本思路是,對於每個超參數,設定一組固定的值,然後枚舉所有可能的超參數組合,最終找到最佳的超參數組合。

舉例來說,假設有一個模型,需要調整兩個超參數:學習率和正則化率。可以設定學習率的可能取值為 0.1、0.01 和 0.001。然後,就會有九種可能的超參數組合:

學習率:0.1,正則化率:0.1
學習率:0.1,正則化率:0.01
學習率:0.1,正則化率:0.001
學習率:0.01,正則化率:0.1
學習率:0.01,正則化率:0.01
學習率:0.01,正則化率:0.001
學習率:0.001,正則化率:0.1
學習率:0.001,正則化率:0.01
學習率:0.001,正則化率:0.001

可以對每組超參數進行訓練,並計算每組超參數的準確率。最後,你就可以找到準確率最高的超參數組合。

from sklearn.model_selection import GridSearchCV

# 定義模型
model = SomeModel()

# 定義超參數組合
param_grid = {'learning_rate': [0.1, 0.01, 0.001],
              'regularization_rate': [0.1, 0.01, 0.001],
              'batch_size': [32, 64, 128]}

# 使用網格搜索尋找最佳超參數組合
grid_search = GridSearchCV(model, param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 輸出最佳超參數組合
print(grid_search.best_params_)

在這個範例中,定義了三個超參數:學習率、正則化率和批量大小。我們將每個超參數的可能取值列出來,然後使用 GridSearchCV 進行網格搜索。最後輸出最佳超參數組合。

網格搜索是一種有效的調整超參數的方法,但它有一個缺點:如果超參數的可能取值較多,那麼需要訓練的模型數量就會變得很多。這可能會導致訓練時間過長。

因此,可以考慮使用隨機搜索來調整超參數,它可以在較短的時間內找到較佳的超參數組合。

用隨機搜索來調整超參數

from sklearn.model_selection import RandomizedSearchCV

# 定義模型
model = SomeModel()

# 定義超參數組合
param_dist = {'learning_rate': scipy.stats.uniform(0.01, 0.1),
              'regularization_rate': scipy.stats.uniform(0.01, 0.1),
              'batch_size': [32, 64, 128]}

# 使用隨機搜索尋找最佳超參數組合
random_search = RandomizedSearchCV(model, param_dist, n_iter=10, cv=5)
random_search.fit(X_train, y_train)

# 輸出最佳超參數組合
print(random_search.best_params_)

Keras中使用隨機搜索調整超參數

在 Keras 中,可以使用 fit() 方法來訓練模型,並在調用該方法時傳遞超參數。以下是一個使用隨機搜索調整 Keras 模型超參數的範例:

from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform

# 定義模型工廠函數
def create_model(learning_rate=0.01, regularization_rate=0.0):
    model = Sequential()
    model.add(Dense(32, input_dim=8, kernel_regularizer=l2(regularization_rate)))
    model.add(Activation('relu'))
    model.add(Dense(1))
    model.add(Activation('sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer=Adam(lr=learning_rate), metrics=['accuracy'])
    return model

# 封裝模型為 KerasClassifier
model = KerasClassifier(build_fn=create_model, verbose=0)

# 定義超參數組合
param_dist = {'learning_rate': uniform(0.01, 0.1),
              'regularization_rate': uniform(0.01, 0.1)}

# 使用隨機搜索尋找最佳超參數組合
random_search = RandomizedSearchCV(model, param_dist, n_iter=10, cv=5)
random_search.fit(X_train, y_train)

# 輸出最佳超參數組合
print(random_search.best_params_)

改變模型結構

可嘗試以下的超參數設置來試試看:

學習率:0.001 到 0.01 之間的浮點數。
正則化率:0.001 到 0.01 之間的浮點數。
批量大小:32、64 或 128。
層數:2 到 4 層之間的整數。
神經元數量:64、128 或 256。

甚麼是神經元

神經元(neuron)是生物神經系統中的基本單元,它負責接收、處理和傳遞信息。在人類大腦中,神經元通過樹狀結構相互連接,形成了神經網絡。

在人工神經網絡中,神經元也是基本單元。它們通過連接形成了多層結構,用於解決各種複雜的計算和學習任務。神經元通常由輸入、權重、偏差和激活函數組成。輸入是神經元接收的數據,權重是用於計算輸出的參數,偏差是用於調整輸出水平的參數,激活函數是用於決定神經元是否觸發的函數。

在訓練神經網絡時,神經元的權重和偏差會被調整,以使得輸出與預期輸出更加接近。通過不斷調整神經元的參數,神經網絡最終可以學習到解決任務所需的知識和技能。

Posted on 1 Comment

準備數據集資料的方針

如何準備數據集

使用質量高的資料,如:​

  • 清晰的圖像: 圖像清晰且無模糊或雜訊。​
  • 正確的標記: 圖像被正確地標記為相應的類別。​
  • 代表性的數據: 數據集中的數據能夠代表所有可能的輸入圖像,例如不同的角度、光線、尺寸等。​

避免以下狀況:​

  • 模糊或不清晰的圖像: 圖像中有大量的模糊或雜訊。​
  • 錯誤的標記: 圖像被錯誤地標記為其他類別。​
  • 不代表性的數據: 數據集中的數據只代表一小部分可能的輸入圖像。

數據集要多少張才足夠

所需的圖片張數會視實際情況而會有所不同。例如,以撲克牌辨識為例,若數據集中只有每種牌的一種花色,或者您的數據集中可能有每種牌的多種花色,隨著分類的數量的增加,所需要的數據集規模也會隨之增加。
因此,在建立模型之前,需要先了解所要建構的數據集的結構,以確保使用的模型能夠正確地處理數據。

決定數據集大小需要考慮的因素有很多,因此無法給出一個硬性的準則。不過,通常而言,越多的訓練數據可以訓練出的模型表現越好。
然而,過多的訓練數據也可能會導致過擬合(overfitting)的問題,即模型對訓練數據表現良好,但對新數據的表現不佳。因此,在建立模型時,還需要考慮到模型的複雜度和訓練數據集的大小之間的平衡。

此外,訓練數據集的質量也很重要。如果您的數據集中有大量的標記錯誤或不清晰的圖像,那麼即使您的數據集很大,模型的表現也可能不佳。
因此,在確定數據集大小時,需要考慮許多因素,並嘗試找出最佳平衡。可以嘗試不同的數據集大小,並觀察模型的表現,以找出最佳的數據集大小。

若只是在測試模型階段,可以先嘗試使用少量的數據集來訓練模型。這可以幫助我們快速測試準備數據集的想法,並大致的了解模型的表現。
當確定了模型的結構和超參數後,可以考慮增加數據集的大小,以提高模型的準確度。因此,在建立模型時,建議先使用少量的數據集來確定模型的結構和超參數,然後再考慮增加數據集的大小。
所謂的少量,若只是測試階段,可以只需要幾百張圖像來確定模型的結構和超參數。但是,需要注意的是,模型的表現可能受到數據集質量的影響。即使數據集很小,如果數據集中的圖像質量很高,那麼模型的表現也可能很好。

可以嘗試使用以下數量的圖像:

  • 少量數據集: 例如,您可以使用 100-200 張圖像來訓練模型。
  • 中等數據集: 例如,您可以使用 1000-5000 張圖像來訓練模型。
  • 大型數據集: 例如,您可以使用 10000 張或更多的圖像來訓練模型。

數據集數量算法: 如果我們要使用 52 張圖像,並且對每張圖像進行 5 種不同的變化,則您的數據集大小就是 52*5=260 張圖像。

怎麼準備圖像資料集

在準備圖形資料時,有時我們會思考若先使用修圖軟體去背,內把要辨識的目標以外的東西都留白,是否有助於計算模型?

在實際運用上,將資料集中非目標部分留白並不會對模型的訓練有明顯的幫助。在訓練模型時,我們最好提供所有可能的資料,以便模型在訓練過程中學習到的特徵越豐富越好。同時,我們也希望模型能夠學習到那些與目標無關的資訊,因為這些資訊可能會在模型在測試時遇到類似的情況時派上用場。

有些人可能會擔心,如果資料集中包含了那些與目標無關的資訊,會不會對模型的訓練帶來干擾?實際上,當模型的訓練資料足夠多,且資料的質量足夠高時,這種情況很少會發生。在這種情況下,模型會自動學習到與目標相關的特徵,並且會忽略那些與目標無關的資訊。

訓練資料的數量的要求取決於許多因素,例如模型的複雜度、資料的質量、資料的分布等。在一般情況下,越複雜的模型、資料質量越高、資料分布越不均勻,訓練資料的數量就需要越多。

然而,要確切地知道訓練資料的數量是否足夠,通常需要通過不斷地實驗和驗證來確定。例如,我們可以對模型進行不斷地訓練並觀察它的效果,然後根據模型的表現是否達到滿意的程度來判斷是否需要增加訓練資料的數量。

然而,實際上,訓練資料的數量往往不是決定模型表現的唯一因素。在訓練模型時,我們還要考慮模型的複雜度、訓練過程中使用的技巧 (例如正則化、數據增強等)、訓練超參數的設定等因素。所以,在訓練模型時,我們需要對所有這些因素都要進行綜合考慮,才能得到最好的模型表現。

如何選擇具代表性的資料集

  • 篩選條件應該基於數據品質:例如,如果有一些圖片的解析度很低,或者圖片中的物體模糊不清,那麼這些圖片可能對訓練準確度沒有太大的幫助,因此可以考慮刪除這些圖片。
  • 篩選方針應該基於訓練目標:例如,如果你的訓練目標是辨識不同種類的動物,那麼你可以考慮保留足夠多的各種動物的圖片,並且刪除一些與訓練目標無關的圖片 (例如,建築物、景觀等)。
  • 篩選條件和方針應該基於數據平衡:例如,如果你的數據集中有一些類別的圖片數量遠大於其他類別的圖片數量,那麼這可能會影響訓練準確度。因此,你可以考慮刪除一些數量較多的類別的圖片,以平衡數據。

梗圖分享

Posted on

如何判讀訓練結果

訓練過程

下面為一個epochs為10的訓練過程的log

機器學習結果判讀

如上圖,當我們下了model.fit開始跑機器學習後,會可以看到跑出下面這些資訊,這時候要如何解讀這些資訊呢?
loss: 0.0337, accuracy: 0.9910, val_loss: 0.1509, val_accuracy: 0.9762​

  • loss:指的是模型在訓練數據集上的損失。損失越低,代表模型的表現越好。​
  • accuracy:指的是模型在訓練數據集上的準確率。準確率越高,代表模型的表現越好。​
  • val_loss:指的是模型在驗證數據集上的損失。損失越低,代表模型的表現越好。​
  • val_accuracy:指的是模型在驗證數據集上的準確率。準確率越高,代表模型的表現越好。​

0.9762 的準確率可以說是相當不錯的,但是在某些應用中可能還不夠。例如,在自動駕駛應用中,準確率可能需要更高,因為一個錯誤的預測可能會導致嚴重的後果。
在這個結果的數據集中,準確率為 0.9762 ,其大約會有 2.38% 的錯誤率。
如果有 100 張圖片,則大約有 2.38 張圖片會被錯誤地預測。

學習效果不好的原因

如果模型在驗證數據集上的準確率低於實際準確率,那可能是因為以下原因:

  • 驗證數據集不具有代表性: 如果驗證數據集中的數據與實際應用中的數據有很大的差異,那麼模型的驗證數據集上的準確率可能會低於實際準確率。
  • 模型過度擬合: 如果模型在訓練數據集上的表現很好,但是在驗證數據集上的表現較差,那麼這可能是因為模型過度擬合了訓練數據集。過度擬合的模型往往在訓練數據集上表現較好,但是在沒有看過的數據集上表現較差。因此,可嘗試增加數據集的大小使用正則化來減少模型的過度擬合。
  • 模型訓練不足: 如果模型沒有被訓練足夠長的時間,那麼它的表現可能會不夠好。你可以增加訓練的 epoch 數,或者增加每個 epoch 中的訓練次數來幫助模型學習。
  • 還有一種情況就是模型的訓練準確率和驗證準確率之間的差距較大,這可能是因為模型過擬合或者過欠擬合。如果模型過擬合,則訓練準確率會很高,但是驗證準確率會很低;如果模型過欠擬合,則訓練準確率和驗證準確率都會很低。可以通過調整模型的超參數來平衡訓練準確率

歸納學習成效不好的原因如下:

  • 欠擬合。如果模型過於簡單,則可能會欠擬合。欠擬合的模型在訓練數據集上的表現可能不夠好,導致訓練準確率越來越差。
  • 過擬合。如果模型過於複雜,則可能會過擬合。過擬合的模型在訓練數據集上的表現可能很好,但是在沒有看過的數據集上的表現可能較差。
  • 學習率過大。如果模型的學習率過大,則模型可能會跳過最佳解,導致訓練準確率越來越差。

如何解決

  • 調整模型的複雜度。你可以增加或減少模型的層數或每層的神經元數量,以平衡模型的複雜度。
  • 使用正則化。正則化是一種常見的技巧,可以減少模型的過擬合。
  • 調整學習率。你可以使用不同的學習率來平衡收敛速度和準確率。
Posted on

Keras介紹

甚麼是Keras

Keras是一個用Python編寫的開源神經網路庫,旨在快速實現深度神經網路,專注於使用者友好、模組化和可延伸性,除標準神經網路外,Keras還支援卷積神經網路和迴圈神經網路。包含許多常用神經網路構建塊的實現,例如層、目標、啟用功能、最佳化器和一系列工具,可以更輕鬆地處理圖像和文字資料。

Keras由純Python編寫而成並基於Tensorflow、Theano以及CNTK後端。Keras 為支持快速實驗而生,能夠把你的idea迅速轉換為結果,如果你有如下需求,請選擇Keras:

  • 簡易和快速的原型設計(keras具有高度模塊化,極簡,和可擴充特性)
  • 支持CNN和RNN,或二者的結合
  • 無縫CPU和GPU切換

Keras建立模型的流程

  • 載入數據集: 首先,您需要載入您要用來訓練模型的圖像數據集。您可以使用 Python 的數據讀取庫(如 pandas 或 numpy) 來讀取本地數據集,或者使用 Keras 自帶的數據集(如 MNIST 手寫數字數據集)。
  • 將數據拆分為訓練集和測試集: 接下來,您需要將數據集拆分為訓練集和測試集。這樣可以幫助您評估模型的表現。通常,您會將大約 80% 的數據集用於訓練,剩餘的 20% 用於測試。
  • 預處理數據: 在進行模型訓練之前,您需要對數據進行預處理。這可能包括將圖像大小轉換為相同的大小,標準化像素值等。
  • 建立模型: 接下來,您可以使用 Keras 來建立模型。Keras 提供了許多不同的模型建構器(如 Sequential 或 functional API),您可以使用它們來建立不同類型的模型。在建立模型時,您需要考慮使用哪種模型類型(如卷積神經網絡或長短期記憶網絡)、使用哪些層類型(如卷積層、池化層、全連接層等),以及如何連接這些層。在決定模型結構時,您可以參考相關研究或嘗試不同的組合以找出最佳的模型結構。
  • 編譯模型: 一旦您已經建立了模型,您需要使用 Keras 的 compile 方法將其編譯。在編譯時,您需要指定損失函數和優化器。損失函數用於評估模型的表現,優化器用於更新模型的權重以使損失最小化。
  • 訓練模型: 一旦您已經編譯了模型,您就可以使用 Keras 的 fit 方法對模型進行訓練。在訓練過程中,您需要指定訓練集和模型訓練的參數,如批次大小和訓練輪數。
  • 評估模型: 一旦模型訓練完成,您就可以使用 Keras 的 evaluate 方法對模型進行評估。評估時,您需要指定測試集,Keras 會自動計算損失和指標(如準確率)。
  • 使用模型: 一旦您已經訓練好了模型,就可使用model.predict來預測資料

與Tensorflow的關係

TensorFlow是一個用於構建和訓練模型的平台。它提供了很多功能,可以讓你輕鬆地構建、訓練和部署各種不同類型的模型。

Keras是一個用於構建和訓練深度學習模型的高階框架。它是在TensorFlow之上構建的,可以讓你輕鬆地使用TensorFlow的功能。

总之,TensorFlow是一個底層的框架,Keras是建立在TensorFlow之上的高階框架,可以讓你更輕鬆地構建和訓練模型。

基礎範例

這是一個建立模型的範例,主要用以做為圖片分類的神經學習,使用了下面幾種模型結構:
1、卷積層: 可以使用一或多個卷積層來提取圖像中的特徵。
2、池化層: 可以使用池化層來縮小圖像的尺寸,並且保留有用的特徵。
3、全連接層: 可以使用一或多個全連接層來將特徵轉換為預測結果。

from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.models import Sequential
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
# X_train 和 y_train 都是 NumPy 陣列
images = np.array(images)
labels= np.array(labels)
# 如果 y_train 是字符串類型的標籤,則可以使用 sklearn 的 LabelEncoder 來將它們轉換為數值。例如:
le = LabelEncoder()
y_train = le.fit_transform(y_train)
# 分割為訓練集及驗證集
X_train, X_test, y_train, y_test = train_test_split(images, labels, test_size=0.2)
# 建立模型
model = Sequential()

# 加入卷積層
model.add(Conv2D(filters=32, kernel_size=(3,3), activation='relu', input_shape=(200,200,3)))

# 加入池化層
model.add(MaxPooling2D(pool_size=(2,2)))

# 加入卷積層
model.add(Conv2D(filters=64, kernel_size=(3,3), activation='relu'))

# 加入池化層
model.add(MaxPooling2D(pool_size=(2,2)))

# 將特徵圖拉平
model.add(Flatten())

# 加入全連接層
model.add(Dense(units=64, activation='relu'))

# 加入輸出層
model.add(Dense(units=52, activation='softmax'))

# 編譯模型
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 開始訓練
model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test))

這是一個使用 Keras 載入模型並預測答案的範例

import numpy as np
import tensorflow as tf
from tensorflow import keras

# 載入模型
model = keras.models.load_model('model.h5')

# 假設我們有一個輸入矩陣 X,其中包含一些資料點
X = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])

# 使用模型預測答案
predictions = model.predict(X)

# 輸出預測結果
print(predictions)
Posted on

LBP 區域二值模式

其實會發這一篇文,主要是看到這個博客的文章真的感動到快哭了…

這幾天因為想增加OCR辨識正確率開始與LBP打交道
https://zh.wikipedia.org/wiki/%E5%B1%80%E9%83%A8%E4%BA%8C%E5%80%BC%E6%A8%A1%E5%BC%8F
我找到了一個看起來很強大很棒的函式庫
https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.local_binary_pattern

網路上有很多教學文章,看起來是很知名的套件
a href=\”https://machine-learning-python.kspax.io/classification/ex1_recognizing_hand-written_digits\”>https://machine-learning-python.kspax.io/classification/ex1_recognizing_hand-written_digits
然後我遇到了和這位博主一樣的問題
https://www.cnblogs.com/ilk123/p/11797261.html
沒錯…….LBP明明出來的應該是1-256的值阿…我也是設定R=1, P=8\r\n這樣用default的LBP出來的應該要是1-256之間的值,但是卻是0和1的二值陣列….

我一直想..這麼偉大的一個scikit-image怎麼可能有錯,一定是我的使用方法有誤…
害我撞頭撞到快崩潰…..
沒想到在此遇到一個和我一樣的苦主
太感動了,特此記錄!

另外,後來我也找到了一個最原始的LBP算法
程式碼下載於 https://github.com/zhongqianli/local_binary_pattern/blob/master/local_binary_pattern.py

def original_lbp(image):
"""origianl local binary pattern"""
rows = image.shape[0]
cols = image.shape[1]

lbp_image = np.zeros((rows - 2, cols - 2), np.uint8)

for i in range(1, rows - 1):
for j in range(1, cols - 1):
code = 0
center_pix = image[i, j]
if image[i - 1, j - 1] > center_pix:
code = code | (1 << 7) if image[i - 1, j] > center_pix:
code = code | (1 << 6) if image[i - 1, j + 1] > center_pix:
code = code | (1 << 5) if image[i, j + 1] > center_pix:
code = code | (1 << 4) if image[i + 1, j + 1] > center_pix:
code = code | (1 << 3) if image[i + 1, j] > center_pix:
code = code | (1 << 2) if image[i + 1, j - 1] > center_pix:
code = code | (1 << 1) if image[i, j - 1] > center_pix:
code = code | (1 << 0) lbp_image[i - 1, j - 1] = code return lbp_image[/code]