Halcom 发表于 2018-5-27 22:07:10

基于极限学习机的手写数字识别

基于极限学习机的手写数字识别
运行结果视频:https://pan.baidu.com/s/1x2wGGBZ8iBIEYU2IZRv0OQ

# -*- coding: utf-8 -*-
"""
Created on Sun May 20 22:43:31 2018

@author: ysw
"""
'''https://blog.csdn.net/zxl55/article/details/79507110'''
#from PIL import Image
import numpy as np
from scipy import io as spio
from scipy import optimize
from matplotlib import pyplot as plt
#from sklearn import datasets
#from sklearn.preprocessing import StandardScaler
import time

#引入包含数据验证方法的包
from sklearn import metrics

class Extreme_Learning_Machine(object):

    def __init__(self,X,y,num_hidden):
      self.data_x = np.atleast_2d(X)       #判断输入训练集是否大于等于二维; 把x_train()取下来
      self.data_y = np.array(y).flatten()#a.flatten()把a放在一维数组中,不写参数默认是“C”,也就是先行后列的方式,也有“F”先列后行的方式; 把 y_train取下来
      self.num_data = len(self.data_x)   #训练数据个数
      self.num_feature = self.data_x.shape;#shape[] 读取矩阵的长度,比如shape就是读取矩阵第一维度的长度 (120行,4列,所以shape==120,shapep==4)
      self.num_hidden = num_hidden;#隐藏层节点个数

      #随机生产权重(从-1,到1,生成(num_feature行,num_hidden列))
      self.w = np.random.uniform(-1, 1, (self.num_feature, self.num_hidden))

      #随机生成偏置,一个隐藏层节点对应一个偏置
      for i in range(self.num_hidden):
            b = np.random.uniform(-0.6, 0.6, (1, self.num_hidden))
            self.first_b = b

      #生成偏置矩阵,以隐藏层节点个数4为行,样本数120为列
      for i in range(self.num_data-1):
            b = np.row_stack((b, self.first_b))#row_stack 以叠加行的方式填充数组
      self.b = b
      
    #定义sigmoid函数
    def sigmoid(self,x):
      return 1.0 / (1 + np.exp(-x))

    def train(self,x_train,y_train,classes):
      mul = np.dot(self.data_x, self.w)    #输入乘以权重
      add = mul + self.b                        #加偏置
      H = self.sigmoid(add)                #激活函数

      H_ = np.linalg.pinv(H)               #求广义逆矩阵
      #print(type(H_.shape))

      #将只有一列的Label矩阵转换,例如,iris的label中共有三个值,则转换为3列,以行为单位,label值对应位置标记为1,其它位置标记为0
      self.train_y = np.zeros((self.num_data,classes))#初始化一个120行,3列的全0矩阵
      for i in range(0,self.num_data):
            self.train_y] = 1   #对应位置标记为1

      self.out_w = np.dot(H_,self.train_y)#求输出权重

    def predict(self,x_test):
      self.t_data = np.atleast_2d(x_test)    #测试数据集
      self.num_tdata = len(self.t_data)      #测试集的样本数
      self.pred_Y = np.zeros((x_test.shape))#初始化

      b = self.first_b

      #扩充偏置矩阵,以隐藏层节点个数4为行,样本数30为列
      for i in range(self.num_tdata-1):
            b = np.row_stack((b, self.first_b))#以叠加行的方式填充数组

         #预测
      self.pred_Y = np.dot(self.sigmoid(np.dot(self.t_data,self.w)+b),self.out_w)

      #取输出节点中值最大的类别作为预测值
      self.predy = []
      for i in self.pred_Y:
            L = i.tolist()
            self.predy.append(L.index(max(L)))

    def score(self,y_test):
      print("准确率:")
      #使用准确率方法验证
      print(metrics.accuracy_score(y_true=y_test, y_pred=self.predy))

# 显示100个数字
def display_data(imgData):
    sum = 0
    '''
    显示100个数(若是一个一个绘制将会非常慢,可以将要画的数字整理好,放到一个矩阵中,显示这个矩阵即可)
    - 初始化一个二维数组
    - 将每行的数据调整成图像的矩阵,放进二维数组
    - 显示即可
    '''
    m,n = imgData.shape
    width = np.int32(np.round(np.sqrt(n)))
    height = np.int32(n/width);
    rows_count = np.int32(np.floor(np.sqrt(m)))
    cols_count = np.int32(np.ceil(m/rows_count))
    pad = 1
    display_array = -np.ones((pad+rows_count*(height+pad),pad+cols_count*(width+pad)))
    for i in range(rows_count):
      for j in range(cols_count):
            if sum >= m: #超过了行数,退出当前循环
                break;
            display_array = imgData.reshape(height,width,order="F")    # order=F指定以列优先,在matlab中是这样的,python中需要指定,默认以行
            sum += 1
      if sum >= m:#超过了行数,退出当前循环
            break;
            
#    plt.imshow(np.transpose(display_array),cmap='gray')   #显示灰度图像
    plt.imshow(display_array, cmap='gray')   #显示灰度图像
    plt.axis('off')
    plt.show()

# 加载mat文件
def loadmat_data(fileName):
    return spio.loadmat(fileName)

if __name__ == "__main__":
    # 加载数据
    data_img = loadmat_data("data_digits.mat")
    X = data_img['X']
    y = data_img['y']
   
    m,n = X.shape
    ## 随机显示几行数据
    rand_indices = ]# 生成100个0-m的随机数
    display_data(X)   # 显示100个数字   
   
    input_layer_size = 400;
    num_hidden = 25;
    classes = 10;
   
    start = time.time()
    ELM = Extreme_Learning_Machine(X, y, num_hidden)   #训练数据集,训练集的label,隐藏层节点个数
    ELM.train(X, y, classes)
    print ('\n')
    print ('\n')
    print ( '执行时间:' )
    print ( time.time()-start )
    '''预测'''
    ELM.predict(X)
#    ELM.score(y)
   
    # 计算得分
    p = ELM.predy;
#    print ('预测准确度为:')
#    print(metrics.accuracy_score(y_true=y, y_pred=p))
    p = np.array(p)
    p = np.reshape(p, [-1, 1] )
    print ('预测准确度为:')
    print ( np.mean(np.float64(p == y.reshape(-1,1))*100) )   
    res = np.hstack((p,y.reshape(-1,1)))
    np.savetxt("predict.csv", res, delimiter=',')

百度网盘链接:链接:https://pan.baidu.com/s/15MPObcNGKfvoYTXE9woG8w 密码:u0na



asqbtzzt 发表于 2020-5-25 22:46:18

谢谢楼主分享
页: [1]
查看完整版本: 基于极限学习机的手写数字识别