目录
感知器是最简单的ANN架构之一。它基于一个稍微不同的被称为线性阈值单元(LTU)的人工神经元:输入和输出都是数字,每个输入的连接都有一个对应的权重。LTU会加权求和所有的输入(),然后对求值结果应用一个阶跃函数并产生最后的输出,如下图:
感知器中最常见的阶跃函数是Heaviside阶跃函数,如下:
单个LTU可以用来做简单的线性二值分类。它计算输入的线性组合,如果结果超出了阈值,输出就是正,反之则为负。训练LTU的意思是寻找 和 的正确值。
感知器就是个单层的LTU,每个神经元都与所有输入相连。这些连接通常使用称为输入神经元的特殊传递神经元来表示:输入什么就输出什么。此外,还会加上一个额外的偏差特征()。偏差特征通常用偏差神经元来表示,永远都只输出1。
图中感知器可以将实例同时分为三个不同的二进制类,因此它被称为多输出分类器。
感知器怎么训练呢?当两个神经元有相同的输出时,它们之间的连接权重就会增强。感知器就是使用这个规则的变体进行训练。
因为每个输出神经元的决策边界是线性的,所以感知器无法学习复杂的模式。
Scikit-Learn提供了一个实现单一LTU网络的Perceptron类。基本可以在鸢尾花数据集上应用:
首先我们导入常规模块和可视化设置:
- # Common imports
- import numpy as np
- import os
-
- # 以下代码可以确保程序再次运行时结果保持不变
- def reset_graph(seed=42):
- tf.compat.v1.reset_default_graph()
- tf.compat.v1.set_random_seed(seed)
- np.random.seed(seed)
-
- # To plot pretty figures
- import matplotlib
- import matplotlib.pyplot as plt
- plt.rcParams['axes.labelsize'] = 14
- plt.rcParams['xtick.labelsize'] = 12
- plt.rcParams['ytick.labelsize'] = 12
- import numpy as np
- from sklearn.datasets import load_iris
- from sklearn.linear_model import Perceptron
-
- iris = load_iris()
- X = iris.data[:, (2, 3)] # 花瓣长度和宽度特征
- y = (iris.target == 0).astype(np.int) #y = (iris.target == 0)返回的是布尔类型数组,astype(np.int)将True转化为1,将False转化为0
-
- per_clf = Perceptron(max_iter=100, tol=-np.infty, random_state=42)
- per_clf.fit(X, y)
-
- y_pred = per_clf.predict([[2, 0.5]])
-
- y_pred
运行结果如下:
array([1])
- a = -per_clf.coef_[0][0] / per_clf.coef_[0][1]
- b = -per_clf.intercept_ / per_clf.coef_[0][1]
-
- axes = [0, 5, 0, 2]
-
- x0, x1 = np.meshgrid(
- np.linspace(axes[0], axes[1], 500).reshape(-1, 1),
- np.linspace(axes[2], axes[3], 200).reshape(-1, 1),
- )
- #X, Y = np.meshgrid(x, y) 代表的是将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到X中,y坐标放入Y中,并且相应位置是对应的
-
- X_new = np.c_[x0.ravel(), x1.ravel()] #扁平化作用
- y_predict = per_clf.predict(X_new)
- zz = y_predict.reshape(x0.shape)
-
- plt.figure(figsize=(10, 4))
- #X[y==0, 0]代表标签值即y==0时的坐标的x值,X[y==0, 1]代表标签值即y==0时的坐标的y值
- plt.plot(X[y==0, 0], X[y==0, 1], "bs", label="Not Iris-Setosa")
- plt.plot(X[y==1, 0], X[y==1, 1], "yo", label="Iris-Setosa")
-
- plt.plot([axes[0], axes[1]], [a * axes[0] + b, a * axes[1] + b], "k-", linewidth=3)
- from matplotlib.colors import ListedColormap
- custom_cmap = ListedColormap(['#9898ff', '#fafab0'])
-
- plt.contourf(x0, x1, zz, cmap=custom_cmap) #用来画出不同分类的边界线,也常常用来绘制等高线
- plt.xlabel("Petal length", fontsize=14)
- plt.ylabel("Petal width", fontsize=14)
- plt.legend(loc="lower right", fontsize=14)
- plt.axis(axes)
-
- plt.show()
运行结果如下:
简洁版如下(掌握):
a = -per_clf.coef_[0][0] / per_clf.