您的位置:首页 > 其它

手动编写感知机

2019-03-31 09:17 34 查看

手动编写感知机

Emmmm,今天是第一篇正式博文,就写一些比较简单的内容吧。我一直觉得最好的学习方式就是直接的上手,如果能够实现程序,也就没有什么大的问题了。
编写一个简单的感知机并不是很困难,无非就是完成两个主要的任务:正向传播的函数设置,反向传播的修正。所以我们先对感知机的正向传播进行设置。

正向的函数的设置

感知机分为两层:第一层是输入层,第二层是输出层,中间只经过一次简单的矩阵乘法即可实现。为了保证准确率,我将输入层和输出层之间的激活函数设置为sigmoid函数。
训练集和测试集采用网络上最常见的手写数字识别的csv格式的测试集,我们用其中的一部分数字作为感知机的训练数据和测试数据。

反向传播的推导

反向传播的修正是神经网络中最重要的部分,如果没有反向传播的修正,也就谈不上什么机器学习了。因为我们是感知机,其中只有一个激活函数,只要明白了它的反向传播的过程,就没有其他的大的问题了。
反向传播是最麻烦的部分,相对于用电脑写出推导公式,我还是更喜欢用手写的方式进行推导,下面是推导的过程图

现在万事具备接下来就是动手开始编写感知机了。

代码编写

虽然大学中最喜欢的语言是java,但是编写感知机这种事情,怎样也比不了用python进行编写,顺便也学习了一下这种语言,哈哈。
我们首先创造一个类,名为:perceptron:
其中包含三个函数:初始化函数、训练函数以及输出函数
首先是初始化函数:

# 初始化函数
def __init__(self, inputnodes, outputnodes, learningrate):
# 内容的初始化
self.input_nodes = inputnodes
self.output_nodes = outputnodes
# 学习率
self.learning_rate = learningrate
# 权重,制作一个大小为输入结点*输出结点的权重大小矩阵
self.wio = numpy.random.normal(0.0, pow(self.output_nodes, -0.5), (self.output_nodes, self.input_nodes))
# 激活函数 y = 1/(1+exp(x))
self.activation_function = lambda x: scipy.special.expit(x)
pass

接着是训练函数:

# 训练函数
def training(self, inputlist, outputlist):
inputs = numpy.array(inputlist, ndmin=2).T
outputs = numpy.array(outputlist, ndmin=2).T
output_input = numpy.dot(self.wio, inputs)
final_output = self.activation_function(output_input)
error_list = outputs - final_output

self.wio += self.learning_rate*numpy.dot((error_list*final_output*(1.0-final_output)), numpy.transpose(inputs))
pass

可以看到最核心的部分就是对于权重的更新,和上述的推导过程中一模一样。

最后是输出函数:

# 输出结果
def query(self, inputlist):
inputs = numpy.array(inputlist, ndmin=2).T
output_input = numpy.dot(self.wio, inputs)
final_output = self.activation_function(output_input)
return final_output
pass
pass

就是简单的正向传播的数据,最后进行输出

OK,基本函数编写完毕,让我们来尝试一下。

test_input = 784
test_out = 10
learning = 0.1
n = perceptron(test_input, test_out, learning)
# 读取文件的数据
training_data_file = open("data\感知机\mnist_train_100.csv", 'r')
training_data_list = training_data_file.readlines()
training_data_file.close()
for record in training_data_list:
all_value = record.split(',')
inputs = (numpy.asfarray(all_value[1:])/255.0*0.99)+0.01
targets = numpy.zeros(test_out)+0.01
targets[int(all_value[0])] = 0.99
n.training(inputs, targets)
pass"""训练完成"""
# 开始测试数据
test_data_file = open("data\感知机\mnist_test_10.csv", 'r')
test_data_list = test_data_file.readlines()
test_data_file.close()
test_score = 0
for record in test_data_list:
all_value = record.split(',')
correct_answer = all_value[0]
inputs = (numpy.asfarray(all_value[1:])/255.0*0.99)+0.01
outputs = n.query(inputs)
answer = numpy.argmax(outputs)
# 计分器
if int(correct_answer) == int(answer):
test_score += 1
else:
test_score += 0
passpassprint(test_score)

最后粘贴一下结果:

哈哈,及格了,多尝试几次发现一直在及格线下徘徊,简单的想一下也明白,只有一百组训练数据,以及10组的测试数据,没有办法反应真实的情况,如果大家感兴趣可以自己寻找完整的数据集,应该可以在60%左右徘徊。
当然,这只是一次简单的尝试,下一次我将会编写一个简单的三层神经网络,正式的开始神经网络之旅。
有兴趣的同学可以复制试一试,也可以模仿着自己编写,自己编写以后还是很有成就感的。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: