python神经网络编程chap02

2.4 使用python制作神经网络

2.4.1 框架代码

1、初始化函数__inital__()———设定输入层节点、隐藏层节点、输出层节点的数量、学习率的大小。
(这些节点数量定义了神经网络的形状和尺寸。我们不会将这些数量固定而是当我们使用参数定义一个新的神经网络对象的时候,才会确定这些数量。通过这种方式,我们保留了选择的余地,轻松滴创建不同大小的新的神经网络)
权重时神经网络固有的一部分,与神经网络共存亡,他不是一个临时的数据集,不会随着函数的调用结束而消失。
因此,权重也必须是初始化的一部分,并且其他的函数(训练函数和询问函数)也可以进行访问。

2、训练函数train()——学习给定数据集样本后,优化权重
在训练神经网络的过程中有两个阶段:
(1)第一个阶段是:计算输出就像query()做的事情。
(2)第二个阶段是:反向传播误差,告知如何优化链接权重。
所以在编写代码的时候,书中实现讲解了inital()和query()这两个函数的编写再编写train()训练函数。

3、查询函数query()——给定输入,从输出节点给出答案
query()函数接受神经网络的输入,返回网络的输出,即做到一下两点
(1)我们需要传递来自输入层节点的输入信号,通过隐藏层,最后从输出层输出
(2)当信号馈送至给定的隐藏层或输出层节点时,我们使用链接权重调节信号,还应用S激活函数抑制来自这些节点的信号。

例子

(1) 简单神经网络

代码:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import scipy.special

imshow()创建图绘指令
matplotlib.pyplot(arr, interpolation = “nearest”)
interpolation是为了告诉python,不要为了让绘图看起来更加平滑而混合颜色

plt.imshow(b, interpolation = "nearest")

输出结果:
请添加图片描述
神经网络需要一些输入,经过计算产生一定的输出
神经网络的这些动作、训练和生成的答案,是神经网络的原生函数,即神经网络对象的函数
神经网络内部有数据——链接权重,这些数据本身就属于神经网络本身
因此,我们将神经网络构建成——对象

#使用python构建神经网络
"""
1、初始化函数__inital__()———设定输入层节点、隐藏层节点、输出层节点的数量、学习率的大小
(这些节点数量定义了神经网络的形状和尺寸。我们不会将这些数量固定而是当我们使用参数定义一个新的神经网络对象的时候,才会确定这些数量。
通过这种方式,我们保留了选择的余地,轻松滴创建不同大小的新的神经网络)
权重时神经网络固有的一部分,与神经网络共存亡,他不是一个临时的数据集,不会随着函数的调用结束而消失。
因此,权重也必须是初始化的一部分,并且其他的函数(训练函数和询问函数)也可以进行访问。

2、训练函数train()——学习给定数据集样本后,优化权重
(1)在训练神经网络的过程中有两个阶段,第一个阶段是计算输出就像query()做的事情,第二个阶段是反向传播误差,告知如何优化链接权重。所以在编写代码的时候,书中实现讲解了inital()和query()这两个函数的编写再编写train()训练函数

3、查询query()——给定输入,从输出节点给出答案
query()函数接受神经网络的输入,返回网络的输出,即做到一下两点:
(1)我们需要传递来自输入层节点的输入信号,通过隐藏层,最后从输出层输出。
(2)当信号馈送至给定的隐藏层或输出层节点时,我们使用链接权重调节信号,还应用S激活函数抑制来自这些节点的信号。
"""
# neural network class definition
class neuralNetwork:
    
    
    # initialise the neural network
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # set number of nodes in each input, hidden, output layer
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        
        # link weight matrices, wih and who
        # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer
        # w11 w21
        # w12 w22 etc 
        self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
        self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))

        # learning rate
        self.lr = learningrate
        
        # activation function is the sigmoid function
        self.activation_function = lambda x: scipy.special.expit(x)
        
        pass

    
    # train the neural network
    def train(self, inputs_list, targets_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        # output layer error is the (target - actual)
        output_errors = targets - final_outputs
        # hidden layer error is the output_errors, split by weights, recombined at hidden nodes
        hidden_errors = numpy.dot(self.who.T, output_errors) 
        
        # update the weights for the links between the hidden and output layers
        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs))
        
        # update the weights for the links between the input and hidden layers
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))
        
        pass

    
    # query the neural network
    def query(self, inputs_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        return final_outputs
    

测试:

# number of input, hidden and output nodes
input_nodes = 3
hidden_nodes = 3
output_nodes = 3

# learning rate is 0.3
learning_rate = 0.3

# create instance of neural network
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)
# test query (doesn't mean anything useful yet)
n.query([1.0, 0.5, -1.5])

输出:
请添加图片描述
以上就是一个简单的神经网络的工作流程。

(2) 手写体数字识别

① 使用部分数据集的手写体数字识别:

(数据集见文章末尾)
导入需要得库

import numpy
# scipy.special for the sigmoid function expit()
import scipy.special
# library for plotting arrays
import matplotlib.pyplot
# ensure the plots are inside this notebook, not an external window
%matplotlib inline

神经网络类定义

# neural network class definition
class neuralNetwork:
    
    
    # initialise the neural network
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # set number of nodes in each input, hidden, output layer
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        
        # link weight matrices, wih and who
        # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer
        # w11 w21
        # w12 w22 etc 
        self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
        self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))

        # learning rate
        self.lr = learningrate
        
        # activation function is the sigmoid function
        self.activation_function = lambda x: scipy.special.expit(x)
        
        pass

    
    # train the neural network
    def train(self, inputs_list, targets_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        # output layer error is the (target - actual)
        output_errors = targets - final_outputs
        # hidden layer error is the output_errors, split by weights, recombined at hidden nodes
        hidden_errors = numpy.dot(self.who.T, output_errors) 
        
        # update the weights for the links between the hidden and output layers
        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs))
        
        # update the weights for the links between the input and hidden layers
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))
        
        pass

    
    # query the neural network
    def query(self, inputs_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        return final_outputs

输入、隐藏层、输出层节点定义,学习率初始化,最后一个语句是创建一个神经网络的实例

# number of input, hidden and output nodes
input_nodes = 784
hidden_nodes = 100
output_nodes = 10

# learning rate
learning_rate = 0.3

# create instance of neural network
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)

加载训练数据集

# load the mnist training data CSV file into a list
training_data_file = open("dataset/mnist_dataset/mnist_train_100.csv", 'r')
training_data_list = training_data_file.readlines()
training_data_file.close()

遍历训练数据集-训练神经网络

for record in training_data_list:
        # split the record by the ',' commas
        all_values = record.split(',')
        # scale and shift the inputs
        inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
        # create the target output values (all 0.01, except the desired label which is 0.99)
        targets = numpy.zeros(output_nodes) + 0.01
        # all_values[0] is the target label for this record
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)
        
        pass

加载测试数据集,并进行测试

#测试
#load the mnist test data csv file into a list
test_data_file = open("dataset/mnist_dataset/mnist_test_10.csv", 'r')
test_data_list = test_data_file.readlines()
test_data_file.close()

输出真实的标签,与我们预测的标签进行比对,看看有没有预测错误

all_values = test_data_list[0].split(',')
print(all_values[0]) #真实的标签

结果:真实的标签是7
请添加图片描述
真实手写体的可视化展示

image_array = numpy.asfarray(all_values[1:]).reshape((28,28))
matplotlib.pyplot.imshow(image_array, cmap = 'Greys', interpolation = 'None')

结果如下

请添加图片描述
输出预测的结果数组

n.query((numpy.asfarray(all_values[1:])/255.0*0.99)+0.01)

请添加图片描述
分析: 从上图中的输出结果克知道,[0.44774504]在数组中取得最大值,因此,我们的神经网络最大可能的把输入的图像预测为7,与真实标签一样,预测正确。

② 使用完整的数据集手写体数字识别

完整代码:

import numpy as np
# scipy.special for the sigmoid function expit()
import scipy.special
# library for plotting arrays
import matplotlib.pyplot as plt
# ensure the plots are inside this notebook, not an external window
%matplotlib inline

# neural network class definition
class neuralNetwork:
    
    
    # initialise the neural network
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # set number of nodes in each input, hidden, output layer
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        
        # link weight matrices, wih and who
        # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer
        # w11 w21
        # w12 w22 etc 
        #self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
        #self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))

        self.wih = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes))
        self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes))
        
        
        # learning rate
        self.lr = learningrate
        
        # activation function is the sigmoid function
        self.activation_function = lambda x: scipy.special.expit(x)
        
        pass

    
    # train the neural network
    def train(self, inputs_list, targets_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        # output layer error is the (target - actual)
        output_errors = targets - final_outputs
        # hidden layer error is the output_errors, split by weights, recombined at hidden nodes
        hidden_errors = numpy.dot(self.who.T, output_errors) 
        
        # update the weights for the links between the hidden and output layers
        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), np.transpose(hidden_outputs))
        
        # update the weights for the links between the input and hidden layers
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs))
        
        pass
        # query the neural network
    def query(self, inputs_list):
        # convert inputs list to 2d array
        inputs = numpy.array(inputs_list, ndmin=2).T
        
        # calculate signals into hidden layer
        hidden_inputs = numpy.dot(self.wih, inputs)
        # calculate the signals emerging from hidden layer
        hidden_outputs = self.activation_function(hidden_inputs)
        
        # calculate signals into final output layer
        final_inputs = numpy.dot(self.who, hidden_outputs)
        # calculate the signals emerging from final output layer
        final_outputs = self.activation_function(final_inputs)
        
        return final_outputs

# number of input, hidden and output nodes
input_nodes = 784
hidden_nodes = 200
output_nodes = 10

# learning rate
learning_rate = 0.2

# create instance of neural network
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)


# load the mnist training data CSV file into a list
training_data_file = open("dataset/mnist_dataset/mnist_train.csv", 'r')
training_data_list = training_data_file.readlines()
training_data_file.close()

# train the neural network

    # go through all records in the training data set
for record in training_data_list:
    # split the record by the ',' commas
    all_values = record.split(',')
    # scale and shift the inputs
    inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    #print(inputs.shape)
    # create the target output values (all 0.01, except the desired label which is 0.99)
    targets = numpy.zeros(output_nodes) + 0.01
    # all_values[0] is the target label for this record
    targets[int(all_values[0])] = 0.99
    n.train(inputs, targets)
    pass

# load the mnist test data CSV file into a list
test_data_file = open("dataset/mnist_dataset/mnist_test.csv", 'r')
test_data_list = test_data_file.readlines()
test_data_file.close()

# test the neural network

# scorecard for how well the network performs, initially empty
scorecard = []

# go through all the records in the test data set
for record in test_data_list:
    # split the record by the ',' commas
    all_values = record.split(',')
    # correct answer is first value
    correct_label = int(all_values[0])
    # scale and shift the inputs
    inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    # query the network
    outputs = n.query(inputs)
    # the index of the highest value corresponds to the label
    label = numpy.argmax(outputs)
    # append correct or incorrect to list
    if (label == correct_label):
        # network's answer matches correct answer, add 1 to scorecard
        scorecard.append(1)
    else:
        # network's answer doesn't match correct answer, add 0 to scorecard
        scorecard.append(0)
        pass   
    pass

# calculate the performance score, the fraction of correct answers
scorecard_array = numpy.asarray(scorecard)
print ("performance = ", scorecard_array.sum() / scorecard_array.size)

不使用epochs的输出结果:
请添加图片描述
使用了epochs的输出结果:请添加图片描述
使用epochs的代码就是将上述的# train the neural network(遍历数据集,训练神经网络的train()改成下面的代码)
带有epochs的train()

# train the neural network
#epochs is the number of times the training data set is used for training
epochs = 5  #训练五次数据集

for e in range(epochs):
    # go through all records in the training data set
    for record in training_data_list:
        # split the record by the ',' commas
        all_values = record.split(',')
        # scale and shift the inputs
        inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
        #print(inputs.shape)
        # create the target output values (all 0.01, except the desired label which is 0.99)
        targets = np.zeros(output_nodes) + 0.01
        # all_values[0] is the target label for this record
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)
        pass
    pass

在上面的完整代码中,我们修改了学习率,还使用了epochs,epoces是表示使用多少次数据集进行训练数据。 代码中 epochs = 5 ,即:训练五次数据集,还可以改变隐藏层输出节点的个数等,这些都可以改进神经网络,提高神经网络的性能。

mnist数据集csv格式链接:

链接: https://pan.baidu.com/s/1qxALz6vfFILsADlo8UPnAw?pwd=1224 提取码: 1224

参考书籍:python神经网络编程 [英] 塔里克·拉希德

ps:数据集一定要找对,不然运行出错还以为是自己的错,反而耽误很多时间!这个数据集亲测是正确的!!!
(哦吼! 今天考研日,考研加油!上岸上岸!!!)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值