简单回答,基于划分,基于密度,基于网络,层次聚类,除此之外聚类和其他领域也有很多的结合形成的交叉领域比如半监督聚类,深度聚类,集成聚类等等。
kmeans是一种基于划分的聚类,中心思想很简单,类内距离尽量小,类间距离尽量大,算法过程为:
S S E = ∑ k = 1 K ∑ p ∈ C k ∣ p − m k ∣ 2 SSE=\sum_{k=1}^K\sum_{p\in{C_k}}|p-m_k|^2 SSE=k=1∑Kp∈Ck∑∣p−mk∣2
其中,K是聚类数量,p是样本, m k m_k mk是第k个聚类的中心点。SSE越小,说明样本聚合程度越高。
一般情况下是对样本聚类,如果对特征聚类则处理方式也简单,对原始的输入进行转置,其目的其实和做相关系数类似,如果两个特征高度相关,例如收入和资产水平,则两个特征的距离相对较小,但是一般不可行,因为转置之后,维度往往是非常高的,例如有100万个样本则有100万的维度,计算上不现实,高维数据的距离度量也是无效的,不如直接计算相关系数。
维度d趋于无穷大时,高维空间中任意两个样本点的最大距离和最小距离趋于相等,距离度量失效。
和评估分类或回归的方式一样,选择某个metric或某些metrics下最好的k,例如sse(其实就是kmeans的损失函数),轮廓系数,兰德系数,互信息;
如果聚类本身是为了有监督任务服务的,则可以直接根据下游任务的metrics进行评估更好;
k-means如何调优
dbscan和optics是基于密度的聚类
设置一个搜索半径,以及最小的满足点,搜索过的点标记为已搜索,避免其他簇抢走该点。如果搜索半径内点的个数小于最小点阈值,则该点为噪声点。
dbscan在不同超参数定义下得到的聚类结果差异很大,主要原因在于:不同簇的密度大小可能是不一样的,dbscan直接给定了半径eplison和min_points,实际上直接定义了最小密度,则密度较小的簇最终会被忽略掉了。
相对于dbscan多定义了核心距离和可达距离,核心距离就是核心点与第min_points个点的距离;可达距离就是样本点与核心点之间的距离。
如果该点的可达距离小于等于人工设定的半径R,则该点属于当前聚类簇;
如果该点的可达距离大于人工设定的半径R,则
我们关注向量数值绝对差异,应当使用欧式距离,如果关心的是向量方向上的相对差异,则应当使用余弦距离。
kmeans是基于划分的聚类算法,GMM是基于模型的聚类算法,EM是估计GMM的参数使用的优化算法;
GMM就是多个相关多元高斯分布的加权求和
首先需要了解EM算法,EM算法和梯度下降法一样,都可以用来优化极大似然函数,当极大似然函数中存在隐变量时,EM算法是一种常用的优化算法;
EM算法是一种迭代优化策略,由于它的计算方法中每一次迭代都分两步,其中一个为期望步(E步),另一个为极大步(M步),所以EM算法被称为EM算法。
无监督metrics:
S S E = ∑ i = 1 n ∑ j = 1 m w ( i , j ) = ∣ ∣ x ( i ) − μ ( j ) ∣ ∣ 2 2 SSE=\sum_{i=1}^n\sum_{j=1}^mw^(i,j)=||x^{(i)}-\mu^{(j)}||^2_2 SSE=i=1∑nj=1∑mw(i,j)=∣∣x(i)−μ(j)∣∣22
μ ( j ) \mu^{(j)} μ(j)表示j簇的中心。
轮廓系数:
轮廓系数是为每个样本定义的,由两个分数组成:
ROC曲线是纵坐标为准确率,横坐标为误检率
PR曲线是纵坐标为准确率,横坐标为召回率
ROC曲线对于正负样本比例不敏感,改变了标签中类别的分布之后,预测正确的正样本/预测正样本的样本数量 也会发生同向的变化,即roc的横坐标的计算结果是独立的,分别是针对正样本和针对负样本独立计算的,两个坐标的计算不会发生互相影响,因此类别比例发生变化的情况下,roc也不会产生剧烈的变动。
PR曲线的横纵坐标的计算结果是存在相互关系的,他们都是针对正样本进行计算,两个坐标的计算发生互相影响,从而使得PR曲线对类别的变化很敏感;
ROC聚焦于二分类模型整体对正负样本的预测能力,所以适用于评估模型整体的性能;如果主要关注正样本的预测能力而不care负样本的预测能力,则pr曲线更合适。
多分类问题中,在二分类指标的基础上需要进行一些处理才能适配多分类的评估,整体有两种计算策略:
基于macro的策略:ovr的划分方式,分别计算每个类别的metrics然后再进行平均
基于micro的策略:所有类放在一起算metrics;
micro的评估方式,当类别非常不均衡时,micro的计算结果会被样本数量多的类别主导,此时需要使用macro
ks曲线的横坐标是分类的阈值,纵坐标代表了精确率或者误杀率,一个分类阈值对应的一个精确率和一个误杀率,而ks曲线就是用每个分类阈值下的精确率-误杀率,ks值则是指ks曲线上的最大值;
通常针对类别不平衡问题可以从调整样本数或修改loss weight两方面取解决,常用的方法有OHEM,OHNM, class balanced loss和Focal loss;限制正负样本比例为1:1,如果正样本不足,就用负样本补充
对于二分类问题来说,理论上,两者是没有任何区别的。由于我们现在用的Pytorch、Tensorflow等框架计算矩阵方式的问题,导致两者在反向传播的过程中还是区别的。通常来说,二分类直接选用sigmoid。
Sigmoid函数:output(x1)= 1 1 + e − x 1 \frac{1}{1+e^{-x_1}} 1+e−x11
Softmax函数:output(x1)= e x 1 e x 1 + e x 2 = 1 1 + e − ( x 1 − x 2 ) \frac{e^{x_1}}{e^{x_1}+e^{x_2}}=\frac{1}{1+e^{-(x_1-x_2)}} ex1+ex2ex1=1+e−(x1−x2)1
f ( x ) = x ∗ s i g m o i d ( β x ) f(x)=x*sigmoid(\beta{x}) f(x)=x∗sigmoid(βx)
f ( x ) = x . t a n h ( θ ( x ) ) θ ( x ) = l n ( 1 + e x ) f(x)=x.tanh(\theta(x))\theta(x)=ln(1+e^x) f(x)=x.tanh(θ(x))θ(x)=ln(1+ex)
卷积神经网络的计算公式为: N = ( W − K + 2 P ) / S + 1 N=(W-K+2P)/S+1 N=(W−K+2P)/S+1
import numpy as np
def py_cpu_nms(dets, thresh):
x1 = dets[:,0]
y1 = dets[:,1]
x2 = dets[:,2]
y2 = dets[:,3]
scores = dets[:,4]
areas = (x2 - x1 +1)*(y2 - y1 + 1)
order = scores.argsort()[::-1] # 降序排列
keep = [] # 保留的边界框
while order.size > 0:
i = order[0] # 取置信度最大的框
keep.append(i) # 将其作为保留的框
# 以下计算置信度最大的框与其它所有的框的IOU,以下都是以向量形式表示和计算
xx1 = np.maximum(x1[i], x1[order[1:]]) #计算xmin的max,即overlap的xmin
yy1 = np.maximum(y1[i], y1[order[1:]]) # 计算ymin的max
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
inter = w * h
ovr = inter / (areas[i] + areas[order[1:]] - inter) # 计算IoU
inds = np.where(ovr <= thresh)[0]
order = order[inds + 1] #删除IoU大于阈值的框
return keep
import numpy as np
def soft_nms(dets, sigma=0.5, Nt=0.5, method=2, threshold=0.1):
box_len = len(dets)
for i in range(box_len):
tmpx1, tmpx2, tmpx2, tmpy2, ts = dets[i, 0], dets[i, 1], dets[i, 2], dets[i,3], dets[i, 4]
max_pos = i
max_socres = ts
# get max box
pos = i + 1
while pos < box_len:
if max_scores < dets[pos, 4]:
max_scores = dets[pos, 4]
max_pos = pos
pos += 1
# add max box as a detection
dets[i, :] = dets[max_pos, :]
# swap ith box with position of max box
dets[max_pos, 0] = tmpx1
dets[max_pos, 1] = tmpy1
dets[max_pos, 2] = tmpx2
dets[max_pos, 3] = tmpy2
dets[max_pos, 4] = ts
# 将置信度最高的box赋给临时变量
tmpx1, tmpy1, tmpx2, tmpy2, ts = dets[i, 0], dets[i, 1], dets[i, 2], dets[i, 3], dets[i, 4]
pos = i + 1
# NMS
while pos < box_len:
x1, y1, x2, y2 = dets[pos, 0], dets[pos, 1], dets[pos, 2], dets[pos, 3]
area = (x2 - x1 + 1)*(y2 - y1 + 1)
iw = (max(tmpx1, x1) - min(tmpx2, x2) + 1)
ih = (max(tmpy1, y1) - min(tmpy2, y2) + 1)
if iw > 0 and ih > 0:
overlaps = iw * ih
ious = overlaps / ((tmpx2 - tmpx1 + 1) * (tmpy2 - tmpy1 + 1) + area - overlaps)
if method == 1: # 线性
if ious > Nt:
weight = 1 - ious
else:
weight = 1
elif method == 2 # gaussian
weight = np.exp(-(ious**2)/sigma)
else:
if ious > Nt:
weight = 0
else:
weight = 1
# 赋予该box新的置信度
dets[pos, 4] =weight*dets[pos, 4]
# 如果box得分低于阈值thresh,则通过与最后一个框交换来丢弃该框
if dets[pos, 4] < threshold:
dets[pos, 0] = dets[box_len-1, 0]
dets[pos, 1] = dets[box_len-1, 1]
dets[pos, 2] = dets[box_len-1, 2]
dets[pos, 3] = dets[box_len-1, 3]
dets[pos, 4] = dets[box_len-1, 4]
box_len = box_len - 1
pos = pos - 1
pos += 1
keep = [i for i in range(box_len)]
return keep
先说一下匹配原则,对于某个ground truth, 首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值,计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置,然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth 匹配,对应的预测框用来预测这个ground truth.
yolo中一个ground truth 只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。
全部的4032个输出框直接和ground truth 计算IOU,取IOU最高的cell分配ground truth;这是因为现有有3个特征值输出,中心有重叠。
没用过,个人理解就是找个模型结构类似但是更具表达能力的上位模型,对原模型进行制导,具体做法就是用KL散度或者均方差让2个模型的输出分布一致
BN在具体实现的时候有4个关键参数,分别是running_mean, running_variance, gamma, beta。其中gamma, beta可以直接和其他网络权重一起同等的训练,因为也是反向传播更新的。
但是running_mean和running_variance是在前向传播的时候更新的。多卡训练的时候,每张卡就会在各自的卡内计算切分后的batchsize下的mean和variance再更新running_mean和running_variance.
这样,等于是batchsize变小了。然后为了解决这个问题就有了同步BN,再更新running_mean和running_variance的时候多张卡做一次同步,然后再做normalize。
多个有2种,一种的dataparallel,一种的distributeddataparallel。 DP的话是每张卡把梯度汇总给主卡,然后主卡做反向传播更新再把参数发给其他卡
DDP是大家把梯度汇总之后各自在各自的卡里面更新。
DDP比DP快的原因:
random crop, flip, mosaic, 旋转,对比度,亮度,mixup,对抗样本