- 2024-09-08
-
发表了主题帖:
《智能驾驶之激光雷达算法详解》空间变换数学基础
本帖最后由 lospring 于 2024-9-8 23:50 编辑
下面介绍一些坐标系欧氏变换的基础数学。
在进行激光雷达的外参标定时,我们实际上是求解激光雷达坐标系相对车体坐标系的姿态和相对位置;在进行车辆定位时,我们通常是在求解车体坐标系的相对变化量及其相对世界参考坐标系的变化量。这两个坐标系之间的位置和姿态变化构成了欧氏变换。其中,姿态描述的是一个坐标系的轴系相对另一个坐标系轴系的旋转或方向关系,相对位置描述的是一个坐标系的原点相对另一个坐标系原点的平移关系。
1.1、旋转和平移变换
首先考虑两坐标系间具有共同原点且仅有相对旋转的情况。则点P的坐标系1和坐标系2下的三维向量可分别表示为
=
=
结合假设两坐标系的单位正交基分别为;。以及坐标系2在坐标系1下单位正交基的投影关系最终可得
=
其中旋转矩阵=
我们可以进一步分析得到旋转矩阵是行列式为1的正交阵,因此旋转矩阵R与其转置矩阵的相乘结果为单位阵E,所以,所以
再进一步可以看出物体相对于坐标轴的旋转和坐标轴相对于物体的等角度反向旋转在描述上是等效的。
齐次矩阵则是考虑了两坐标系间同时具有旋转和平移的情况。最终可得。
1.2、旋转的欧拉角表示
在使用旋转矩阵R表示三维空间中的旋转和姿态时,共需要9个变量来表示,而对应的旋转本身则通常只有3个自由度。这种表达明显带来参数冗余,使得求解复杂。所以采用欧拉角姿态表示。
根据旋转轴顺序的不同,欧拉角有多种形式。以RPY为例,绕X轴旋转角称为翻滚角R,绕Y轴旋转角称为俯仰角P,绕Z轴旋转角称为Y。欧拉角描述的空间旋转与其转动顺序强相关,且欧拉角的三个分量不具有互换性,在求解RPY的逆变换时,不能仅对角度取负实现,而应该按照相反的旋转顺序反转相应的角度。当俯仰角pitch=时,欧拉角描述的旋转存在奇异性,此时滚动角和领航角无法区分,其描述的旋转会出现退化现象,称为欧拉角的万向锁现象。所以在优化和滤波等迭代算法中通常不使用欧拉角表示较大的旋转变换。
1.3、旋转的轴角表示/旋转向量表示
旋转向量到旋转矩阵的转换关系如下:
1.4、旋转的单位四元数表示
四元数是将二维空间中的复数扩展至三维空间中得到的超复数:
i,j,k为虚数单位,分别对应坐标系的三个轴,并满足
采用矢量形式表示为
2.1 李群、李代数
为简化位姿估计相关的求解过程,引入李群和李代数。
群通常表示为由有限或无限个元素构成的集合加上一种运算的代数结构。具有群结构的光滑微分流形为李群,即若G为一个群,同时它又是D维空间的一个流形,并且其群乘积和取逆操作都是平滑函数,则G为一个李群。李代数是一个由集合V,数域F和一个李括号运算组成的代数结构,用于表示被赋予李括号运算的线性空间。在三维空间中,向量的叉乘运算即为该空间的李括号运算,所以李代数实际上是李群在其幺元处的切空间,它能够完全捕获李群的局部结构,并且李群M,李代数m可表示为。之后可通过李群和李代数的映射关系将流形空间中待求解的问题表示成对应的线性空间的李代数结构,从而使得利用线性空间中的模型和算法成为可能。
-
发表了主题帖:
《智能驾驶之激光雷达算法详解》初识激光雷达
1、激光雷达基本原理
激光雷达是光探测和测距的简称,常见的车载机械式激光雷达大致原理为:激光雷达以激光作为信号源,由激光器发射出脉冲激光,打到地面、树木、车辆、道路、桥梁和建筑物等被测物体表面上,随后激光发生散射,一部分光波会被反射到激光雷达的接收器上,再根据激光测距原理,即可得到从激光雷达到目标点的距离信息,进而通过激光器不断地水平旋转,便可得到周围目标物上的全部激光点数据;再能此数据进行成像处理,便可得到周围环境的三维立体点云。
2、激光雷达的分类
激光雷达可以按光源、发射端、接收端、扫描系统进行分类
机械扫描式技术成熟,但成本较高,供货周期长,体积大,运动部件较多以及难以符合车规要求等,尚无法满足量产车辆的内嵌安装需求,目前多作为robottaxi的激光雷达解决方案或用于数据采集车辆中。MEMS振镜式、透射棱镜式和转镜式是目前影响力较大的半固态激光雷达,已逐步应用于量产车型中。FLASH和OPA为纯固态激光雷达,业界认为是未来车载激光雷达的技术趋势,但由于现阶段探测范围、技术成熟度和成本等问题,应用较少。
3、车载激光雷达的应用功能
激光雷达多应用于智能车的感知系统和定位系统中
下图为感知系统流程示例
在记忆泊车、自动辅助导航四驾驶等L2+的智能驾驶中,除了需要进行目标、道路环境的感知检测外,还需要实时确定车辆的行驶位置。由于成本原因,车载GPS能够提供的定位精度通常为米级,信号频率为1Hz,在地下停车场,高架桥下等场景还会由于遮挡丢失GPS信号。为了弥补GPS的上述缺点,通过实时激光雷达点云和图像与事先建立的高精度地图进行帧-图匹配,可得到车辆的绝对位置估计再将其与GPS信号结合,在一定程度上可以降低GPS信号丢失对绝对位置计算的影响。
- 2024-09-02
-
回复了主题帖:
《智能驾驶之激光雷达算法详解》概述
秦天qintian0303 发表于 2024-9-1 18:27
彩色书籍还是比较良心的,看着赏心悦目
书籍质量挺不错的
- 2024-09-01
-
发表了主题帖:
《智能驾驶之激光雷达算法详解》概述
本书是系统性介绍车载激光雷达关键算法的技术书,全书共14章,涉及激光雷达和智能驾驶的基础知识,以及激光雷达在智能驾驶中的标定、感知和定位方法,基本涵盖了当前车载激光雷达的应用场景。需要的数学知识比较多,包括了大量的公式推导。
智能驾驶是辅助驾驶和自动驾驶的统称,通常指汽车通过搭载先进的传感器、控制器等设备,结合人工智能算法以辅助驾驶员对车辆的操控甚至实现无人驾驶。随着智能驾驶的兴起,大量的技术研究,加快了智能驾驶技术的商业化落地。目前智能驾驶的感知技术主要分为以相机和激光雷达为主导的多传感器融合方案两个方向。目前激光雷达的硬件成本正快速下降,致使车企明显加速了激光雷达的应用进度。所以激光雷达的算法工程师需求量也在逐步增大。
第1章介绍了激光雷达的基本硬件原理、发展历程及特点、功能和商业化应用现状。第2章介绍了坐标系欧氏变的基础和李群、李代数基础。第3、4章介绍了有代表性的激光雷达与车体的外参标定算法以及激光雷达和相机间的外参标定,涵盖了基于标定物、无标定物、离线标定和在线标定等多种标定模式。5-6,8-10章为感知算法,介绍了基于激光雷达进行地面检测、障碍物聚类、目标检测、多目标跟踪、路沿检测的代表性算法。11-13章介绍了几种定位算法,14章对车载激光雷达的未来发展进行了介绍。
本书可以作为高校教材,也可代智能驾驶或机器人领域的技术爱好者以及激光雷达标定、感知、定位算法工程师使用。
- 2024-08-16
-
回复了主题帖:
充电十分钟,续航1000公里!油车时代彻底结束了?
还是担心安全问题,这么大的功率电池是不是就更容易损伤?
- 2024-08-15
-
发表了主题帖:
【2024 DigiKey 创意大赛】物料开箱
感谢DigiKey提供的这次机会,活动很棒。
本次项目主要用到RT1062 Teensy 4.1 i.MX ARM® Cortex®-M7 MPU 评估板;AK09916,ICM-20948加速计,陀螺仪,磁力计,传感器Qwiic,STEMMA QT平台评估扩展板;BME680气体,湿度,压力,温度传感器Qwiic,STEMMA QT平台评估扩展板。发货速度非常快。
- 2024-08-13
-
回复了主题帖:
共读入围名单: 《智能驾驶之激光雷达算法详解》
个人信息无误,确认可以完成评测计划
- 2024-08-11
-
发表了主题帖:
《机器学习算法与实现 —— Python编程与应用实例》深度学习AlexNet
AlexNet的网络架构如下图所示:
可见Alexnet模型由5个卷积层和3个池化Pooling和3个全连接层构成,共有6×1076×10^7个参数和65000个神经元,最终的输出层是1000通道的Softmax。AlexNet使⽤了更多的卷积层和更⼤的参数空间来拟合⼤规模数据集 ImageNet,它是浅层神经⽹络和深度神经⽹络的分界线。
以下使用PyTorch实现AlexNet
import torch.nn as nn
import torch
from torch.autograd import Variable
class AlexNet(nn.Module):
def __init__(self, num_classes=1000, init_weights=False):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True), #inplace可以载入更大的模型
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(96, 256, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(256, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(p=0.5),
nn.Linear(256*6*6, 4096), #全连接
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)
if init_weights:
self._initialize_weights()
def forward(self, x):
x = self.features(x)
x = torch.flatten(x, start_dim=1) #展平或者view()
x = self.classifier(x)
return x
由于AlexNet较复杂,使用简单的数据集无法体现其优势,因此本次试验需要用到CIFAR10数据集,CIFAR10 这个数据集一共有 50000 张训练集,10000 张测试集,两个数据集里面的图片都是 png 彩色图片,图片大小是 32 x 32 x 3,一共是 10 分类问题,分别为飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船和卡车。这个数据集是对网络性能测试一个非常重要的指标,可以说如果一个网络在这个数据集上超过另外一个网络,那么这个网络性能上一定要比另外一个网络好,目前这个数据集最好的结果是 95% 左右的测试集准确率。CIFAR10 已经被 PyTorch 内置了,使用非常方便,只需要调用torchvision.datasets.CIFAR10就可以了。
以下是训练AlexNet网络模型
from torchvision.datasets import CIFAR10
from torch.utils.data import DataLoader
from torchvision import transforms as tfs
from utils import train
import matplotlib.pyplot as plt
%matplotlib inline
# 数据转换
def data_tf(x):
im_aug = tfs.Compose([
tfs.Resize(227),
tfs.ToTensor(),
tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
x = im_aug(x)
return x
train_set = CIFAR10('../../data', train=True, transform=data_tf)
train_data = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
test_set = CIFAR10('../../data', train=False, transform=data_tf)
test_data = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=False)
net = AlexNet(num_classes=10)
optimizer = torch.optim.Adam(net.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
res = train(net, train_data, test_data, 20, optimizer, criterion, use_cuda=True)
plt.plot(res[0], label='train')
plt.plot(res[2], label='valid')
plt.xlabel('epoch')
plt.ylabel('Loss')
plt.legend(loc='best')
plt.show()
plt.plot(res[1], label='train')
plt.plot(res[3], label='valid')
plt.xlabel('epoch')
plt.ylabel('Acc')
plt.legend(loc='best')
plt.show()
AlexNet网络模型需要输入的图像尺寸是227*227,所以需要使用tfs.Resize(227)将输入的图像重新采样为227*227大小,然后再转换成Tensor,最后对数据进行归一化处理。试验进行了20次迭代,损失和准确率变化如下,随着训练的进行,损失一直下降,准确率一直上升。
- 2024-08-04
-
发表了主题帖:
《机器学习算法与实现 —— Python编程与应用实例》神经网络的训练 - 反向传播算法
在多层神经网络中有这样一个问题:最后一层的参数可以用这样的方式求解得到;隐层节点没有输出的真值,因此无法直接构建损失函数来求解。
反向传播算法可以解决该问题,反射传播自满其实就是链式求导法则的应用。
按照机器学习的通用求解思路,我们先确定神经网络的目标函数,然后用随机梯度下降优化算法去求目标函数最小值时的参数值。
取网络所有输出层节点的误差平方和作为目标函数:
其中,Ed表示是样本d的误差, t是样本的标签值,y是神经网络的输出值。
然后,使用随机梯度下降算法对目标函数进行优化:
随机梯度下降算法也就是需要求出误差Ed对于每个权重wji的偏导数(也就是梯度),如何求解?
观察上图,可发现权重wji仅能通过影响节点j的输入值影响网络的其它部分,设netj是节点j的加权输入,即
Ed是netj的函数,而netj是wji的函数。根据链式求导法则,可以得到:
上式中,xji是节点传递给节点j的输入值,也就是节点i的输出值。
对于的∂Ed/∂netj推导,需要区分输出层和隐藏层两种情况。
1、输出层权值训练
对于输出层来说,netj仅能通过节点j的输出值yj来影响网络其它部分,也就是说Ed是yj的函数,而yj是netj的函数,其中yj=sigmod(netj)。所以我们可以再次使用链式求导法则:
其中:
将第一项和第二项带入,得到:
如果令δj=−∂Ed/∂netj,也就是一个节点的误差项δ是网络误差对这个节点输入的偏导数的相反数。带入上式,得到:
将上述推导带入随机梯度下降公式,得到:
2、隐藏层权值训练
现在我们要推导出隐藏层的∂Ed/∂netj∂:
首先,我们需要定义节点j的所有直接下游节点的集合Downstream(j)。例如,对于节点4来说,它的直接下游节点是节点8、节点9。可以看到netj只能通过影响Downstream(j)再影响Ed。设netk是节点j的下游节点的输入,则Ed是netk的函数,而netk是netj的函数。因为netk有多个,我们应用全导数公式,可以做出如下推导:
因为δj=−∂Ed/∂netj,带入上式得到:
至此,我们已经推导出了反向传播算法。需要注意的是,我们刚刚推导出的训练规则是根据激活函数是sigmoid函数、平方和误差、全连接网络、随机梯度下降优化算法。如果激活函数不同、误差计算方式不同、网络连接结构不同、优化算法不同,则具体的训练规则也会不一样。但是无论怎样,训练规则的推导方式都是一样的,应用链式求导法则进行推导即可。
3、具体解释
然后,按照下面的方法计算出每个节点的误差项δi:
对于输出层节点i
其中,δi是节点i的误差项,yi是节点i的输出值,ti是样本对应于节点i的目标值。举个例子,根据上图,对于输出层节点8来说,它的输出值是y1,而样本的目标值是t1,带入上面的公式得到节点8的误差项应该是:
对于隐藏层节点
其中,ai是节点i的输出值,wki是节点i到它的下一层节点k的连接的权重,δk是节点i的下一层节点k的误差项。例如,对于隐藏层节点4来说,计算方法如下:
最后,更新每个连接上的权值:
其中,wji是节点i到节点j的权重,η是一个成为学习速率的常数,δj是节点j的误差项,xji是节点i传递给节点j的输入。例如,权重w84的更新方法如下:
类似的,权重w41的更新方法如下:
偏置项的输入值永远为1。例如,节点4的偏置项w4b应该按照下面的方法计算:
计算一个节点的误差项,需要先计算每个与其相连的下一层节点的误差项,这就要求误差项的计算顺序必须是从输出层开始,然后反向依次计算每个隐藏层的误差项,直到与输入层相连的那个隐藏层,这就是反向传播算法的名字的含义。当所有节点的误差项计算完毕后,就可以根据式5来更新所有的权重。
以上就是反向传播算法的一个求解过程,整个过程也是搬抄其它大佬的结果,希望对大家有点帮助。
-
发表了主题帖:
《机器学习算法与实现 —— Python编程与应用实例》评估聚性能的方法
本帖最后由 lospring 于 2024-8-4 19:23 编辑
k-Means是无监督学习的算法之一。k-means就是将n个数据点进行聚类分析,得到 k 个聚类,使得每个数据点到聚类中心的距离最小。
k-Means的相关过程很容易获得,整体的推导过程实在是没什么意义再复制出来,下面就看看评估聚性能的方法:
方法1 - ARI
如果被用来评估的数据本身带有正确的类别信息,则利用Adjusted Rand Index(ARI)对聚类结果进行评估,ARI与分类问题中计算准确性的方法类似,兼顾了类簇无法和分类标记一一对应的问题。
1、RI
为了方便理解ARI,先讨论一下RI,也就是rand index,是ARI的基础方法。
假如有两类,那么针对这两类的的RI评价指标为:
a,b,c,d分别代表的含义为:
a : 应该在一类,最后聚类到一类的数量,
b : 不应该在一类,最后聚类结果也没把他们聚类在一起的数量。
c和d那么就是应该在一起而被分开的和不应该在一起而被迫在一起的。毕竟强扭的瓜不甜,c和d固然是错误的。
所以从R的表达式中可以看出,a和b是对的,这样能够保证R在0到1之间,而且,聚类越准确,指标越接近于1.
这里有一个关键性的问题,就是什么叫数量?怎么去计算?准确的说,是配对的数量。比如说a是应该在一起而真的幸福的在一起了的数量,这显然就应该像人类一样按照小夫妻数量计算,但是我们的样本可不管一夫一妻制,任意选两个就是一个配对,所以,就是 n(n−1)/2这样来计算,也就是组合数,n个当中选两个的选法。同时我们看到,分母其实是所有配对的总和,所以,我们最后可以写成这样:
2、ARI
有了先前RI的感性理解之后,接下来解释一下ARI。
RI有一个缺点,就是惩罚力度不够,换句话说,大家普遍得分比较高,没什么区分度,普遍80分以上。这样的话,往往是评价区分性不是特别好,于是就诞生出了ARI,这个指标相对于RI就很有区分度了。
具体的公式是:
ARI取值范围为[-1,1],值越大越好,反映两种划分的重叠程度,使用该度量指标需要数据本身有类别标记。
关联表(contingency table)的定义:
表中:
公式中:
假设配对矩阵是这样的,共有 n(n−1)/2 个配对方法。在行方向计算出可能取到的配对数,在列方向计算可能取到的配对数,相乘以后,除以总的配对数,这就是a的期望了。
from sklearn.metrics import adjusted_rand_score
ari_train = adjusted_rand_score(y_train, kmeans.labels_)
print("ari_train = %f" % ari_train)
方法2 - 轮廓系数
如果被用来评估的数据没有所属类别,则使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量,评估聚类的效果。轮廓系数同时兼顾了聚类的凝聚度和分离度,取值范围是[-1,1],轮廓系数越大,表示聚类效果越好。
轮廓系数的具体计算步骤:
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize']=(10,10)
plt.subplot(3,2,1)
x1=np.array([1,2,3,1,5,6,5,5,6,7,8,9,7,9]) #初始化原始数据
x2=np.array([1,3,2,2,8,6,7,6,7,1,2,1,1,3])
X=np.array(list(zip(x1,x2))).reshape(len(x1),2)
plt.xlim([0,10])
plt.ylim([0,10])
plt.title('Instances')
plt.scatter(x1,x2)
colors=['b','g','r','c','m','y','k','b']
markers=['o','s','D','v','^','p','*','+']
clusters=[2,3,4,5,8]
subplot_counter=1
sc_scores=[]
for t in clusters:
subplot_counter +=1
plt.subplot(3,2,subplot_counter)
kmeans_model=KMeans(n_clusters=t).fit(X) #KMeans建模
for i,l in enumerate(kmeans_model.labels_):
plt.plot(x1[i],x2[i],color=colors[l],marker=markers[l],ls='None')
plt.xlim([0,10])
plt.ylim([0,10])
sc_score=silhouette_score(X,kmeans_model.labels_,metric='euclidean') #计算轮廓系数
sc_scores.append(sc_score)
plt.title('k=%s,silhouette coefficient=%0.03f'%(t,sc_score))
plt.figure()
plt.plot(clusters,sc_scores,'*-') #绘制类簇数量与对应轮廓系数关系
plt.xlabel('Number of Clusters')
plt.ylabel('Silhouette Coefficient Score')
plt.savefig('fig-res-k-means_silhouette_coef.pdf')
plt.show()
- 2024-07-21
-
发表了主题帖:
《机器学习算法与实现 —— Python编程与应用实例》KNN算法
K最近邻(k-Nearest Neighbor,kNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。简单来说,kNN可以看成:有那么一堆你已经知道分类的数据,然后当一个新数据进入的时候,就开始跟训练数据里的每个点求距离,然后挑选这个训练数据最近的K个点,看看这几个点属于什么类型,然后用少数服从多数的原则,给新数据归类。kNN算法不仅可以用于分类,还可以用于回归。
跟着书中的实验学习一下
生成训练数据和测试数据
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
# 生成模拟数据
np.random.seed(314)
data_size1 = 1000
x1 = np.random.randn(data_size1, 2)*2 + np.array([4,4])
y1 = [0 for _ in range(data_size1)]
data_size2 = 1000
x2 = np.random.randn(data_size2, 2)*2 + np.array([10,10])
y2 = [1 for _ in range(data_size2)]
# 合并生成全部数据
x = np.concatenate((x1, x2), axis=0)
y = np.concatenate((y1, y2), axis=0)
data_size_all = data_size1 + data_size2
shuffled_index = np.random.permutation(data_size_all)
x = x[shuffled_index]
y = y[shuffled_index]
# 分割训练与测试数据
split_index = int(data_size_all*0.7)
x_train = x[:split_index]
y_train = y[:split_index]
x_test = x[split_index:]
y_test = y[split_index:]
# 绘制结果
for i in range(split_index):
if y_train[i] == 0:
plt.scatter(x_train[i,0],x_train[i,1], s=38, c = 'r', marker='.')
else:
plt.scatter(x_train[i,0],x_train[i,1], s=38, c = 'b', marker='^')
#plt.rcParams['figure.figsize']=(12.0, 8.0)
mpl.rcParams['font.family'] = 'SimHei'
plt.title("训练数据")
plt.savefig("fig-res-knn-traindata.pdf")
plt.show()
for i in range(data_size_all - split_index):
if y_test[i] == 0:
plt.scatter(x_test[i,0],x_test[i,1], s=38, c = 'r', marker='.')
else:
plt.scatter(x_test[i,0],x_test[i,1], s=38, c = 'b', marker='^')
#plt.rcParams['figure.figsize']=(12.0, 8.0)
mpl.rcParams['font.family'] = 'SimHei'
plt.title("测试数据")
plt.savefig("fig-res-knn-testdata.pdf")
plt.show()
KNN实现主要分为三步:计算距离,按距离取样本,投票决定类别。分别定义这三步函数为knn_distance(),knn_vote(),knn_predict()
import numpy as np
import operator
def knn_distance(v1, v2):
"""计算两个多维向量的距离"""
return np.sum(np.square(v1-v2))
def knn_vote(ys):
"""根据ys的类别,挑选类别最多一类作为输出"""
vote_dict = {}
for y in ys:
if y not in vote_dict.keys():
vote_dict[y] = 1
else:
vote_dict[y] += 1
method = 1
# 方法1 - 使用循环遍历找到类别最多的一类
if method == 1:
maxv = maxk = 0
for y in np.unique(ys):
if maxv < vote_dict[y]:
maxv = vote_dict[y]
maxk = y
return maxk
# 方法2 - 使用排序的方法
if method == 2:
sorted_vote_dict = sorted(vote_dict.items(), \
#key=operator.itemgetter(1), \
key=lambda x:x[1], \
reverse=True)
return sorted_vote_dict[0][0]
def knn_predict(x, train_x, train_y, k=3):
"""
针对给定的数据进行分类
参数
x - 输入的待分类样本
train_x - 训练数据的样本
train_y - 训练数据的标签
k - 最近邻的样本个数
"""
dist_arr = [knn_distance(x, train_x[j]) for j in range(len(train_x))]
sorted_index = np.argsort(dist_arr)
top_k_index = sorted_index[:k]
ys=train_y[top_k_index]
return knn_vote(ys)
# 对每个样本进行分类
y_train_est = [knn_predict(x_train[i], x_train, y_train, k=5) for i in range(len(x_train))]
print(y_train_est)
# 绘制结果
for i in range(len(y_train_est)):
if y_train_est[i] == 0:
plt.scatter(x_train[i,0],x_train[i,1], s=38, c = 'r', marker='.')
else:
plt.scatter(x_train[i,0],x_train[i,1], s=38, c = 'b', marker='^')
#plt.rcParams['figure.figsize']=(12.0, 8.0)
mpl.rcParams['font.family'] = 'SimHei'
plt.title("Train Results")
plt.savefig("fig-res-knn-train-res.pdf")
plt.show()
计算一下训练和测试精度
# 计算训练数据的精度
n_correct = 0
for i in range(len(x_train)):
if y_train_est[i] == y_train[i]:
n_correct += 1
accuracy = n_correct / len(x_train) * 100.0
print("Train Accuracy: %f%%" % accuracy)
# 计算测试数据的精度
y_test_est = [knn_predict(x_test[i], x_train, y_train, 3) for i in range(len(x_test))]
n_correct = 0
for i in range(len(x_test)):
if y_test_est[i] == y_test[i]:
n_correct += 1
accuracy = n_correct / len(x_test) * 100.0
print("Test Accuracy: %f%%" % accuracy)
print(n_correct, len(x_test))
Train Accuracy: 97.857143%
Train Accuracy: 96.666667%%
58 60
至此验证了KNN算法的可行性和可靠性。
- 2024-07-08
-
发表了主题帖:
《机器学习算法与实现 —— Python编程与应用实例》试读一
很荣幸能够试读该书,由于拿到时间比较短,只大致翻读了前两章,跟大家大致分享一下。
本书一共11章,全书共332,是一本很厚实的书,而且书中插图均为彩色,是比较不多见的。
前三章为python基础知识讲解,包括环境搭建,及基本语法数据结构等。本书是基于Jupyter Notebook为开发工具进行试验的,所以本书着重讲解了相关的安装使用方法。由于本人不是计算机专业,很多知识学习的都不是很系统,书中的很多地方也对我的知识体系进行了补缺补漏,如设置conda软件源,Jupyter Notebook快捷键查看方法(在单元格呈蓝色时按"h"键查看),Magic关键字等。
对于数据结构方面,书中介绍了列表,元组,集合,字典等,不仅给出了各数据结构的定义,还有操作方法及常用函数,并且也给出了详尽的实例。但是数据结构应该是初学者最容易搞不清楚的地方,还是建议对其进行比较,并且单独开辟一个小节进行归纳总结。毕竟本书实际应该是作为高校教材,内容应该更加聚焦基础。下面对这几种数据结构进行一些总结,希望大家批评指正
列表:动态,长度不固定,可以增删改;支持索引、切片、嵌套、函数转换和内置函数。
元组:静态,长度固定,不能直接增删改,但可以合并元组;支持索引、切片、嵌套、函数转换和内置函数。
字典:由key和value组成,字典是有序的,可变的;支持索引操作,key不能重复,字典对应的哈希表中存储了哈希值、key和value
集合:集合没有key和value的配对,是无序的,且元素值唯一,可变的;不支持索引/切片操作,值不能重复,集合对应的哈希表中仅存储了哈希值
4-6章主要介绍三种机器学习算法,K最近邻算法,K均值聚类算法及逻辑斯蒂回归。将在接下来的两周进行阅读和实践,希望进度能快一点,好好学习一下这本书。
- 2024-06-20
-
回复了主题帖:
共读入围:《机器学习算法与实现 —— Python编程与应用实例》
个人信息确认无误,确认可以完成测评分享计划
- 2024-05-25
-
加入了学习《泰克 4 系列 B MSO》,观看 4系列B MSO示波器
- 2024-03-11
-
回复了主题帖:
汽车VCU知识问答第一站:了解VCU系统框图和功能清单
1、VCU即整车控制器,是新能源汽车控制系统的核心控制单元。它就像是整车的大脑一样,采集输入信号,输出负载控制信号,协调各个控制系统工作并且提供监控检测功能随着新能源EE架构的迭代及控制单元集成度越来越高,VCU的功能可能会被拆解到中央控制器+域控制器,或者拆解到多合一的控制单元
-
回复了主题帖:
汽车VCU知识问答第一站:了解VCU系统框图和功能清单
2、VCU主要功能包括:驱动力矩控制、制动能量的优化控制、整车的能量管理、充电管理、通讯及网络管理、故障诊断和处理、车辆状态监视等
-
回复了主题帖:
汽车VCU知识问答第一站:了解VCU系统框图和功能清单
4、目前VCU一般采用ASIL-D级别的MCU作为主控
-
回复了主题帖:
汽车VCU知识问答第一站:了解VCU系统框图和功能清单
3、诊断和标定,网关
- 2024-02-19
-
回复了主题帖:
2024开工大吉,你期待测评中心,能有哪些板卡或书籍等?
鲁班猫4上一上,性能比较好的板子,可以评测的内容比较多。
- 2024-01-20
-
加入了学习《picow_eeworld_taikongrenbiaopan》,观看 picow太空人表盘