统计学习方法---感知机算法拓展(神经网络)

el/2024/7/17 20:35:48

神经元

神经元是神经网络的基本单元,接受多个神经元传递过来的输入信号,然后通过激活函数计算输出信号。

从图里可以看到每个输入信号都有一个权重w,这个权重是动态改变的。我们平时所说的训练神经网络主要是训练(修正)这个权重w。

同时每个神经元有一个参数theta,这个theta是阈值,生物意义上,如果输入信号的加权和比阈值高,意味着这个神经元被激活(处于兴奋状态)。信号向下一个神经元传递,但是在这里的感知机模型里面,theta不过是个公式里的参数罢了。

感知机(Perceptron) 
感知机本质上就是两个神经元构成的简单神经网络。一层是输入层,全部是输入神经元,直接把信号传递给下一层神经元,第二层就是输出层。

感知机使用Sigmoid函数作为激活函数: 

使用Python语言可以用一行代码表示出来,不过得借助math库。 

lambda s:1.0/(1+math.exp(-s))

每次感知机有输出的时候,内部参数(w)都需要被训练和调整,其训练算法如下: 

学习率介于0和1之间,我们可以手动设置。算法本身很简单。

接下来,我们思考一下代码的实现:

  • 首先,我们可以定义一个节点类Node用来表示一个神经元节点,从这个Node类可以进一步派生出输入节点类和输出节点类。
  • 我们可以认为每个节点Node都有一个输入节点列表。对于输入节点,它的输入节点列表就是空集[]。
  • 节点Node的默认激活函数是sigmoid函数。
  • 本来输入节点的职能就是把输入信号传递给输出层,不需要激活函数的,但是我们也可以把它视为一个M-P神经元,它的输入信号加权和为0(它本身就是输入层,不存在额外的输入,)将它的阈值theta视为他要传递给输出层的数值的相反数。将它的激活函数设置为f(x)=x。就可以等同于一个M-P神经元了。

代码实现

# coding:utf-8
import mathdef sigmoid(x):return 1.0/(1+math.exp(-x))class Record:# 输入的一条训练数据def __init__(self):feature_vector = []# 特征向量label = None# 标签returnclass Node: # 神经元节点def __init__(self):self.input_list = []# 输入的神经元列表self.activated = False# 这个神经元是否已经计算出输出信号self.recent_output = None# 上一次的输出信号self.threshold = 0.0# 阈值θself.activation_func = lambda s: 1.0 / (1 + math.exp(-s))  # default func: sigmoid  functionreturndef add_input(self, node):# 添加输入结点self.input_list.append([node, 1.0])# [结点对象,权重w] 权重默认为1returndef set_threshold(self, th):# 设置阈值θself.threshold = threturndef output(self):# 通过激活函数计算输出信号sum_ = 0.0for p in self.input_list:prev_node = p[0]sum_ += prev_node.output() * p[1]self.recent_output = self.activation_func(sum_ - self.threshold)return self.recent_outputclass InputNode(Node):# 神经元输入节点def __init__(self):Node.__init__(self)self.activation_func = lambda s: s# 注意激活函数是 f(x)=x returndef set_input_val(self, val):Node.set_threshold(self, -val)# 输入的结点列表为空,设置阈值为 -valreturnclass OutputNode(Node):# 神经元输出节点def __init__(self):Node.__init__(self)self.threshold = 4.0returnclass NeuralNetwork:# 抽象神经网络def __init__(self):self.eta = 0.5# 学习率ηself.data_set = []# 输入的数据集,列表内的元素为 Record对象def set_data_set(self, data_set_):# 设置数据集self.data_set = data_set_returnclass SingleLayerNeuralNetwork(NeuralNetwork):# 感知机模型def __init__(self):NeuralNetwork.__init__(self)self.perceptron = OutputNode()# 一个输出结点self.input_node_list = []self.perceptron.threshold = 4.0returndef add_input_node(self):# 添加输入结点inode = InputNode()self.input_node_list.append(inode)self.perceptron.add_input(inode)returndef set_input(self, value_list):# 给每个输入结点设置输入数据assert len(value_list) == len(self.input_node_list)for index in range(0, len(value_list), 1):value = value_list[index]node = self.input_node_list[index]node.set_input_val(value)returndef adjust(self, label):# 每条记录训练后,自动调整内部参数wfor prev_node_pair in self.perceptron.input_list:delta_weight = self.eta * (label - self.perceptron.recent_output) * prev_node_pair[0].recent_outputorigin_weight = prev_node_pair[1]prev_node_pair[1] = origin_weight + delta_weightreturndef run(self):# 开始跑训练集for data in self.data_set:# 遍历训练集self.set_input(data.feature_vector)record_ = self.perceptron.output()print record_self.adjust(data.label)# 每条记录训练后,自动调整内部参数wreturn
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

现在让这个感知机来解决或问题(x∨y),假设1表示真,0表示假,那么1和1进行或运算结果就是1,1和0进行或运算结果就是1,0和0进行或运算结果就是0。 
输入数据如下(一条记录保存为一行,第一个和第二个数字是输入,第3个数字是标签。数据假设保存在E://data/ann/train_0.txt):

1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
1 0 1
0 0 0
1 0 1
1 1 1
1 1 1
0 1 1
1 0 1
0 0 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192

有了以上代码和数据后,用以下Python代码开始跑训练集:

file_handler = open('E://data/ann/train_0.txt')
data_set = []
line = file_handler.readline()
while line:# 遍历文件里的数据record = Record()item_feature_vector = []str_list = line.split()item_feature_vector.append(float(str_list[0]))item_feature_vector.append(float(str_list[1]))record.feature_vector = item_feature_vectorrecord.label = float(str_list[2])data_set.append(record)line = file_handler.readline()
print len(data_set)ann = SingleLayerNeuralNetwork()# 实例化感知机对象
ann.add_input_node()
ann.add_input_node()# 添加两个输入结点
ann.set_data_set(data_set)# 设置数据集
ann.run()# 等待结果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

结果如下图所示:

一开始的输出可能有点不准确,但是随着数据的增多,输出变得越来越像训练数据的真实值,比较逼近与0.0或者逼近与1.0。

实际上感知机能解决的问题很少,为了解决复杂问题,需要引入多层神经网络和新的学习算法:BP误差逆传播算法。

本篇文章主要摘自:机器学习笔记-Python实现感知Perceptron)在此非常感谢!

参考资料:

  • 机器学习笔记-Python实现感知Perceptron)在此非常感谢!



http://www.ngui.cc/el/5557019.html

相关文章

统计学习方法---KNN(K近邻)

前言 k邻近算法(k-nearest)是一种判别模型,解决分类问题和回归问题,以分类问题为主,在此我们也主要介绍分类问题中的k近邻算法。 k近邻算法的输入为实例的特征向量,对应予特征空间中的点;输出…

统计学习方法---k近邻法

本文对应《统计学习方法》第3章,用数十行代码实现KNN的kd树构建与搜索算法,并用matplotlib可视化了动画观赏。 k近邻算法 给定一个训练数据集,对新的输入实例,在训练数据集中找到跟它最近的k个实例,根据这k个实例的类…

统计学习方法---

4、朴素贝叶斯法 http://www.hankcs.com/ml/naive-bayesian-method.html http://blog.csdn.net/u010626937/article/details/73810753 5、决策树 http://www.hankcs.com/ml/decision-tree.html 6、逻辑斯谛回归与最大熵模型 http://www.hankcs.com/ml/the-logistic-regressi…

pandas数据合并与重塑---concat方法

谈到pandas数据的行更新、表合并等操作,一般用到的方法有concat、join、merge。但这三种方法对于很多新手来说,都不太好分清使用的场合与用途。今天就pandas官网中关于数据合并和重述的章节做个使用方法的总结。 1、concat pd.concat(objs, axis0, joino…

pandas数据合并与重塑---join、merge方法

在上一篇文章中,我整理了pandas在数据合并和重塑中常用到的concat方法的使用说明。在这里,将接着介绍pandas中也常常用到的join 和merge方法 merge pandas的merge方法提供了一种类似于SQL的内存链接操作,官网文档提到它的性能会比其他开源语言…

XGBoost简介---相关概念、原理

XGBoost是2014年2月诞生的专注于梯度提升算法的机器学习函数库,此函数库因其优良的学习效果以及高效的训练速度而获得广泛的关注。仅在2015年,在Kaggle竞赛中获胜的29个算法中,有17个使用了XGBoost库,而作为对比,近年大…

Sklearn工具包---train_test_split随机划分训练集和测试集

一般形式: train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和test data,形式为: X_train,X_test, y_train, y_test cross_validation.train_test_split(train_data,train_target,test_size0.4…

sklearn工具包---分类效果评估(acc、recall、F1、ROC、回归、距离)

一、acc、recall、F1、混淆矩阵、分类综合报告 1、准确率 第一种方式:accuracy_score # 准确率 import numpy as np from sklearn.metrics import accuracy_score y_pred [0, 2, 1, 3,9,9,8,5,8] y_true [0, 1, 2, 3,2,6,3,5,9] #共9个数据,3个相同…

python中可变和不可变对象(复值,拷贝,函数值传递)

python中有可变对象和不可变对象,可变对象: list, dict.不可变对象有: int, string, float, tuple.python不可变对象int, string, float, tuple先来看一个例子 def int_test(): i 77 j 77 print(id(77)) #140396579590…

推荐算法概述:基于内容的推荐算法、协同过滤推荐算法和基于知识的推荐算法

“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。” 所谓推荐算法就是利用用…