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

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

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