神經網絡(NN)實現多分類-----Keras實現

IRIS數據集介紹

  IRIS數據集(鳶尾花數據集),是一個經典的機器學習數據集,適合做爲多分類問題的測試數據,它的下載地址爲:http://archive.ics.uci.edu/ml/machine-learning-databases/iris/
  IRIS數據集是用來給鳶尾花作分類的數據集,一共150個樣本,每一個樣本包含了花萼長度(sepal length in cm)、花萼寬度(sepal width in cm)、花瓣長度(petal length in cm)、花瓣寬度(petal width in cm)四個特徵,將鳶尾花分爲三類,分別爲Iris Setosa,Iris Versicolour,Iris Virginica,每一類都有50個樣本。
  IRIS數據集具體以下(只展現部分數據,順序已打亂):數組

讀取數據集

import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelBinarizer # 讀取CSV數據集,並拆分爲訓練集和測試集 # 該函數的傳入參數爲CSV_FILE_PATH: csv文件路徑
def load_data(CSV_FILE_PATH): IRIS = pd.read_csv(CSV_FILE_PATH) target_var = 'class'  # 目標變量
    # 數據集的特徵
    features = list(IRIS.columns) features.remove(target_var) # 目標變量的類別
    Class = IRIS[target_var].unique() # 目標變量的類別字典
    Class_dict = dict(zip(Class, range(len(Class)))) # 增長一列target, 將目標變量進行編碼
    IRIS['target'] = IRIS[target_var].apply(lambda x: Class_dict[x]) # 對目標變量進行0-1編碼(One-hot Encoding)
    lb = LabelBinarizer() lb.fit(list(Class_dict.values())) transformed_labels = lb.transform(IRIS['target']) y_bin_labels = []  # 對多分類進行0-1編碼的變量
    for i in range(transformed_labels.shape[1]): y_bin_labels.append('y' + str(i)) IRIS['y' + str(i)] = transformed_labels[:, i] # 將數據集分爲訓練集和測試集
    train_x, test_x, train_y, test_y = train_test_split(IRIS[features], IRIS[y_bin_labels], \ train_size=0.7, test_size=0.3, random_state=0) return train_x, test_x, train_y, test_y, Class_dict

搭建DNN

  接下來,筆者將展現如何利用Keras來搭建一個簡單的深度神經網絡(DNN)來解決這個多分類問題。咱們要搭建的DNN的結構以下圖所示:網絡

 
DNN模型的結構示意圖

咱們搭建的DNN由輸入層、隱藏層、輸出層和softmax函數組成,其中輸入層由4個神經元組成,對應IRIS數據集中的4個特徵,做爲輸入向量,隱藏層有兩層,每層分別有5和6個神經元,以後就是輸出層,由3個神經元組成,對應IRIS數據集的目標變量的類別個數,最後,就是一個softmax函數,用於解決多分類問題而建立。
  對應以上的DNN結構,用Keras來搭建的話,其Python代碼以下:app


import keras as K # 2. 定義模型
    init = K.initializers.glorot_uniform(seed=1) simple_adam = K.optimizers.Adam() model = K.models.Sequential() model.add(K.layers.Dense(units=5, input_dim=4, kernel_initializer=init, activation='relu')) model.add(K.layers.Dense(units=6, kernel_initializer=init, activation='relu')) model.add(K.layers.Dense(units=3, kernel_initializer=init, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer=simple_adam, metrics=['accuracy'])

在這個模型中,咱們選擇的神經元激活函數爲ReLU函數,損失函數爲交叉熵(cross entropy),迭代的優化器(optimizer)選擇Adam,最初各個層的鏈接權重(weights)和偏重(biases)是隨機生成的。這樣咱們就講這個DNN的模型定義完畢了。dom

訓練及預測

  OK,定義完模型後,咱們須要對模型進行訓練、評估及預測。對於模型訓練,咱們每次訓練的批數爲1,共迭代100次,代碼以下(接以上代碼):機器學習

# 3. 訓練模型
    b_size = 1 max_epochs = 100
    print("Starting training ") h = model.fit(train_x, train_y, batch_size=b_size, epochs=max_epochs, shuffle=True, verbose=1) print("Training finished \n")

爲了對模型有個評估,感知模型的表現,須要輸出該DNN模型的損失函數的值以及在測試集上的準確率,其Python代碼以下(接以上代碼):函數

# 4. 評估模型
    eval = model.evaluate(test_x, test_y, verbose=0) print("Evaluation on test data: loss = %0.6f accuracy = %0.2f%% \n" \ % (eval[0], eval[1] * 100) )

訓練100次,輸出的結果以下(中間部分的訓練展現已忽略):學習

Starting training Epoch 1/100

  1/105 [..............................] - ETA: 17s - loss: 0.3679 - acc: 1.0000
 42/105 [===========>..................] - ETA: 0s - loss: 1.8081 - acc: 0.3095 
 89/105 [========================>.....] - ETA: 0s - loss: 1.5068 - acc: 0.4270
105/105 [==============================] - 0s 3ms/step - loss: 1.4164 - acc: 0.4667 Epoch 2/100

  1/105 [..............................] - ETA: 0s - loss: 0.4766 - acc: 1.0000
 45/105 [===========>..................] - ETA: 0s - loss: 1.0813 - acc: 0.4889
 93/105 [=========================>....] - ETA: 0s - loss: 1.0335 - acc: 0.4839
105/105 [==============================] - 0s 1ms/step - loss: 1.0144 - acc: 0.4857 ...... Epoch 99/100

  1/105 [..............................] - ETA: 0s - loss: 0.0013 - acc: 1.0000
 43/105 [===========>..................] - ETA: 0s - loss: 0.0447 - acc: 0.9767
 84/105 [=======================>......] - ETA: 0s - loss: 0.0824 - acc: 0.9524
105/105 [==============================] - 0s 1ms/step - loss: 0.0711 - acc: 0.9619 Epoch 100/100

  1/105 [..............................] - ETA: 0s - loss: 2.3032 - acc: 0.0000e+00
 51/105 [=============>................] - ETA: 0s - loss: 0.1122 - acc: 0.9608    
 99/105 [===========================>..] - ETA: 0s - loss: 0.0755 - acc: 0.9798
105/105 [==============================] - 0s 1ms/step - loss: 0.0756 - acc: 0.9810 Training finished Evaluation on test data: loss = 0.094882 accuracy = 97.78%

能夠看到,訓練完100次後,在測試集上的準確率已達到97.78%,效果至關好。
  最後是對新數據集進行預測,咱們假設一朵鳶尾花的4個特徵爲6.1,3.1,5.1,1.1,咱們想知道這個DNN模型會把它預測到哪一類,其Python代碼以下:測試

import numpy as np # 5. 使用模型進行預測
    np.set_printoptions(precision=4) unknown = np.array([[6.1, 3.1, 5.1, 1.1]], dtype=np.float32) predicted = model.predict(unknown) print("Using model to predict species for features: ") print(unknown) print("\nPredicted softmax vector is: ") print(predicted) species_dict = {v:k for k,v in Class_dict.items()} print("\nPredicted species is: ") print(species_dict[np.argmax(predicted)])

輸出的結果以下:優化

Using model to predict species for features: [[ 6.1  3.1  5.1  1.1]] Predicted softmax vector is: [[ 2.0687e-07   9.7901e-01   2.0993e-02]] Predicted species is: versicolor

若是咱們仔細地比對IRIS數據集,就會發現,這個預測結果使人至關滿意,這個鳶尾花樣本的預測結果,以人類的眼光來看,也應當是versicolor。編碼

 

最後,附上該DNN模型的完整Python代碼:
# iris_keras_dnn.py # Python 3.5.1, TensorFlow 1.6.0, Keras 2.1.5 # ======================================================== # 導入模塊
import os import numpy as np import keras as K import tensorflow as tf import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelBinarizer os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

# 讀取CSV數據集,並拆分爲訓練集和測試集 # 該函數的傳入參數爲CSV_FILE_PATH: csv文件路徑
def load_data(CSV_FILE_PATH): IRIS = pd.read_csv(CSV_FILE_PATH) target_var = 'class'  # 目標變量
    # 數據集的特徵
    features = list(IRIS.columns) features.remove(target_var) # 目標變量的類別
    Class = IRIS[target_var].unique() # 目標變量的類別字典
    Class_dict = dict(zip(Class, range(len(Class)))) # 增長一列target, 將目標變量進行編碼
    IRIS['target'] = IRIS[target_var].apply(lambda x: Class_dict[x]) # 對目標變量進行0-1編碼(One-hot Encoding)
    lb = LabelBinarizer() lb.fit(list(Class_dict.values())) transformed_labels = lb.transform(IRIS['target']) y_bin_labels = []  # 對多分類進行0-1編碼的變量
    for i in range(transformed_labels.shape[1]): y_bin_labels.append('y' + str(i)) IRIS['y' + str(i)] = transformed_labels[:, i] # 將數據集分爲訓練集和測試集
    train_x, test_x, train_y, test_y = train_test_split(IRIS[features], IRIS[y_bin_labels], \ train_size=0.7, test_size=0.3, random_state=0) return train_x, test_x, train_y, test_y, Class_dict def main(): # 0. 開始
    print("\nIris dataset using Keras/TensorFlow ") np.random.seed(4) tf.set_random_seed(13) # 1. 讀取CSV數據集
    print("Loading Iris data into memory") CSV_FILE_PATH = 'E://iris.csv' train_x, test_x, train_y, test_y, Class_dict = load_data(CSV_FILE_PATH) # 2. 定義模型
    init = K.initializers.glorot_uniform(seed=1) simple_adam = K.optimizers.Adam() model = K.models.Sequential() model.add(K.layers.Dense(units=5, input_dim=4, kernel_initializer=init, activation='relu')) model.add(K.layers.Dense(units=6, kernel_initializer=init, activation='relu')) model.add(K.layers.Dense(units=3, kernel_initializer=init, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer=simple_adam, metrics=['accuracy']) # 3. 訓練模型
    b_size = 1 max_epochs = 100
    print("Starting training ") h = model.fit(train_x, train_y, batch_size=b_size, epochs=max_epochs, shuffle=True, verbose=1) print("Training finished \n") # 4. 評估模型
    eval = model.evaluate(test_x, test_y, verbose=0) print("Evaluation on test data: loss = %0.6f accuracy = %0.2f%% \n" \ % (eval[0], eval[1] * 100) ) # 5. 使用模型進行預測
    np.set_printoptions(precision=4) unknown = np.array([[6.1, 3.1, 5.1, 1.1]], dtype=np.float32) predicted = model.predict(unknown) print("Using model to predict species for features: ") print(unknown) print("\nPredicted softmax vector is: ") print(predicted) species_dict = {v:k for k,v in Class_dict.items()} print("\nPredicted species is: ") print(species_dict[np.argmax(predicted)]) main()
連接:https://www.jianshu.com/p/1d88a6ed707e 來源:簡書
相關文章
相關標籤/搜索