You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Perceptron.py 9.5 kB

6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # -*- coding: utf-8 -*-
  2. # ---
  3. # jupyter:
  4. # jupytext_format_version: '1.2'
  5. # kernelspec:
  6. # display_name: Python 3
  7. # language: python
  8. # name: python3
  9. # language_info:
  10. # codemirror_mode:
  11. # name: ipython
  12. # version: 3
  13. # file_extension: .py
  14. # mimetype: text/x-python
  15. # name: python
  16. # nbconvert_exporter: python
  17. # pygments_lexer: ipython3
  18. # version: 3.5.2
  19. # ---
  20. # ## 感知机
  21. #
  22. # 感知机(perceptron)是二分类的线性分类模型,输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。感知机的学习算法具有简单而易于实现的优点,分为原始形式和对偶形式。感知机预测是用学习得到的感知机模型对新的实例进行预测的,因此属于判别模型。感知机由Rosenblatt于1957年提出的,是神经网络和支持向量机的基础。
  23. #
  24. # 模仿的是生物神经系统内的神经元,它能够接受来自多个源的信号输入,然后将信号转化为便于传播的信号在进行输出(在生物体内表现为电信号)。
  25. #
  26. # ![neuron](images/neuron.png)
  27. #
  28. # * dendrites - 树突
  29. # * nucleus - 细胞核
  30. # * axon - 轴突
  31. #
  32. # 心理学家Rosenblatt构想了感知机,它作为简化的数学模型解释大脑神经元如何工作:它取一组二进制输入值(附近的神经元),将每个输入值乘以一个连续值权重(每个附近神经元的突触强度),并设立一个阈值,如果这些加权输入值的和超过这个阈值,就输出1,否则输出0(同理于神经元是否放电)。对于感知机,绝大多数输入值不是一些数据,就是别的感知机的输出值。
  33. #
  34. # 麦卡洛克-皮兹模型缺乏一个对AI而言至关重要的学习机制。这就是感知机更出色的地方所在——罗森布拉特受到唐纳德·赫布(Donald Hebb) 基础性工作的启发,想出一个让这种人工神经元学习的办法。赫布提出了一个出人意料并影响深远的想法,称知识和学习发生在大脑主要是通过神经元间突触的形成与变化,简要表述为赫布法则:
  35. #
  36. # >当细胞A的轴突足以接近以激发细胞B,并反复持续地对细胞B放电,一些生长过程或代谢变化将发生在某一个或这两个细胞内,以致A作为对B放电的细胞中的一个,效率增加。
  37. #
  38. #
  39. # 感知机并没有完全遵循这个想法,**但通过调输入值的权重,可以有一个非常简单直观的学习方案:给定一个有输入输出实例的训练集,感知机应该「学习」一个函数:对每个例子,若感知机的输出值比实例低太多,则增加它的权重,否则若设比实例高太多,则减少它的权重。**
  40. #
  41. # ## 1. 感知机模型
  42. #
  43. # 假设输入空间(特征向量)为X⊆Rn,输出空间为Y={-1, +1}。输入x∈X表示实例的特征向量,对应于输入空间的点;输出y∈Y表示示例的类别。由输入空间到输出空间的函数为
  44. #
  45. # $$
  46. # f(x) = sign(w x + b)
  47. # $$
  48. #
  49. # 称为感知机。其中,参数w叫做权值向量,b称为偏置。w·x表示w和x的内积。sign为符号函数,即
  50. # ![sign_function](images/sign.png)
  51. #
  52. # ### 几何解释
  53. # 感知机模型是线性分类模型,感知机模型的假设空间是定义在特征空间中的所有线性分类模型,即函数集合{f|f(x)=w·x+b}。线性方程 w·x+b=0对应于特征空间Rn中的一个超平面S,其中w是超平面的法向量,b是超平面的截踞。这个超平面把特征空间划分为两部分。位于两侧的点分别为正负两类。超平面S称为分离超平面,如下图:
  54. # ![perceptron_geometry_def](images/perceptron_geometry_def.png)
  55. #
  56. # ### 生物学类比
  57. # ![perceptron_2](images/perceptron_2.PNG)
  58. #
  59. #
  60. #
  61. # ## 2. 感知机学习策略
  62. #
  63. # 假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据的正负实例点完全分开的分离超平面,即最终求得参数w、b。这需要一个学习策略,即定义(经验)损失函数并将损失函数最小化。
  64. #
  65. # 损失函数的一个自然的选择是误分类的点的总数。但是这样得到的损失函数不是参数w、b的连续可导函数,不宜优化。损失函数的另一个选择是误分类点到分里面的距离之和。
  66. #
  67. # 首先,对于任意一点xo到超平面的距离为
  68. # $$
  69. # \frac{1}{||w||} | w \cdot xo + b |
  70. # $$
  71. #
  72. # 其次,对于误分类点(xi,yi)来说 -yi(w·xi+b)>0
  73. #
  74. # 这样,假设超平面S的总的误分类点集合为M,那么所有误分类点到S的距离之和为
  75. # $$
  76. # -\frac{1}{||w||} \sum_{x_i \in M} y_i (w \cdot x_i + b)
  77. # $$
  78. # 不考虑1/||w||,就得到了感知机学习的损失函数。
  79. #
  80. # ### 经验风险函数
  81. #
  82. # 给定数据集T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N),感知机sign(w·x+b)学习的损失函数定义为
  83. # $$
  84. # L(w, b) = - \sum_{x_i \in M} y_i (w \cdot x_i + b)
  85. # $$
  86. # 其中M为误分类点的集合,这个损失函数就是感知机学习的[经验风险函数](https://blog.csdn.net/zhzhx1204/article/details/70163099)。
  87. #
  88. # 显然,损失函数L(w,b)是非负的。如果没有误分类点,那么L(w,b)为0,误分类点数越少,L(w,b)值越小。一个特定的损失函数:在误分类时是参数w,b的线性函数,在正确分类时,是0.因此,给定训练数据集T,损失函数L(w,b)是w,b的连续可导函数。
  89. #
  90. # ## 3. 感知机学习算法
  91. #
  92. #
  93. # 最优化问题:给定数据集T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N),求参数w,b,使其成为损失函数的解(M为误分类的集合):
  94. #
  95. # $$
  96. # min_{w,b} L(w, b) = - \sum_{x_i \in M} y_i (w \cdot x_i + b)
  97. # $$
  98. #
  99. # 感知机学习是误分类驱动的,具体采用[随机梯度下降法](https://blog.csdn.net/zbc1090549839/article/details/38149561)。首先,任意选定$w_0$、$b_0$,然后用梯度下降法不断极小化目标函数,极小化的过程不知一次性的把M中的所有误分类点梯度下降,而是一次随机选取一个误分类点使其梯度下降。
  100. #
  101. # 假设误分类集合M是固定的,那么损失函数L(w,b)的梯度为
  102. # $$
  103. # \triangledown_w L(w, b) = - \sum_{x_i \in M} y_i x_i \\
  104. # \triangledown_b L(w, b) = - \sum_{x_i \in M} y_i \\
  105. # $$
  106. #
  107. # 随机选取一个误分类点$(x_i,y_i)$,对$w,b$进行更新:
  108. # $$
  109. # w = w + \eta y_i x_i \\
  110. # b = b + \eta y_i
  111. # $$
  112. #
  113. # 式中$\eta$(0 ≤ $ \eta $ ≤ 1)是步长,在统计学是中成为学习速率。步长越大,梯度下降的速度越快,更能接近极小点。如果步长过大,有可能导致跨过极小点,导致函数发散;如果步长过小,有可能会耗很长时间才能达到极小点。
  114. #
  115. # 直观解释:当一个实例点被误分类时,调整w,b,使分离超平面向该误分类点的一侧移动,以减少该误分类点与超平面的距离,直至超越该点被正确分类。
  116. #
  117. #
  118. #
  119. # 算法
  120. # ```
  121. # 输入:T={(x1,y1),(x2,y2)...(xN,yN)}(其中xi∈X=Rn,yi∈Y={-1, +1},i=1,2...N,学习速率为η)
  122. # 输出:w, b;感知机模型f(x)=sign(w·x+b)
  123. # (1) 初始化w0,b0
  124. # (2) 在训练数据集中选取(xi, yi)
  125. # (3) 如果yi(w xi+b)≤0
  126. # w = w + ηyixi
  127. # b = b + ηyi
  128. # (4) 转至(2)
  129. # ```
  130. #
  131. #
  132. # ## 4. Program
  133. #
  134. # +
  135. import random
  136. import numpy as np
  137. # 符号函数
  138. def sign(v):
  139. if v > 0: return 1
  140. else: return -1
  141. def perceptron_train(train_data, eta=0.5, n_iter=100):
  142. weight = [0, 0] # 权重
  143. bias = 0 # 偏置量
  144. learning_rate = eta # 学习速率
  145. train_num = n_iter # 迭代次数
  146. for i in range(train_num):
  147. #FIXME: the random chose sample is to slow
  148. train = random.choice(train_data)
  149. x1, x2, y = train
  150. predict = sign(weight[0] * x1 + weight[1] * x2 + bias) # 输出
  151. #print("train data: x: (%2d, %2d) y: %2d ==> predict: %2d" % (x1, x2, y, predict))
  152. if y * predict <= 0: # 判断误分类点
  153. weight[0] = weight[0] + learning_rate * y * x1 # 更新权重
  154. weight[1] = weight[1] + learning_rate * y * x2
  155. bias = bias + learning_rate * y # 更新偏置量
  156. print("update weight and bias: ", weight[0], weight[1], bias)
  157. #print("stop training: ", weight[0], weight[1], bias)
  158. return weight, bias
  159. def perceptron_pred(data, w, b):
  160. y_pred = []
  161. for d in data:
  162. x1, x2, y = d
  163. yi = sign(w[0]*x1 + w[1]*x2 + b)
  164. y_pred.append(yi)
  165. return y_pred
  166. # set training data
  167. train_data = np.array([[1, 3, 1], [2, 5, 1], [3, 8, 1], [2, 6, 1],
  168. [3, 1, -1], [4, 1, -1], [6, 2, -1], [7, 3, -1]])
  169. # do training
  170. w, b = perceptron_train(train_data)
  171. print("w = ", w)
  172. print("b = ", b)
  173. # predict
  174. y_pred = perceptron_pred(train_data, w, b)
  175. print(train_data[:, 2])
  176. print(y_pred)
  177. # -
  178. # ## Reference
  179. # * [感知机(Python实现)](http://www.cnblogs.com/kaituorensheng/p/3561091.html)
  180. # * [Programming a Perceptron in Python](https://blog.dbrgn.ch/2013/3/26/perceptrons-in-python/)
  181. # * [损失函数、风险函数、经验风险最小化、结构风险最小化](https://blog.csdn.net/zhzhx1204/article/details/70163099)

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。