深度学习之感知器的python实现,及用感知器实现鸢尾花的分类
2019-03-14 10:16
351 查看
机器学习一般用来处理结构化的数据,深度学习一般用来处理非结构化的数据,例如图像、视频、文字等。
、
权重更新过程: 如果真实是1,预测是0,则权重会增加,相当于为了达到阈值增加权重
如果真实是0,预测是1,则权重会降低,相当于为了达到阈值减少权重
实现步骤
- 对权重进行初始化。(初始化为0或者很小的数值。)
- 对训练集中每一个样本进行迭代,计算输出值y。
- 根据输出值y与真实值,更新权重。
- 循环步骤2。直到达到指定的次数(或者完全收敛)。
说明:
如果两个类别线性可分,则感知器一定会收敛。
如果两个类别线性不可分,则感知器一定不会收敛。
实现与门:
import numpy as np # 定义数据集 X = np.array([[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]) # 定义标签(每个样本所属的分类)。 y = np.array([0, 0, 0, 1]) # 定义权重。对于单层感知器,权重通常初始化为0或者很小的数值。 # w = np.zeros(3) w = np.random.random(3) # 定义学习率。 eta = 0.1 for epoch in range(6): for x, target in zip(X, y): 4000 # 计算净输入 z = np.dot(w, x) # 根据净输入,计算分类值。 y_hat = 1 if z >= 0 else 0 # 根据预测值与真实值,进行权重调整。 w = w + eta * (target - y_hat) * x # 注意数组的矢量化计算,相当于执行了以下的操作。 # w[0] = w[0] + eta * (y - y_hat) * x[0] # w[1] = w[1] + eta * (y - y_hat) * x[1] # w[2] = w[2] + eta * (y - y_hat) * x[2] print(target, y_hat) print(w)
线性可分,能收敛
# 使用单层感知器无法实现异或门。 # 感知器的局限:如果两个类别的样本在空间中线性不可分,则感知器永远也不会收敛。 X = np.array([[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]) y = np.array([0, 1, 1, 0]) # w = np.zeros(3) w = np.random.random(3) eta = 0.1 for epoch in range(70): for x, target in zip(X, y): z = np.dot(w, x) y_hat = 1 if z >= 0 else 0 w = w + eta * (target - y_hat) * x print(target, y_hat) print(w)
算法的Python实现
现在,我们使用Python语言来实现感知器算法,进行鸢尾花的分类。
class Perceptron: """通过Python语言实现感知器类。用来进行二分类任务。""" def __init__(self, eta, epoch): """初始化方法。 Parameter: ------- eta: float 学习率。 epoch: int 对训练集训练的轮数。 """ self.eta = eta self.epoch = epoch def step(self, z): """阶跃函数。对净输入进行转换。 Parameter: ----- z: 标量或数组类型 净输入。 Return: ------ t: 变量或数组类型。 分类的结果。0或者1。当z >= 0时,返回1,否则返回0。 """ # return 1 if z >= 0 else 0 return np.where(z >= 0, 1, 0) def fit(self, X, y): """训练方法。 Parameter: X: 类数组类型。形状为 (样本数量, 特征数量) 提供的训练集。 y: 类数组类型。形状为(样本数量,) 样本对应的标签(分类) """ # 对类型进行转换,不管是什么二维类型,统一转换成二维的ndarray数组类型。 X = np.asarray(X) y = np.asarray(y) # 注意:权重的数量要比特征的数量多1。多出来的一个就是偏置。 self.w_ = np.zeros(X.shape[1] + 1) # 定义损失列表。用来存放每个epoch迭代之后,分类错误的数量。 self.loss_ = [] # 迭代epoch指定的轮数。 for i in range(self.epoch): # 用来记录单次epoch的损失值(分类错误的数量) loss = 0 for x, target in zip(X, y): # 计算净输入 z = np.dot(x, self.w_[1:]) + self.w_[0] # 根据净输入,计算分类。 y_hat = self.step(z) # if target != y_hat: # loss += 1 loss += target != y_hat # 调整权重 self.w_[1:] += self.eta * (target - y_hat) * x # 调整偏置 self.w_[0] += self.eta * (target - y_hat) # 将损失值加入到损失列表当中。 self.loss_.append(loss) def predict(self, X): """预测方法。根据提供的数据集X,返回每一个样本对应的标签(分类)。 Parameter: ----- X: 类数组类型。形状为 (样本数量, 特征数量) 提供预测集。 Return: ----- label: 类数组类型。形状为:(样本数量,) 预测的每一个便签分类。 """ X = np.asarray(X) # 计算净输入。(矢量化计算,没有使用循环分别对每一个样本求净输出) z = np.dot(X, self.w_[1:]) + self.w_[0] # 获取最终的分类结果。(一维数组类型。) result = self.step(z) return result # 感知器类进行测试。 X = np.array([[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]) y = np.array([0, 0, 0, 1]) p = Perceptron(0.1, 7) p.fit(X, y) print(p.w_) print(p.loss_)
# 使用感知器实现鸢尾花的分类。 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split import pandas as pd # return_X_y设置为True,只返回Data与target。 X, y = load_iris(return_X_y=True) # X.shape, y.shape # np.concatenate 合并的数组,要求具有相同的维度,因此,需要将y变成 # 2维的形式。 data = pd.DataFrame(np.concatenate((X, y.reshape((-1, 1))), axis=1)) # np.sum(data.duplicated()) # display(data.shape) data.drop_duplicates(inplace=True) # display(data.shape) # data[4].map({0:1, 1:-1, 2:2}) # data = data[data[4] != 2] data[4] = data[4].map({0:10, 1:0, 2:1}) data = data[data[4] != 10] data[4].value_counts() # data[4].value_counts()
X, y = data.iloc[:, :4], data.iloc[:, 4] train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.2, random_state=0) # train_X.shape, test_X.shape p = Perceptron(0.1, 20) p.fit(train_X, train_y) # 查看训练后的权重与损失情况。 # display(p.w_) # display(p.loss_) result = p.predict(test_X) np.sum(test_y == result) / len(result)
import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams["font.family"] = "SimHei" mpl.rcParams["axes.unicode_minus"] = False plt.plot(test_y.values, "go", ms=15, label="真实值") plt.plot(result, "rx", ms=15, label="预测值") plt.title("感知器二分类预测") plt.xlabel("样本序号") plt.ylabel("样本类别") plt.legend() plt.show()
# 绘制损失曲线。(每个epoch预测样本错误的数量) plt.plot(range(1, len(p.loss_) + 1), p.loss_, "o-")
split_index = test_size * len() data[:split_index] data[split_index:]
相关文章推荐
- 神经网络与深度学习 1.6 使用Python实现基于梯度下降算法的神经网络和MNIST数据集的手写数字分类程序
- 神经网络与深度学习 使用Python实现基于梯度下降算法的神经网络和自制仿MNIST数据集的手写数字分类可视化程序 web版本
- 深度学习最邻近规则 python实现
- 在ubuntu中配置深度学习python图片分类实验环境
- [TensorFlow深度学习入门]实战四·逻辑回归鸢尾花进行分类(对比均方根误差与softmax交叉熵误差区别)
- 【Python开发】【神经网络与深度学习】网络爬虫之python实现
- [置顶] 【深度学习】BP反向传播算法Python简单实现
- 深度学习入门基于python的理论与实现 第四章two_layer_net.py完全解析
- 【深度学习】1.2:简单神经网络的python实现
- 深度学习入门---softmax回归 Python实现
- 深度学习第一课 第四周 深层神经网络用python的实现
- 深度学习——梯度下降实现对感知器的权重优化问题的分析(理论加上梯度下降的代码实现)
- 分享《深度学习入门:基于Python的理论与实现》+PDF+源码+斋藤康毅+陆宇杰
- 机器学习、深度学习的区别(from 深度学习入门:基于 Python 的理论与实现)
- 《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码
- caffe19 《深度学习--Caffe之经典模型详解与实战》笔记01 分类测试python调用
- 用Python实现随机森林算法,深度学习
- 深度学习-基于softmax神经网络分类的源码实现
- 【深度学习】keras + tensorflow 实现猫和狗图像分类
- 斯坦福大学深度学习公开课cs231n学习笔记(9)softmax分类和神经网络分类代码实现