• Multi-Adapter RGBT Tracking代码学习(二)


    1.tracking/bbreg.py:
    ①解答1:
    回归的目的是预测数值型的目标值。最直接的办法是依据输入写出一个目标值的计算公式。
    假如你想要预测兰博基尼跑车的功率大小,可能会这样计算:

    HorsePower = 0.0015 * annualSalary - 0.99 *hoursListeningToPublicRadio

    这就是所谓的 回归方程(regression equation),其中的 0.0015 和 -0.99 称作 回归系数(regression weights),求这些回归系数的过程就是回归。一旦有了这些回归系数,再给定输入,做预测就非常容易了。具体的做法是用回归系数乘以输入值,再将结果全部加在一起,就得到了预测值。我们这里所说的,回归系数是一个向量,输入也是向量,这些运算也就是求出二者的内积。
    说到回归,一般都是指 线性回归(linear regression)。线性回归意味着可以将输入项分别乘以一些常量,再将结果加起来得到输出。

    总的来说,回归问题的学习等价于函数拟合,选择一条函数曲线使其很好地拟合已知数据且很好地预测未知数据。

    参考博客:机器学习实战- 回归(Regression) 概述
    回归(regression)的理解(regressor,回归子)

    ②解答二:

    作者详细的解释了边界框回归的相关问题
    1.为什么要边框回归?
    2.什么是边框回归?
    3.边框回归怎么做的?
    4.边框回归为什么宽高,坐标会设计这种形式?
    5.为什么边框回归只能微调,在离Ground Truth近的时候才能生效?
    参考博客:边框回归(Bounding Box Regression)详解

    class BBRegressor():
        def __init__(self, img_size, alpha=1000, overlap=[0.6, 1], scale=[1, 2]):
            self.img_size = img_size
            self.alpha = alpha
            self.overlap_range = overlap
            self.scale_range = scale
            self.model = Ridge(alpha=self.alpha)#Ridge岭回归,alpha正则化力度???不是应该多为1嘛
        #X为提取到的特征,bbox为提取到的样本区域,所存为正样本的边界框,gt为该图片的真值(x,y,w,h)
        def train(self, X, bbox, gt):
            X = X.cpu().numpy()#Xw本来为一个张量,.numpy()是将张量变成数组numpy
            bbox = np.copy(bbox)#copy是复制一份,而不是简单的引用。
            gt = np.copy(gt)
    
            if gt.ndim==1:#gt的维度。一维数组就返回1
                gt = gt[None,:]#将gt扩展成二维的。
    
            r = overlap_ratio(bbox, gt)#计算重叠率
            # print("bbox_为:")
            # print(bbox)
            # print("gt 为:")
            # print(gt)
            # print(r)
            s = np.prod(bbox[:,2:], axis=1) / np.prod(gt[0,2:])#np.prod(x)x内元素相乘,axis是指定维度。axis是指一行中的两个元素相乘,正好是w*h,为面积。除以真值的面积。
            #
            idx = (r >= self.overlap_range[0]) * (r <= self.overlap_range[1]) * \
                  (s >= self.scale_range[0]) * (s <= self.scale_range[1])#这里不是很明白为什么s要大于等于1,小于等于2.This is a question!
            #idx获得一个布尔型的数组。
    
            X = X[idx]#筛选出idx为True,即满足条件的特征以及边界框。
            #因为只有比较靠近真值的边界框才能满足线性回归,所以这里要选出iou大于0.6小于1的候选框。
            bbox = bbox[idx]
    
            Y = self.get_examples(bbox, gt)#得到的y值为,实际应该移动的变化值,即正确的调整方案。这个函数,输入X为正样本特征,Y为正确的调整方案,然后让其自己学习,博客上说用的是岭回归。(在初始化中,定义了岭回归模型)
            self.model.fit(X, Y)
    
        def predict(self, X, bbox):
            X = X.cpu().numpy()
            bbox_ = np.copy(bbox)
    
            Y = self.model.predict(X)
    
            bbox_[:,:2] = bbox_[:,:2] + bbox_[:,2:]/2
            bbox_[:,:2] = Y[:,:2] * bbox_[:,2:] + bbox_[:,:2]
            bbox_[:,2:] = np.exp(Y[:,2:]) * bbox_[:,2:]
            bbox_[:,:2] = bbox_[:,:2] - bbox_[:,2:]/2
    
            bbox_[:,:2] = np.maximum(bbox_[:,:2], 0)
            bbox_[:,2:] = np.minimum(bbox_[:,2:], self.img_size - bbox[:,:2])
            return bbox_
    
        def get_examples(self, bbox, gt):
            bbox[:,:2] = bbox[:,:2] + bbox[:,2:]/2#求得中心左边(x,y)
            gt[:,:2] = gt[:,:2] + gt[:,2:]/2#求得真值边界框的的中心坐标
    
            dst_xy = (gt[:,:2] - bbox[:,:2]) / bbox[:,2:]#根据公式,求出目标移动的值x,y,w,h
            dst_wh = np.log(gt[:,2:] / bbox[:,2:])
    
            Y = np.concatenate((dst_xy, dst_wh), axis=1)
            return Y
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    参考博客:边框回归(Bounding Box Regression)详解

    ③shuffle的作用:
    在这里插入图片描述
    参考博客:深度学习:shuffle 的作用

    2.tracking/bbreg.py中alpha的含义:
    首先看一个简单的梯度下降的例子:

    weight = 0.5
    goal_pred = 0.8
    input = 0.5
    
    for iteration in range(20):
        pred = input * weight
        error = (pred - goal_pred) ** 2
        delta = pred - goal_pred
        weight_delta = delta * input
        weight = weight - weight_delta
        
        print("Error:" + str(error) + "  prediction:" + str(pred))
    
    # 输出如下:
    Error:0.30250000000000005  prediction:0.25
    Error:0.17015625000000004  prediction:0.3875
    Error:0.095712890625  prediction:0.49062500000000003
    Error:0.05383850097656251  prediction:0.56796875
    Error:0.03028415679931642  prediction:0.6259765625
    Error:0.0170348381996155  prediction:0.669482421875
    Error:0.00958209648728372  prediction:0.70211181640625
    Error:0.005389929274097089  prediction:0.7265838623046875
    Error:0.0030318352166796153  prediction:0.7449378967285156
    Error:0.0017054073093822882  prediction:0.7587034225463867
    Error:0.0009592916115275371  prediction:0.76902756690979
    Error:0.0005396015314842384  prediction:0.7767706751823426
    Error:0.000303525861459885  prediction:0.7825780063867569
    Error:0.00017073329707118678  prediction:0.7869335047900676
    Error:9.603747960254256e-05  prediction:0.7902001285925507
    Error:5.402108227642978e-05  prediction:0.7926500964444131
    Error:3.038685878049206e-05  prediction:0.7944875723333098
    Error:1.7092608064027242e-05  prediction:0.7958656792499823
    Error:9.614592036015323e-06  prediction:0.7968992594374867
    Error:5.408208020258491e-06  prediction:0.7976744445781151
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    上述代码使用简单的线性公式和均方差损失函数进行演示,在上述代码中我们没有使用学习率alpha,根据输出可以看到,在合适输入和权重前提下,所使用的模型的损失函数能够不断下降。

    我们现在改变输入,破坏梯度下降;我们把input从1.1改为2,看看上述代码会输出什么结果:

    weight = 0.5
    goal_pred = 0.8
    input = 2
    
    for iteration in range(20):
        pred = input * weight
        error = (pred - goal_pred) ** 2
        delta = pred - goal_pred
        weight_delta = delta * input
        weight = weight - weight_delta
        
        print("Error:" + str(error) + "  prediction:" + str(pred))
    
    
    # 代码输出如下
    Error:0.03999999999999998  prediction:1.0
    Error:0.3599999999999998  prediction:0.20000000000000018
    Error:3.2399999999999984  prediction:2.5999999999999996
    Error:29.159999999999986  prediction:-4.599999999999999
    Error:262.4399999999999  prediction:16.999999999999996
    Error:2361.959999999998  prediction:-47.79999999999998
    Error:21257.639999999978  prediction:146.59999999999994
    Error:191318.75999999983  prediction:-436.5999999999998
    Error:1721868.839999999  prediction:1312.9999999999995
    Error:15496819.559999991  prediction:-3935.799999999999
    Error:139471376.03999993  prediction:11810.599999999997
    Error:1255242384.3599997  prediction:-35428.59999999999
    Error:11297181459.239996  prediction:106288.99999999999
    Error:101674633133.15994  prediction:-318863.79999999993
    Error:915071698198.4395  prediction:956594.5999999997
    Error:8235645283785.954  prediction:-2869780.599999999
    Error:74120807554073.56  prediction:8609344.999999996
    Error:667087267986662.1  prediction:-25828031.799999986
    Error:6003785411879960.0  prediction:77484098.59999996
    Error:5.403406870691965e+16  prediction:-232452292.5999999
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    通过观察上面的输出,我们发现预测的结果爆炸了!它们从负数变为正数,又从正数变为负数,来回往复,但每一步都离真正的答案越来越远。换句话说,对权重的每次更新都会造成过度修正。
    如果输入足够大,即使误差很消息,也会使权重的增量很大。当权重增量很大而误差的量很小时,网络会桥枉过正。如果新的误差更大,网络就会尝试更多地纠正错误。这就导致我们上面看到的现象,称为发散。(有时候,神经网络的输出会爆炸,具体原因也类似)

    对于上面的发散现象,我们的解决办法是将权值的增量乘以一个系数,让它变得更小。大多数情况下,这个方法表现为将权值增量乘于一个介于0和1之间的实数,称为α ( a l p h a ) \alpha (alpha)α(alpha)。请注意,这种方法不会对核心问题产生任何影响——也就是说输入还是那个较大的值。同时也会减少那些不太大的输入所对应的权重增量。

    即使最先进的神经网络,合适的alpha值也常常是靠猜测来找到的。随着时间的推移,我们会看到误差的变换,如果它逐渐开始发散(上升),那么alpha值就太高了,我们需要将其调低一些。如果学习进展太慢,那么alpha值太低,我们需要将它调高一点。

    参考博客:机器学习中的alpha学习率参数

    代码框架总结:(不一定对,不对的请大家指出来,我们可以共同学习一下)

    1. modules/MANet3x1x1_IC.py:主要用来设置网络框架。
    2. modules/sample_generator.py:主要用来生成样本框。
    3. modules/utils.py:①overlap_ratio主要用来计算IOU;②crop_image主要用来剪裁图片。
    4. pretrain/data_prov.py:对数据进行预处理。
    5. pretrain/options.py:设置数据处理的参数。
    6. pretrain/prepro_data.py:生成预处理文件之前的路径参数配置,且运行生成pkl文件。
    7. pretrain/train.py:调整pkl文件路径,然后运行生成pth文件。
    8. tracking/bbreg.py:边界框的设置,边界框回归
    9. tracking/data_prov.py:提取目标框的算法

    未完晚点继续更新…

  • 相关阅读:
    产品思维训练 | 你的项目总是不能按期上线,你会如何解决?
    TCP套接字编程
    多线程进阶
    JAVA毕业设计科普网站计算机源码+lw文档+系统+调试部署+数据库
    怎么用蜂邮EDM和Outlook批量发送邮件带附件
    分布式训练框架
    MQ消息队列产品对比
    改进YOLOv7系列:25.YOLOv7 加入RepVGG模型结构,重参数化 极简架构
    提升测试效果:深入解析《Effective软件测试》的关键方法与实践
    openssl C++研发之pem格式处理详解
  • 原文地址:https://blog.csdn.net/qq_45104603/article/details/126103993