目录
深入研究鸢尾花数据集
画出数据集中150个数据的前两个特征的散点分布图:
import numpy as np
import torch
import matplotlib.pyplot as plt
from nndl.dataset import load_data
data_x,data_y = load_data()
iris_first = []
iris_second = []
iris_third = []
for i in range(0,len(data_y)):
if(data_y[i]==0):
iris_first.append(data_x[i,:].numpy())
elif(data_y[i]==2):
iris_second.append(data_x[i,:].numpy())
else:
iris_third.append(data_x[i,:].numpy())
iris_first = torch.tensor(iris_first)
iris_second = torch.tensor(iris_second)
iris_third = torch.tensor(iris_third)
plt.scatter(iris_first[:,0],iris_first[:,1],c='b')
plt.scatter(iris_second[:,0],iris_second[:,1],c='y')
plt.scatter(iris_third[:,0],iris_third[:,1],c='g')
plt.legend(['iris versicolor','iris setosa','iris vlrglnica'])
plt.show()
load_data:
import torch
import numpy as np
from sklearn.datasets import load_iris
# 加载数据集
def load_data(shuffle=True):
# 加载原始数据
X = np.array(load_iris().data, dtype=np.float32)
y = np.array(load_iris().target, dtype=np.int32)
X = torch.tensor(X)
y = torch.tensor(y)
# 数据归一化
X_min = torch.min(X, dim=0)
X_max = torch.max(X, dim=0)
X = (X - X_min.values) / (X_max.values - X_min.values)
# 如果shuffle为True,随机打乱数据
if shuffle:
idx = torch.randperm(X.shape[0])
X = X[idx]
y = y[idx]
return X, y
4.5 实践:基于前馈神经网络完成鸢尾花分类
继续使用第三章中的鸢尾花分类任务,将Softmax分类器替换为前馈神经网络。
- 损失函数:交叉熵损失;
- 优化器:随机梯度下降法;
- 评价指标:准确率。
4.5.1 小批量梯度下降法
批量梯度下降法: 在梯度下降法中,目标函数是整个训练集上的风险函数,这种方式称为批量梯度下降法(Batch Gradient Descent,BGD)。 批量梯度下降法在每次迭代时需要计算每个样本上损失函数的梯度并求和。当训练集中的样本数量N NN很大时,空间复杂度比较高,每次迭代的计算开销也很大。
小批量梯度下降法: 为了减少每次迭代的计算复杂度,我们可以在每次迭代时只采集一小部分样本,计算在这组样本上损失函数的梯度并更新参数,这种优化方式称为小批量梯度下降法(Mini-Batch Gradient Descent,Mini-Batch GD)。
第次迭代时,随机选取一个包含个样本的子集,计算这个子集上每个样本损失函数的梯度并进行平均,然后再进行参数更新。
其中K为批量大小(Batch Size)。K通常不会设置很大,一般在1∼1001∼100之间。在实际应用中为了提高计算效率,通常设置为2的幂2^{n}。
在实际应用中,小批量随机梯度下降法有收敛快、计算开销小的优点,因此逐渐成为大规模的机器学习中的主要优化算法。此外,随机梯度下降相当于在批量梯度下降的梯度上引入了随机噪声。在非凸优化问题中,随机梯度下降更容易逃离局部最优点。
小批量随机梯度下降法的训练过程如下:
4.5.1.1 数据分组
为了使用小批量梯度下降法,我们需要对数据进行随机分组。目前,机器学习中通常做法是构建一个数据迭代器,每个迭代过程中从全部数据集中获取一批指定数量的数据。
数据迭代器的实现原理如下图所示:
(1)首先,将数据集封装为Dataset类,传入一组索引值,根据索引从数据集合中获取数据;
(2)其次,构建DataLoader类,需要指定数据批量的大小和是否需要对数据进行乱序,通过该类即可批量获取数据。
在实践过程中,通常使用进行参数优化。在pytorch中,使用torch.utils.data.DataLoader加载minibatch的数据,torch.utils.data.DataLoader API可以生成一个迭代器,其中通过设置batch_size参数来指定minibatch的长度,通过设置shuffle参数为True,可以在生成minibatch的索引列表时将索引顺序打乱。
4.5.2 数据处理
构造IrisDataset类进行数据读取,继承自torch.utils.data.Dataset类。torch.utils.data.Dataset是用来封装 Dataset的方法和行为的抽象类,通过一个索引获取指定的样本,同时对该样本进行数据处理。当继承torch.utils.data.Dataset来定义数据读取类时,实现如下方法:
__getitem__:根据给定索引获取数据集中指定样本,并