代码来源:《Python神经网络编程》 手写数据集下载地址: 1.训练数据集 2.测试数据集
摘要
本文代码主要讲解基于Python的简单神经网络构建用于识别手写数据集,类模块具有通用性,在分析清楚问题后可以加以改动,运用于其他方面。
代码
import numpy
import scipy
.special
import matplotlib
.pyplot
as plt
class neuralNetwork:
def __init__(self
, inputnodes
, hiddennodes
, outputnodes
, learningrate
):
self
.inodes
= inputnodes
self
.hnodes
= hiddennodes
self
.onodes
= outputnodes
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
))
self
.lr
= learningrate
self
.activation_function
= lambda x
: scipy
.special
.expit
(x
)
pass
def train(self
, inputs_list
, targets_list
):
inputs
= numpy
.array
(inputs_list
, ndmin
=2).T
targets
= numpy
.array
(targets_list
, ndmin
=2).T
hidden_inputs
= numpy
.dot
(self
.wih
, inputs
)
hidden_outputs
= self
.activation_function
(hidden_inputs
)
final_inputs
= numpy
.dot
(self
.who
, hidden_outputs
)
final_outputs
= self
.activation_function
(final_inputs
)
output_errors
= targets
- final_outputs
hidden_errors
= numpy
.dot
(self
.who
.T
, output_errors
)
self
.who
+= self
.lr
* numpy
.dot
((output_errors
* final_outputs
* (1.0 - final_outputs
)), numpy
.transpose
(hidden_outputs
))
self
.wih
+= self
.lr
* numpy
.dot
((hidden_errors
* hidden_outputs
* (1.0 - hidden_outputs
)), numpy
.transpose
(inputs
))
pass
def query(self
, inputs_list
):
inputs
= numpy
.array
(inputs_list
, ndmin
=2).T
hidden_inputs
= numpy
.dot
(self
.wih
, inputs
)
hidden_outputs
= self
.activation_function
(hidden_inputs
)
final_inputs
= numpy
.dot
(self
.who
, hidden_outputs
)
final_outputs
= self
.activation_function
(final_inputs
)
return final_outputs
input_nodes
= 784
hidden_nodes
= 200
output_nodes
= 10
learning_rate
= 0.1
n
= neuralNetwork
(input_nodes
, hidden_nodes
, output_nodes
, learning_rate
)
training_data_file
= open("mnist_data/mnist_train.csv", 'r')
training_data_list
= training_data_file
.readlines
()
training_data_file
.close
()
epochs
= 5
for e
in range(epochs
):
for record
in training_data_list
:
all_values
= record
.split
(',')
inputs
= (numpy
.asfarray
(all_values
[1:]) / 255.0 * 0.99) + 0.01
targets
= numpy
.zeros
(output_nodes
) + 0.01
targets
[int(all_values
[0])] = 0.99
n
.train
(inputs
, targets
)
pass
pass
test_data_file
= open("mnist_data/mnist_test.csv", 'r')
test_data_list
= test_data_file
.readlines
()
test_data_file
.close
()
scorecard
= []
for record
in test_data_list
:
all_values
= record
.split
(',')
correct_label
= int(all_values
[0])
print(correct_label
, "correct label")
inputs
= (numpy
.asfarray
(all_values
[1:]) / 255.0 * 0.99) + 0.01
outputs
= n
.query
(inputs
)
label
= numpy
.argmax
(outputs
)
print(label
, "network's answer")
if label
== correct_label
:
scorecard
.append
(1)
else:
scorecard
.append
(0)
pass
pass
scorecard_array
= numpy
.asarray
(scorecard
)
print("performance = ", scorecard_array
.sum() / scorecard_array
.size
)
总结
网络训练中矩阵计算起到重要作用,要特别注意两个矩阵相乘时的矩阵形状sigmoid函数的定义域与值域反向误差传播中计算部分要深入理解,书中的三层网络结构中最后一层输出层在计算式也要使用sigmoid函数在一定程度上多次使用数据集训练网络可以提高识别率