手动编写感知机

手动编写感知机

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
        pass
    pass
print(test_score)

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

猜你喜欢

转载自blog.csdn.net/weixin_43666945/article/details/88920893
今日推荐