前言
訓練時讀入的是.mat格式的訓練集,測試正確率時用的是png格式的圖片python
代碼
#!/usr/bin/env python3 # coding=utf-8 import math import sys import os import numpy as np from PIL import Image import scipy.io as sio def sigmoid(x): return np.array(list(map(lambda i: 1 / (1 + math.exp(-i)), x))) def get_train_pattern(): # 返回訓練集的特徵和標籤 # current_dir = os.getcwd() current_dir = "/home/lxp/F/developing_folder/intelligence_system/bpneuralnet/" train = sio.loadmat(current_dir + "mnist_train.mat")["mnist_train"] train_label = sio.loadmat( current_dir + "mnist_train_labels.mat")["mnist_train_labels"] train = np.where(train > 180, 1, 0) # 二值化 return train, train_label def get_test_pattern(): # 返回測試集 # base_url = os.getcwd() + "/test/" base_url = "/home/lxp/F/developing_folder/intelligence_system/bpneuralnet/mnist_test/" test_img_pattern = [] for i in range(10): img_url = os.listdir(base_url + str(i)) t = [] for url in img_url: img = Image.open(base_url + str(i) + "/" + url) img = img.convert('1') # 二值化 img_array = np.asarray(img, 'i') # 轉化爲int數組 img_vector = img_array.reshape( img_array.shape[0] * img_array.shape[1]) # 展開成一維數組 t.append(img_vector) test_img_pattern.append(t) return test_img_pattern class BPNetwork: # 神經網絡類 def __init__(self, in_count, hiden_count, out_count, in_rate, hiden_rate): """ :param in_count: 輸入層數 :param hiden_count: 隱藏層數 :param out_count: 輸出層數 :param in_rate: 輸入層學習率 :param hiden_rate: 隱藏層學習率 """ # 各個層的節點數量 self.in_count = in_count self.hiden_count = hiden_count self.out_count = out_count # 輸入層到隱藏層連線的權重隨機初始化 self.w1 = 0.2 * \ np.random.random((self.in_count, self.hiden_count)) - 0.1 # 隱藏層到輸出層連線的權重隨機初始化 self.w2 = 0.2 * \ np.random.random((self.hiden_count, self.out_count)) - 0.1 # 隱藏層偏置向量 self.hiden_offset = np.zeros(self.hiden_count) # 輸出層偏置向量 self.out_offset = np.zeros(self.out_count) # 輸入層學習率 self.in_rate = in_rate # 隱藏層學習率 self.hiden_rate = hiden_rate def train(self, train_img_pattern, train_label): if self.in_count != len(train_img_pattern[0]): sys.exit("輸入層維數與樣本維數不等") # for num in range(10): # for num in range(10): for i in range(len(train_img_pattern)): if i % 5000 == 0: print(i) # 生成目標向量 target = [0] * 10 target[train_label[i][0]] = 1 # for t in range(len(train_img_pattern[num])): # 前向傳播 # 隱藏層值等於輸入層*w1+隱藏層偏置 hiden_value = np.dot( train_img_pattern[i], self.w1) + self.hiden_offset hiden_value = sigmoid(hiden_value) # 計算輸出層的輸出 out_value = np.dot(hiden_value, self.w2) + self.out_offset out_value = sigmoid(out_value) # 反向更新 error = target - out_value # 計算輸出層偏差 out_error = out_value * (1 - out_value) * error # 計算隱藏層偏差 hiden_error = hiden_value * \ (1 - hiden_value) * np.dot(self.w2, out_error) # 更新w2,w2是j行k列的矩陣,存儲隱藏層到輸出層的權值 for k in range(self.out_count): # 更新w2第k列的值,鏈接隱藏層全部節點到輸出層的第k個節點的邊 # 隱藏層學習率×輸入層偏差×隱藏層的輸出值 self.w2[:, k] += self.hiden_rate * out_error[k] * hiden_value # 更新w1 for j in range(self.hiden_count): self.w1[:, j] += self.in_rate * \ hiden_error[j] * train_img_pattern[i] # 更新偏置向量 self.out_offset += self.hiden_rate * out_error self.hiden_offset += self.in_rate * hiden_error def test(self, test_img_pattern): """ 測試神經網絡的正確率 :param test_img_pattern[num][t]表示數字num的第t張圖片 :return: """ right = np.zeros(10) test_sum = 0 for num in range(10): # 10個數字 # print("正在識別", num) num_count = len(test_img_pattern[num]) test_sum += num_count for t in range(num_count): # 數字num的第t張圖片 hiden_value = np.dot( test_img_pattern[num][t], self.w1) + self.hiden_offset hiden_value = sigmoid(hiden_value) out_value = np.dot(hiden_value, self.w2) + self.out_offset out_value = sigmoid(out_value) # print(out_value) if np.argmax(out_value) == num: # 識別正確 right[num] += 1 print("數字%d的識別正確率%f" % (num, right[num] / num_count)) # 平均識別率 print("平均識別率爲:", sum(right) / test_sum) """ def test1: """ def run(): # 讀入訓練集 train, train_label = get_train_pattern() # 讀入測試圖片 test_pattern = get_test_pattern() # 神經網絡配置參數 in_count = 28 * 28 hiden_count = 6 out_count = 10 in_rate = 0.1 hiden_rate = 0.1 bpnn = BPNetwork(in_count, hiden_count, out_count, in_rate, hiden_rate) bpnn.train(train, train_label) bpnn.test(test_pattern) # 單張測試 # 識別單獨一張圖片,返回識別結果 """ while True: img_name = input("輸入要識別的圖片\n") base_url = "/home/lxp/F/developing_folder/intelligence_system/bpneuralnet/" img_url = base_url + img_name img = Image.open(img_url) img = img.convert('1') # 二值化 img_array = np.asarray(img, 'i') # 轉化爲int數組 # 獲得圖片的特徵向量 img_v = img_array.reshape(img_array.shape[0] * img_array.shape[1]) # 展開成一維數組 bpnn.test1(img_v) """ if __name__ == "__main__": run() # train, train_label = get_train_pattern() # print(train_label[5][0]) # test = get_test_pattern()
數據集下載: 連接: https://pan.baidu.com/s/1ldWTSqVUm6l1cc4EDOzHpQ 提取碼: mm93數組