保存一下我簡短學習的神經網絡(只是最最最基礎的那種三層的神經網絡而已)。
功能:訓練、識別手寫數字,統計正確率。
!裏面用到的訓練集和測試集是網上下載的,如果有需要可以私聊我。。。。因爲我不知道怎麼傳文件????
# 神經網絡構建 識別手寫數字
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)
'''