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的计算
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)