著作權宣告:本文為博主ExcelMann的原創文章,未經博主允許不得轉載,
python實作RBF神經網路識別Mnist資料集
作者:ExcelMann,轉載需注明,
話不多說,直接貼代碼,代碼有注釋,
# Author:Xuangan, Xu
# Data:2020-11-11
"""
RBF神經網路
-----------------
設計RBF神經網路實作手寫數字的識別問題
資料集:Mnist資料集
"""
import os
import struct
import math
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from scipy import *
from scipy.linalg import norm, pinv
from sklearn.cluster import KMeans
class RBFNet:
def __init__(self,sample_num,input_nodes,hidden_nodes,output_nodes):
# 初始化網路各層結點個數
self.i_nodes = input_nodes # 即每個樣本的維數
self.h_nodes = hidden_nodes # 即中心點個數
self.o_nodes = output_nodes
# 初始化中心節點、方差、權重以及矩陣G(G[i][j]表示第i個樣本在第j個中心節點的高斯函式值)
self.centers = [random.uniform(-1,1,input_nodes) for i in range(hidden_nodes)]
self.beta = 0
self.w = random.uniform(-0.5,0.5,(hidden_nodes,output_nodes))
self.G = np.zeros((sample_num,hidden_nodes))
def culMse(self,pre_y,y):
"""
計算均方誤差
:param pre_y: 預測值(60000 X 10)
:param y: 期望值(60000 X 10)
"""
totalError = 0
for i in range(len(y)):
for j in range(10):
totalError += (y[i][j]-pre_y[i][j])**2
return totalError/len(y)
def calBasis(self,X,Xi):
"""
計算隱含層結點值
:param X:輸入值,大小為維度
:param Xi:第i個中心點,大小為維度
:return:回傳該隱含層結點的值
"""
return exp((-np.linalg.norm(X-Xi)**2)/2*self.beta**2)
def calHiddenValue(self,X):
"""
計算矩陣G
:param X:輸入樣本X
"""
for ci,c in enumerate(self.centers):
for xi,x in enumerate(X):
self.G[xi][ci] = self.calBasis(c, x)
def train(self,X,Y):
"""
訓練網路,由閉式解得到網路權重w
:param X:輸入樣本X,大小為(樣本個數, 784)
:param Y:標簽資料Y,大小為(樣本個數,10)
"""
# 選擇中心點
estimator = KMeans(n_clusters=1000) # 劃分為1000類
estimator.fit(X)
self.centers = estimator.cluster_centers_ # 得到1000個類別的各自中心點
# 更新方差beta
max_distance = 0 # 所選取中心之間的最大距離
for i in range(self.h_nodes):
for j in range(self.h_nodes-i):
dis = np.linalg.norm(self.centers[i]-self.centers[j])
if(dis > max_distance):
max_distance = dis
self.beta = max_distance/sqrt(2*self.h_nodes)
# 計算矩陣G
self.calHiddenValue(X)
# 由閉式解,得到網路權重w
self.w = dot(pinv(dot(self.G.T,self.G)), self.G.T).dot(Y)
# 計算loss
pre_y = self.G.dot(self.w)
print(f"loss:{self.culMse(pre_y,Y)}")
def estimate(self,X,Y):
"""
測驗資料,回傳預測準確率
:param X: 測驗資料,200 X 784維
:param Y: 測驗資料的標簽,200 X 10維
"""
hidden_v = np.zeros(self.h_nodes) # 隱含層結點值
correct_num = 0
# 遍歷測驗樣本
for i in range(X.shape[0]):
# 計算該測驗樣本對應的隱藏層結點值
for j in range(self.h_nodes):
hidden_v[j] = self.calBasis(X[i],self.centers[j])
output = hidden_v.dot(self.w) # 網路輸出值ouput
pre_y = np.argmax(output) # 預測標簽
y = np.argmax(Y[i]) # 期望標簽
if y == pre_y:
correct_num = correct_num+1
return correct_num/X.shape[0]
if __name__ == "__main__":
# 通過tensorflow讀取mnist資料,并對讀取到的資料進行處理
mnist = tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y) = mnist.load_data()
# 將影像資料轉為0-1的范圍
train_data = np.zeros((60000, 784))
train_label = np.zeros((60000, 10))
test_data = np.zeros((10000, 784))
test_label = np.zeros((10000, 10))
for i in range(60000): # 處理訓練資料
train_data[i] = (np.array(train_x[i]).flatten())/255
temp = np.zeros(10)
temp[train_y[i]] = 1
train_label[i] = temp
for i in range(10000): # 處理測驗資料
test_data[i] = (np.array(test_x[i]).flatten())/255
temp = np.zeros(10)
temp[test_y[i]] = 1
test_label[i] = temp
# RBF網路的輸入、隱含、輸出層結點個數
input_nodes = 784
hidden_nodes = 1000
output_nodes = 10
sample_num = 60000
rbfNet = RBFNet(sample_num,input_nodes,hidden_nodes,output_nodes)
rbfNet.train(train_data,train_label)
accuracy = rbfNet.estimate(test_data,test_label)
print(f"準確率:{accuracy}")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/223111.html
標籤:其他
上一篇:centernet 訓練自己資料集ubuntu16.04, pytorch1.1.0,cuda10.0
下一篇:教你用python畫動態愛心表白
