python实现mnist手写数字识别

看了《python神经网络编程》,跟着书上敲了一下mnist手写数字的代码,对神经网络有了初步的了解。

此项目为三层神经网络识别,激活函数采用sigmoid函数,数据集为mnist手写数字集,训练集包括60000个样本,测试集10000个样本。

第一部分,创建神将网络模型

import numpy
import matplotlib.pyplot
#%matplotlib inline用在Jupyter notebook中(代替plt.show()),使用%matplotlib命令可以将matplotlib的图表直接嵌入到Notebook之中
%matplotlib inline 
#sigmoid函数,在这组函数中,S函数称为expit()
import scipy.special  
 
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.woh=(numpy.random.rand(self.onodes,self.hnodes)-0.5)
        
#        激活函数为sigmoid函数,使用lambda创建函数(匿名函数),方便快捷
        self.activation_function = lambda x:scipy.special.expit(x)
        
        pass
    
#     训练d代码
    def train(self,input_list,target_list):
#         将输入转换为numpy数组,dmin指定生成数组的最小维度
        inputs = numpy.array(input_list,ndmin=2).T
        targets = numpy.array(target_list,ndmin=2).T
#     计算隐藏层
        hidden_inputs = numpy.dot(self.wih,inputs)
#     调用sigmoid激活函数
        hidden_outputs = self.activation_function(hidden_inputs)
#      输出层
        final_inputs=numpy.dot(self.woh,hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        
#         计算误差
        error = targets-final_outputs
#     隐藏层误差节点反向传播的误差
        hidden_error = numpy.dot(self.woh.T,error) 
    
#       优化权重, 正常对应元素相乘,·乘是矩阵点击
#       transpose()简单来说,就相当于数学中的转置,在矩阵中,转置就是把行与列相互调换位置;
        self.woh += self.lr * numpy.dot((error * final_outputs * (1.0-final_outputs)),numpy.transpose(hidden_outputs)) 
        self.wih += self.lr * numpy.dot((hidden_error*hidden_outputs*(1.0-hidden_outputs)),numpy.transpose(inputs)) 
        
        pass
      
#     查询函数
    def query(self,inputs):

        inputs = numpy.array(inputs,ndmin=2).T
        
        hidden_inputs = numpy.dot(self.wih,inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs=numpy.dot(self.woh,hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        
        return final_outputs
        pass

第二部分 训练网络

inputnodes=28*28
hiddennodes=100
outputnodes=10
learningrate=0.1
# 创造神经网络实例
n = neuralNetwork(inputnodes,hiddennodes,outputnodes,learningrate)

# 获取mnist_train数据集
training_date_file = open("mnist_train.csv","r")
training_date_list = training_date_file.readlines()
training_date_file.close()

a=0
for record in training_date_list:
    
# 用“,”分割长的字符串值,拆分为单个值
    all_values = record.split(',')
# 第一个值为标签,忽略, 将剩余784个值转换为28*28数组
# numpy.asfarray()将文本字符串转换为实数并创建这些数字的数组,
# 因为文件是用文本读取的,每一条记录仍然是文本,用“,”分割得到的仍然是文本
# all_values[1:]/255.0*0.99)+0.01 是将输入颜色从0-255缩小到0.01-1.00,最小值为0.01是避免先前观察到的0值输入最终会人为地造成权重更新失败
    inputs =( numpy.asfarray(all_values[1:])/255.0*0.99)+0.01
    
#     将训练目标标签从字符串形式转换为整数形式,正确元素设置为0.99 标签“0”转换为整数0
    targets = numpy.zeros(outputnodes)+0.01
    targets[int(all_values[0])]=0.99
    n.train(inputs,targets)
    
#     a用来计数,查看训练进度
    a=a+1
    if(a%10000==0):
        print(a)
        
    pass

网络训练结束

第三部分 网络测试

# 测试网络

test_date_file = open("mnist_test.csv","r")
test_date_list = test_date_file.readlines()
test_date_file.close()

# 创建空列表,用作积分卡,在测试每条记录之后都会进行更新
scorecard=[]
b=0
for record in test_date_list:
    all_values = record.split(',')
    inputs = (numpy.asfarray(all_values[1:])/255.0*0.99)+0.01
#     目标标签
    correct_label=int(all_values[0])
    outputs = n.query(inputs)
#     测试所得标签
    label=numpy.argmax(outputs)
    
#   如果相等,在记分卡追加1,不相等0
    if(label==correct_label):
        scorecard.append(1)
    else:
        scorecard.append(0)
        
#    b用来计数,查看测试进度   
    b= b+1
    if(b%1000==0):
        print(b)
        
    pass

#输出正确率
scorecard_array=numpy.asarray(scorecard)
print("Accuracy= ",scorecard_array.sum()/scorecard_array.size)

结果:

模型改进:

1.调整学习率,变大,变小

  • 当前学习率为0.1,准确率为0.9477
  • 调整学习率为0.2,学习率有所提升.

  • 调整为0.05,学习率有所下降

2.多次运行,训练一次称为一个世代

3.改变网络形状,改变隐藏节点的数量等

  • 11
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值