天天看點

4 機器學習實踐之手寫數字識别- 神經網絡識别

在 初步特征選擇及線性識别篇中提到機器學習算法輸入資料分為原始資料,特征工程(人工選擇特征)及深度學習(機器自己計算)。 在前面采用了特征工程的方案,識别率也在85%左右。 識别率不是很高,這跟特征工程選擇的工程不全有關,繼續選擇各種工程會比較麻煩,以後有機會再細研究。 之後打算從原始資料輸入及深度學習方面着手來解決這個手寫數字識别功能。 

接下去的過程中主要功能都将盡量采用自己編寫的代碼來實作并示範。

BP神經網絡的python代碼實作見http://blog.csdn.net/net_wolf_007/article/details/52055718, 這裡不再給點。

BP神經網絡識别

結果說明

識别結果目前為87%,比前面的識别結果好些。不過準确率有待提高。

訓練時間花得太長,40,000個資料訓練10次,花了50分鐘!這跟神經網絡代碼有并,需要優化。

下一步計劃:

1. 優化代碼

2. 提高識别率:

添加偏置, 

添加dropout功能

再到深度學習功能識别

識别說明

這裡采用4層網絡結構來識别 NeuralNetWork([28*28, 256, 100, 10])。

參數個數:256*28*28 + 100*256 + 10*100 = 227,304個。

由于神經網絡輸出的是10個節點,每個節點輸出一個數字。而我們的資料的輸入隻是一位資料,是以需要對他們進行轉換。以此實作了兩個工具函數:format_y及unformat_y.

對于輸入資料也要做下預處理,把原來[0-256)的資料,轉變成[0-1).

需要引用統計報告函數: from sklearn.metrics import classification_report 

now_str() 傳回目前時間格式化結果字元串
           

實作代碼如下:

def format_y(data):
    y_tmp = np.zeros((len(data), 10))
    for i in range(len(data)):
        y_tmp[i, data[i]] = 1
    return y_tmp

def unformat_y(data):
    m = max(data)
    for j, val in enumerate(data):
        if val == m:
            return j
    return 11

def load_source(filename):
    with open(filename, "r") as file:
        lines = file.readlines()
        return lines[1:]

if __name__ == '__main__':
    # print("test neural network")
    np.set_printoptions(precision=3, suppress=True)
    data_lines = load_source("./data/train.csv")
    for i in range(len(data_lines)):
        data_lines[i] = data_lines[i].split(',')
    data_lines = np.array(data_lines).astype(np.int)

    x_data = data_lines[:, 1:]/256 #格式化資料
    y_data = data_lines[:, 0]

    TEST = -2000
    x_train = x_data[:TEST]
    y_train = y_data[:TEST]
    x_test = x_data[TEST:]
    y_test = y_data[TEST:]
    print(now_str(), "train len", len(x_train), "test len:", len(x_test))

    print(new_str(), "start train...")
    network = NeuralNetWork([28*28, 256, 100, 10])
    network.fit(x_train=x_train, y_train=format_y(y_train), learning_rate=0.1, epochs=10, shuffle=False)

    print(now_str(), "start train...")
    predicts = []
    for i in range(len(x_test)):
        predict = network.predict(x_test[i])
        predicts.append(unformat_y(predict))

    predicts = np.array(predicts)

    ok_cnt = sum([1 for i in range(len(predicts)) if predicts[i] == y_test[i]])

    print(ok_cnt, len(predicts), "%.3f" % (float(ok_cnt)/len(predicts)))
    print(classification_report(y_test, predicts))
           

輸出結果:

/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /XXX/機器學習/number/NeuralNetwork.py
Jul-28-16 <span style="font-family: Arial, Helvetica, sans-serif;">20:56</span><span style="font-family: Arial, Helvetica, sans-serif;">:06 train len 40000 test len: 2000</span>
Jul-28-16 21:50:46 start train...
1732 2000 0.866
             precision    recall  f1-score   support

          0       0.84      0.95      0.90       197
          1       0.94      0.96      0.95       225
          2       0.80      0.88      0.84       190
          3       0.88      0.78      0.83       198
          4       0.90      0.83      0.87       226
          5       0.80      0.75      0.77       162
          6       0.94      0.91      0.92       216
          7       0.97      0.87      0.92       202
          8       0.80      0.79      0.80       179
          9       0.78      0.89      0.83       205

avg / total       0.87      0.87      0.87      2000


Process finished with exit code 0