# python三層神經網絡構建 識別手寫數字

保存一下我簡短學習的神經網絡(只是最最最基礎的那種三層的神經網絡而已)。

功能:訓練、識別手寫數字,統計正確率。

!裏面用到的訓練集和測試集是網上下載的,如果有需要可以私聊我。。。。因爲我不知道怎麼傳文件????

 

# 神經網絡構建 識別手寫數字

import numpy
import scipy.special
import scipy.misc
import matplotlib.pyplot

# 神經網絡定義
class neuralNetwork:
    # 初始化神經網絡參數
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # 輸入層、隱藏層、輸出層的結點個數
        self.inodes = inputnodes    # 輸入層節點個數
        self.hnodes = hiddennodes   # 隱藏層節點個數
        self.onodes = outputnodes   # 輸出層節點個數

        # 學習率
        self.lr = learningrate

        # 權值矩陣
        self.wih = (numpy.random.rand(self.hnodes, self.inodes) - 0.5)  # 輸入層與隱藏層之間權值
        self.who = (numpy.random.rand(self.onodes, self.hnodes) - 0.5)  #隱藏層與輸出層之間權值
        '''正態分佈採樣權重
        self.win = numpy.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes, self.inodes))
        self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes))
        '''
        # S函數
        self.activation_function = lambda x: scipy.special.expit(x) # lambda爲快速創建函數,x爲參數,返回scipy.special.expit(x)
        pass

    # 訓練神經網絡
    def train(self, inputs_list, targets_list):
        inputs = numpy.array(inputs_list, ndmin=2).T    # 將輸入數據轉換爲列矩陣
        targets = numpy.array(targets_list, ndmin=2).T  # 將正確答案轉換爲列矩陣

        hidden_inputs = numpy.dot(self.wih, inputs)     # 隱藏層輸入爲權值矩陣與輸入矩陣的乘積
        hidden_outputs = self.activation_function(hidden_inputs)    # 隱藏層輸出 經過S函數變換

        final_inputs = numpy.dot(self.who, hidden_outputs)  # 輸出層輸入爲權值矩陣與隱藏層輸出矩陣的乘積
        final_outputs = self.activation_function(final_inputs)  # 輸出層輸出 經過S函數變換

        output_errors = targets - final_outputs     # 輸出結果與正確答案誤差

        hidden_errors = numpy.dot(self.who.T, output_errors)    # 隱藏層誤差爲 權值矩陣的轉職與輸出誤差矩陣的乘積

        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),    # 根據誤差更新權值矩陣
                                        numpy.transpose(hidden_outputs))

        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
                                        numpy.transpose(inputs))

        pass

    # 查詢
    def query(self, inputs_list):
        inputs = numpy.array(inputs_list, ndmin=2).T    # 將輸入數據轉爲輸入矩陣

        hidden_inputs = numpy.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)

        final_inputs = numpy.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs    # 返回最後結果
        pass


# 神經網絡初始化
input_nodes = 784
hidden_nodes = 100
output_nodes = 10
learning_rate = 0.2

n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)   # 新建神經網絡

#準備訓練
training_data_file = open("mnist_train.csv", 'r')   # 打開訓練文件
training_data_list = training_data_file.readlines()    # 存訓練數據
training_data_file.close()

for record in training_data_list:   # 遍歷訓練數據
    all_values = record.split(',')  # 以,分割數據
    inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 爲保證輸出在0-1,將輸入數據範圍優化在0.01-1之間
    targets = numpy.zeros(output_nodes) + 0.01
    targets[int(all_values[0])] = 0.99  # 將正確答案位置設爲0.99,其他位置爲0.01
    n.train(inputs, targets)    # 訓練
    pass

'''***********************************測試輸出正確率******************************
# 輸出正確數字
test_data_file = open("mnist_test.csv", 'r')        # 打開測試數據文件
test_data_list = test_data_file.readlines()
test_data_file.close()
all_values = test_data_list[0].split(',')
print(all_values[0])

# 輸出像素點組成的圖片
image_array = numpy.asfarray(all_values[1:]).reshape((28,28))
#image_array = scipy.misc.imread("1.png", flatten=True)
#img_data = 255.0 - image_array.reshape(784)
#img_data = (img_data / 255.0 * 0.99) + 0.01
matplotlib.pyplot.imshow(image_array , cmap='Greys', interpolation='None')
matplotlib.pyplot.show()

# 查詢結果
n.query((numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01) # 操作一波讓輸入在0—1之間
print(n.query((numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01))  # 輸出神經網絡判斷結果

#記錄正確率
scorecard = []

for record in test_data_list:   # 循環測試數組
    all_values = record.split(',')  # 分割數據
    correct_label = int(all_values[0])  # 記錄正確數據,即第一個數字
 #   print(correct_label, "correct label")

    inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 輸入數據
    outputs = n.query(inputs)   #輸出查詢結果
    label = numpy.argmax(outputs)   # 經過神經網絡判斷得到的數字
#    print(label, "network's answer")

    if(label == correct_label): # 如果判斷結果與正確數據相同,記錄1
        scorecard.append(1)
    else:                       # 如果判斷錯誤,記錄0
        scorecard.append(0)

# 輸出正確率
scorecard_array = numpy.asarray(scorecard)
print("正確率=", scorecard_array.sum() / scorecard_array.size)
'''

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章