手写二维卷积,池化,IoU,softmax

1.二维卷积,池化

#二维卷积,最大池化,平均池化的实现
def conv2(x,stride,kernal):
    """
    x二维数组输入
    kernal为卷积核,二维数组
    
    """

    x = np.array(x)
    kernal = np.array(kernal)   #如果输入的是二维列表,要用此两行代码变为数组

    h, w = x.shape
    k, _ = kernal.shape
    result = []
    for i in range(0,h - k + 1,stride):
        line = []
        for j in range(0,w - k + 1,stride):
            a = x[i:i + k, j:j + k]
            #line.append(np.sum(np.multiply(a,kernal)))    #此行实现的是二维卷积,注意求和要用np.sum(), 而不是sum()函数,np.sum()是对整个矩阵求和,sum()是对矩阵的每一列求和
            #line.append(np.max(a))                         #此行实现的是最大池化,注意用np.max()
            #line.append(np.sum(a) / (k * k))                #此行实现的是平均池化
        result.append(line)
    result = np.array(result)     #注意将结果变为数组输出
    return result

#验证
k = np.array([
    [0,1,2],
    [2,2,0],
    [0,1,2]
])

x = [[3,3,2,1,0],
     [0,0,1,3,1],
     [3,1,2,2,3],
     [2,0,0,2,2],
     [2,0,0,0,1]]
s = 1
result = conv2(x,s,k)
print(result)

2.三维卷积

#此三维卷积为三通道卷积,在二维卷积的基础上生成的


def conv_2d(x,kernel,stride,pad):
    c,h,w = x.shape
    _,k,_ = kernel.shape
    pad_x = np.zeros([c,h + 2 * pad,w + 2 * pad])
    pad_x[:,pad:pad + h,pad:pad + w] = x
    c,h,w = x.shape
    result = []
    for i in range(c):
        result.append(conv2(pad_x[i],kernel[i],stride))  #conv2为二维卷积,见上面
    a = np.sum(result,0)
    return a
    

3.IoU的计算

参考:https://github.com/amusi/Deep-Learning-Interview-Book/blob/master/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89.md

def get_IoU(pred_bbox, gt_bbox):
    """
    pred_bbox: 预测框[x0,y0,x1,y1] 为左上角坐标,右下角坐标
    gt_bbox: 同理
    """

    # 1、计算交集inter [i0,i1,i2,i3]
    xx1 = max(pred_bbox[0], gt_bbox[0])
    yy1 = max(pred_bbox[1], gt_bbox[1])
    xx2 = min(pred_bbox[2], gt_bbox[2])
    yy2 = min(pred_bbox[3], gt_bbox[3])
    inter = max(xx2 - xx1 + 1.0, 0) * max(yy2 - yy1 + 1.0, 0)

    # 2、计算pred,gt面积,即s1,s2 ,注意边长+1.0
    s1 = (pred_bbox[2] - pred_bbox[0] + 1.) * (pred_bbox[3] - pred_bbox[1] + 1.)
    s2 = (gt_bbox[2] - gt_bbox[0] + 1.) * (gt_bbox[2] - gt_bbox[0] + 1.)

    # 3、 计算并集union
    union = s1 + s2 - inter

    # 4、计算iou
    iou = inter / union

    return iou

4.nms的计算

参考:手写NMS算法_xiaoleige0713的博客-CSDN博客


def nms(bbox,thread):
    x1 = bbox[:,0]
    y1 = bbox[:,1]
    x2 = bbox[:,2]
    y2 = bbox[:,3]
    scores = bbox[:,4]
    index = np.argsort(-scores)
    keep = []
    while len(index) > 0:
        first = index[0]
        keep.append(first)
        index = np.delete(index, 0)
        delete = []
        for i in range(len(index)):
            xx1 = max(x1[first], x1[index[i]])
            yy1 = max(y1[first], y1[index[i]])
            xx2 = min(x2[first], x2[index[i]])
            yy2 = min(y2[first], y2[index[i]])
            inter = max(xx2 - xx1 + 1., 0) * max(yy2 - yy1 + 1., 0)
            union = (y2[first] - y1[first] + 1.) * (x2[first] - x1[first] + 1.) + (y2[index[i]] - y1[index[i]] + 1.) * (x2[index[i]] - x1[index[i]] + 1.) - inter
            iou = inter / union
            if iou >= thread:
                delete.append(i)
        index = np.delete(index,delete)
    return keep


boxes = np.array([[100,100,210,210,0.72],
        [250,250,420,420,0.8],
        [220,220,320,330,0.92],
        [100,100,210,210,0.73],
        [230,240,325,330,0.81],
        [220,230,315,340,0.9]],dtype = float)

result = nms(boxes,0.7)
print(result)

5.softmax

import numpy as np
def softmax(x):
    exp = np.exp(x)
    sum_ = np.sum(exp, axis=0) #注意别忘了axis=0
    return exp / sum_

6.二分法开平方根,保留三位小数

def sqrt(x):
    precision = 0.001
    if x < 0:
        raise ValueError('x is -')    #手动触发异常,后面的语句不会被执行
    elif x == 0:
        return 0
    elif x > 0:
        left = 0
        right = max(1.0, x)   #x可能为小于0,小于0的数开方大于本身
        while left <= right:
            middle = (right + left) / 2.0
            if abs(middle ** 2 - x) <= precision:
                return round(middle,3)  
                 #用此写法保留三位小数时,如果小数位数小于三位,则不会保留三位,可使用下面方法
                return '{:.3f}'.format(middle)
            elif middle ** 2 > x:
                right = middle
            elif middle ** 2 < x:
                left = middle

a = sqrt(0.8)
print(a)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值