《python神经网络编程》二

训练自己的神经网络

首先定义一个神经网络:
代码如下:

import numpy
import scipy.special
class neuralNetwork:
#类似于java的构造方法,所有方法都有一个self参数,相当于class内部方法都带有this指
#指针一样,指向当前对象
    def __init__(self,inodes,hnodes,onodes,learningRate):
        self.inode = inodes
        self.hnode = hnodes
        self.onode = onodes
        self.lr = learningRate
        #weight link matrice 输入连接数目的根号分之1,均差是0,方差是输入连接数目的 
        ##根号分之1  ,科学家的经验所得,是个正太分布,从概率分布中进行采样,
        ## 其次是,输入的权重不能相等。因为如果相等,通过误差反向传播之后,权重还##是一样,但是我们训练网络其实是为了每一个神经元逼近事物的各个特征,当然每个##特征不一样的
        self.wih = numpy.random.normal(0.0,pow(self.hnode,-0.5),(self.hnode,self.inode))
        self.who = numpy.random.normal(0.0,pow(self.onode,-0.5),(self.onode,self.hnode))
       ## 激活函数采用sigmoid函数,但是这个不是zero-centered,收敛速度慢。
        ## 激活函数 S(x)就是这个expit(x)
         self.activateFunc = lambda x:scipy.special.expit(x)
        pass
##训练网络
    def train(self,inputList,targetList):
#1 先得到输入数组的转置矩阵
        inputs = numpy.array(inputList,ndmin=2).T
# 隐藏层的输入是对ih的矩阵和输入矩阵点乘
        hiddenInputs = numpy.dot(self.wih,inputs)  
# 隐藏层的输出是经过激活函数非线性化
        hiddenOutputs = self.activateFunc(hiddenInputs) 
# 隐藏层的输出就是相当于前面的输入信号,最后输出层的输入  是ho权重矩阵和隐藏层的输出做点乘    
        finalInputs = numpy.dot(self.who,hiddenOutputs) 
        finalOutputs = self.activateFunc(finalInputs)          
## 最后   targetOutputs 是样本值
        targetOutputs = numpy.array(targetList,ndmin=2).T
## 输出层的误差
        outputErrors = targetOutputs-finalOutputs
## 隐藏层的误差反向传播,是权重矩阵的转置,和输出层的误差矩阵点乘
        hiddenErrors = numpy.dot(self.who.T,outputErrors)
       
        ##update weight matrice 更新权重矩阵参数
        self.wih += self.lr*numpy.dot(hiddenErrors*hiddenOutputs*(1-hiddenOutputs),numpy.transpose(inputs))
        self.who += self.lr*numpy.dot(outputErrors*finalOutputs*(1-finalOutputs),numpy.transpose(hiddenOutputs)) 
        pass
## 测试网络
    def query(self,inputList):
        inputs = numpy.array(inputList,ndmin=2).T

        hiddenInputs = numpy.dot(self.wih,inputs)  
        hiddenOutputs = self.activateFunc(hiddenInputs)
        
        finalInputs = numpy.dot(self.who,hiddenOutputs) 
        finalOutputs = self.activateFunc(finalInputs)
        return finalOutputs


##测试
inputNodes=784
hiddenNodes=100
outputNodes =10
learningRate =0.3
##实例化神经网络
n = neuralNetwork(inputNodes,hiddenNodes,outputNodes,learningRate)
##读取训练数据
trainDataFile =open('E:/neuralNetwork/mnist_train_100.csv',"r")
trainDataList = trainDataFile.readlines()
trainDataFile.close()
##train the data

#go through all data in train set
for record in trainDataList:
    allValues = record.split(',')
    ##scale and shift input data
## 训练数据的归一化,是数据在0.01到1变化
## allValues[0]是标签值,也就是样本值。后面的二进制数据是图片转成二进制的
    scaledInputs = (numpy.asfarray(allValues[1:])/255*0.99)+0.01
    ## create the target output values
##期望输出,其他是0.01 ,样本值对应的索引,是0.99
    targets = numpy.zeros(outputNodes)+0.01
    targets[int(allValues[0])] =0.99
    ##每条数据都调用一次训练方法
    n.train(scaledInputs,targets) 
print("has trained successfully")
##load test data
#
testDataFile =open('E:/neuralNetwork/mnist_test_10.csv',"r")
testDataList = testDataFile.readlines()                           
testDataFile.close()  
firstTestLine = testDataList[0]
testallValues = firstTestLine.split(',')  
result = n.query(numpy.asfarray(testallValues[1:])/255*0.99+0.01) 
print(result)
scorecard=[]
for record in testDataList:
    testAllValues =record.split(',')
    correctLabel=int(testAllValues[0])
    print(correctLabel,"correct label :")
    testInputs = numpy.asfarray(testAllValues[1:])/255*0.99+0.01
    testOutputs = n.query(testInputs)
    #get the highest value correspond to label
    label =numpy.argmax(testOutputs)
    print(label,"neuralNetwork answer is ")
    if(label ==correctLabel):
        scorecard.append(1)
    else:
        scorecard.append(0)
print(scorecard)

输出结果:数组输出第8位也就是索引7 ,是最大的,那这个图片就是数字

has trained successfully
[[ 0.0439157 ]
 [ 0.01209635]
 [ 0.00872318]
 [ 0.11759458]
 [ 0.07145463]
 [ 0.01963777]
 [ 0.01497414]
 [ 0.91942315]
 [ 0.03667926]
 [ 0.03500161]]
7 correct label :
7 neuralNetwork answer is 
2 correct label :
2 neuralNetwork answer is 
1 correct label :
1 neuralNetwork answer is 
0 correct label :
0 neuralNetwork answer is 
4 correct label :
4 neuralNetwork answer is 
1 correct label :
1 neuralNetwork answer is 
4 correct label :
4 neuralNetwork answer is 
9 correct label :
4 neuralNetwork answer is 
5 correct label :
1 neuralNetwork answer is 
9 correct label :
7 neuralNetwork answer is 
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0]

不管怎么样,后面虽然有错误的,但是我们训练集小才100 条记录。下面我们用60000条记录的训练集训练。
前面神经网络定义都一样,下面的测试不太一样

inputNodes=784
hiddenNodes=100
outputNodes =10
learningRate =0.1
n = neuralNetwork(inputNodes,hiddenNodes,outputNodes,learningRate)
trainDataFile =open('E:/neuralNetwork/mnist_train.csv',"r")
trainDataList = trainDataFile.readlines()
trainDataFile.close()
##train the data

#go through all data in train set
for record in trainDataList:
    allValues = record.split(',')
    ##scale and shift input data
    scaledInputs = (numpy.asfarray(allValues[1:])/255*0.99)+0.01
    ## create the target output values
    targets = numpy.zeros(outputNodes)+0.01
    targets[int(allValues[0])] =0.99
    n.train(scaledInputs,targets) 
print("has trained successfully")
##load test data
#
testDataFile =open('E:/neuralNetwork/mnist_test.csv',"r")
testDataList = testDataFile.readlines()                           
testDataFile.close()  
firstTestLine = testDataList[0]
testallValues = firstTestLine.split(',')  
result = n.query(numpy.asfarray(testallValues[1:])/255*0.99+0.01) 
print(result)
scorecard=[]
for record in testDataList:
    testAllValues =record.split(',')
    correctLabel=int(testAllValues[0])
    testInputs = numpy.asfarray(testAllValues[1:])/255*0.99+0.01
    testOutputs = n.query(testInputs)
    #get the highest value correspond to label
    label =numpy.argmax(testOutputs)
    if(label ==correctLabel):
        scorecard.append(1)
    else:
        scorecard.append(0)
scorearray = numpy.asarray(scorecard)
print("records length :",scorearray.size)
print("performance= ",scorearray.sum()/scorearray.size)

最后输出有95%的正确率:

has trained successfully
[[ 0.01576339]
 [ 0.00644632]
 [ 0.00516604]
 [ 0.01209309]
 [ 0.00353169]
 [ 0.00112428]
 [ 0.00835384]
 [ 0.98973284]
 [ 0.00217241]
 [ 0.00417368]]
records length : 10000
performance=  0.95

接下来我们改变学习率,看一下对正确率有什么变化

import matplotlib.pylab as pyl
import numpy as np 
## 定义画散点图的函数
def draw_scatter():
   
    x1=[]
    y1=[]
    dataFile =open('E:/neuralNetwork/lr.csv',"r")
    dataList = dataFile.readlines()
    dataFile.close()
    for record in dataList:
        allValues = record.split(',')
        x1.append(allValues[0])
        y1.append(allValues[1])    
    print(x1)
    print(y1)
    pyl.plot(x1,y1,'ob')
    pyl.title("learningRate--->precision")
    pyl.xlabel("learningRate")
    pyl.ylabel("precision")
    pyl.ylim(0.9100,0.9500)
    pyl.xlim(0.00,0.70)
    pyl.show()

draw_scatter()

输出结果:

['0.3', '0.4', '0.5', '0.6', '0.2', '0.1', '0.05', '0.01']
['0.9463\n', '0.9363\n', '0.9229\n', '0.9135\n', '0.9472\n', '0.9498\n', '0.9487\n', '0.9209\n']
image.png

当学习率在0.1的时候有个峰值。随着学习率的 增加,准确率反而下降了。

你可能感兴趣的:(《python神经网络编程》二)