[机器学习]k-NN算法相关知识点

开一个新专题,每次讲一个机器学习算法的知识点。


k近邻(k-Nearest Neighbor, 简称k-NN)学习是一种常用的监督学习方法。

工作机制: 给定测试样本,基于某种距离度量找出训练集中与其最靠近的 k 个训练样本,然后基于这 k 个"邻居 “的信息来进行预测 . 既可以回答分类问题,也可以回答回归问题。通常,在分类任务中可使用 “投票法” 即选择这 k 个样本中出现最多的类别标记作为预测结果;在回归任务中时使用"平均法”,即将这 k 个样本的实值输出标记的平均值作为预测结果;还可基于距离远近进行加权平均或加权投票,距离越近的样本权重越大.

这种学习算法没有显式的训练过程,属于"懒惰学习"(lazy learning) ,此类学习技术在训练阶段仅仅是把样本保存起来,训练时间开销为零,待收到
测试样本后再进行处理;相应的,那些在训练阶段就对样本进行学习处理的方
法,称为"急切学习" (eager learning)。

lazy learning和eager learning的区别如下:

  • 懒惰学习比急切学习在训练阶段花的时间少,但是在预测阶段花的时间较多
  • 懒惰学习都是用局部的线性函数来近似,而急切学习都是全局的方法

摘自统计学习方法

kNN算法有三个要素,分别是:

  • k值的选择
  • 距离的度量
  • 分类决策规则

k值的选择

摘自周志华西瓜书
如果选择较小的k值,就相当于用较小的邻域中的训练实例进行预测,“学习”的近似误差(bias)会减小,只有与输入实例较近的训练实例才会对预测结果起到作用。但缺点是“学习”的估计误差(variance)会增大,预测结果会对近邻的实例点非常敏感。
换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合。
如果选择较大的k值,就相当于用较大的邻域中的训练实例进行预测,其优点是“学习”的估计误差(variance)会减小。但缺点是“学习”的近似误差(bias)会增大,这时候与输入实例较远的训练实例也会对预测起作用,使预测发生错误。
即k值的增大就意味着整体模型变得简单,完全忽略训练实例中的大量有用信息,不可取。

k=3~10,一般用交叉验证选取k值。

最近邻分类器虽简单,但它的泛化错误率不超过贝叶斯最优分类器的错误率的两倍。

注意:数据需要标准化

距离的度量

有几种距离计算方法:

  • 明氏距离
    L p ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ p ) 1 p L_p(x_i,x_j)=(\sum_{l=1}^n |x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}} Lp(xi,xj)=
这段代码定义了一个名为 VGG19Encoder 的神经网络模型。它使用了预训练的 VGG19 模型的前四个卷积层和最后一个全连接层作为特征提取器,其中前四个卷积层被分别用于提取不同层级的特征。然后,通过几个额外的卷积层和全连接层将提取的特征转换为对输入图像中物体类别的预测。其中,提取的特征被分别送入四个全连接层中进行分类。 具体来说,代码中的各个部分的功能如下: - `features_list = list(vgg19.features.children())`:获取 VGG19 模型的所有卷积层。 - `self.conv2_2 = torch.nn.Sequential(*features_list[:13])`:将前 13 层卷积层作为 conv2_2 层。 - `self.conv3_4 = torch.nn.Sequential(*features_list[13:26])`:将第 14 层到第 26 层卷积层作为 conv3_4 层。 - `self.conv4_4 = torch.nn.Sequential(*features_list[26: 39])`:将第 27 层到第 39 层卷积层作为 conv4_4 层。 - `self.conv5_4 = torch.nn.Sequential(*features_list[39:-1])`:将第 40 层到倒数第二层卷积层作为 conv5_4 层。 - `self.tail_layer = features_list[-1]`:将最后一层卷积层作为尾部层。 - `self.fc_layers = list(vgg19.classifier.children())[:-2]`:获取 VGG19 模型的所有全连接层,但不包括最后两层。 - `self.fc_layers = torch.nn.Sequential(*list(self.fc_layers))`:将所有全连接层组成一个新的连续的全连接层。 - `self.extract_0 = torch.nn.Sequential(torch.nn.MaxPool2d(kernel_size=8, stride=8), torch.nn.Conv2d(128, self.k, kernel_size=1, stride=1))`:将 conv2_2 层的输出进行最大池化和卷积操作,以提取更高级别的特征。 - `self.extract_1 = torch.nn.Sequential(torch.nn.MaxPool2d(kernel_size=4, stride=4), torch.nn.Conv2d(256, self.k, kernel_size=1, stride=1))`:将 conv3_4 层的输出进行最大池化和卷积操作,以提取更高级别的特征。 - `self.extract_2 = torch.nn.Sequential(torch.nn.MaxPool2d(kernel_size=2, stride=2), torch.nn.Conv2d(512, self.k, kernel_size=1, stride=1))`:将 conv4_4 层的输出进行最大池化和卷积操作,以提取更高级别的特征。 - `self.extract_3 = torch.nn.Sequential(torch.nn.Conv2d(512, self.k, kernel_size=1, stride=1))`:将 conv5_4 层的输出进行卷积操作,以提取更高级别的特征。 - `self.fc0 = torch.nn.Linear(196, 1, bias=True)`:定义一个输入为 196 的全连接层,用于分类。 - `self.fc1 = torch.nn.Linear(196, 1, bias=True)`:定义第二个输入为 196 的全连接层,用于分类。 - `self.fc2 = torch.nn.Linear(196, 1, bias=True)`:定义第三个输入为 196 的全连接层,用于分类。 - `self.fc3 = torch.nn.Linear(196, 1, bias=True)`:定义第四个输入为 196 的全连接层,用于分类。 - `self.fc4 = torch.nn.Linear(4096, 2 * k, bias=True)`:定义一个输入为 4096 的全连接层,用于分类。 - `self.bn1 = torch.nn.BatchNorm1d(k)`:定义一个 Batch Normalization 层,用于归一化数据。 - `self.bn2 = torch.nn.BatchNorm1d(k)`:定义第二个 Batch Normalization 层,用于归一化数据。 - `weight_init(self.fc0, self.fc1, self.fc2, self.fc3, self.fc4)`:对所有全连接层进行权重初始化,以提高模型的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值