共计 5950 个字符,预计需要花费 15 分钟才能阅读完成。
卷积
import numpy as np
input_data=[[[1,0,1,2,1],
[0,2,1,0,1],
[1,1,0,2,0],
[2,2,1,1,0],
[2,0,1,2,0]],
[[2,0,2,1,1],
[0,1,0,0,2],
[1,0,0,2,1],
[1,1,2,1,0],
[1,0,1,1,1]]
]
weights_data=[[[ 1, 0, 1],
[-1, 1, 0],
[0,-1, 0]],
[[-1, 0, 1],
[0, 0, 1],
[1, 1, 1]]
]
#fm:[h,w]
#kernel:[k,k]
#return rs:[h,w]
def compute_conv(fm,kernel):
[h,w]=fm.shape
[k,_]=kernel.shape
r=int(k/2)
#定义边界填充 0 后的 map
padding_fm=np.zeros([h+2,w+2],np.float32)
#保留计算结果
rs=np.zeros([h,w],np.float32)
#将输出在指定该区域赋值,即除了 4 个边界后,剩下的区域
padding_fm[1:h+1,1:w+1]=fm
#对每个点为核心的区域遍历
for i in range(1,h+1):
for j in range(1,w+1):
#取出以后点为核心的 k * k 区域
roi=padding_fm[i-r:i+r+1,j-r:j+r+1]
#计算以后点的卷积, 对 k * k 个点点乘后求和
rs[i-1][j-1]=np.sum(roi*kernel)
return rs
def my_conv2d(input,weights):
[c,h,w]=input.shape
[_,k,_]=weights.shape
outputs=np.zeros([h,w],np.float32)
#对每个 feature map 遍历,从而对每个 feature map 进行卷积
for i in range(c):
#feature map==>[h,w]
f_map=input[i]
#kernel ==>[k,k]
w=weights[i]
rs =compute_conv(f_map,w)
outputs=outputs+rs
return outputs
def main():
#shape=[c,h,w]
input = np.asarray(input_data,np.float32)
#shape=[in_c,k,k]
weights = np.asarray(weights_data,np.float32)
rs=my_conv2d(input,weights)
print(rs)
if __name__=='__main__':
main()
反卷积 (反卷积 = 卷积 + 填充 + 裁剪)
input_data=[[[1,0,1],
[0,2,1],
[1,1,0]],
[[2,0,2],
[0,1,0],
[1,0,0]],
[[1,1,1],
[2,2,0],
[1,1,1]],
[[1,1,2],
[1,0,1],
[0,2,2]]
]
weights_data=[[[[ 1, 0, 1],
[-1, 1, 0],
[0,-1, 0]],
[[-1, 0, 1],
[0, 0, 1],
[1, 1, 1]],
[[0, 1, 1],
[2, 0, 1],
[1, 2, 1]],
[[1, 1, 1],
[0, 2, 1],
[1, 0, 1]]],
[[[1, 0, 2],
[-2, 1, 1],
[1,-1, 0]],
[[-1, 0, 1],
[-1, 2, 1],
[1, 1, 1]],
[[0, 0, 0],
[2, 2, 1],
[1,-1, 1]],
[[2, 1, 1],
[0,-1, 1],
[1, 1, 1]]]
]
#依据输出 map([h,w]) 和卷积核 ([k,k]), 计算卷积后的 feature map
import numpy as np
def compute_conv(fm,kernel):
[h,w]=fm.shape
[k,_]=kernel.shape
r=int(k/2)
#定义边界填充 0 后的 map
padding_fm=np.zeros([h+2,w+2],np.float32)
#保留计算结果
rs=np.zeros([h,w],np.float32)
#将输出在指定该区域赋值,即除了 4 个边界后,剩下的区域
padding_fm[1:h+1,1:w+1]=fm
#对每个点为核心的区域遍历
for i in range(1,h+1):
for j in range(1,w+1):
#取出以后点为核心的 k * k 区域
roi=padding_fm[i-r:i+r+1,j-r:j+r+1]
#计算以后点的卷积, 对 k * k 个点点乘后求和
rs[i-1][j-1]=np.sum(roi*kernel)
return rs
#填充 0
def fill_zeros(input):
[c,h,w]=input.shape
rs=np.zeros([c,h*2+1,w*2+1],np.float32)
for i in range(c):
for j in range(h):
for k in range(w):
rs[i,2*j+1,2*k+1]=input[i,j,k]
return rs
def my_deconv(input,weights):
#weights shape=[out_c,in_c,h,w]
[out_c,in_c,h,w]=weights.shape
out_h=h*2
out_w=w*2
rs=[]
for i in range(out_c):
w=weights[i]
tmp=np.zeros([out_h,out_w],np.float32)
for j in range(in_c):
conv=compute_conv(input[j],w[j])
#留神裁剪,最初一行和最初一列去掉
tmp=tmp+conv[0:out_h,0:out_w]
rs.append(tmp)
return rs
def main():
input=np.asarray(input_data,np.float32)
input= fill_zeros(input)
weights=np.asarray(weights_data,np.float32)
deconv=my_deconv(input,weights)
print(np.asarray(deconv))
if __name__=='__main__':
main()
Dropout
import numpy as np
def dropout(x, p, mode='train'):
keep_prob = 1 - p
if mode == 'train':
x *= np.random.binomial(1, keep_prob, size=x.shape)
else:
x *= keep_prob
return x
---------------------
test = np.random.binomial(5, 0.5, 10) #伯努利二项式散布
print(test)
输入:[1 5 5 2 4 2 3 3 2 3]
(一次抛 5 枚硬币,每枚硬币侧面朝上概率为 0.5,做 10 次试验,求每次试验产生侧面朝上的硬币个数:)
IOU
def IOU(x1,y1,X1,Y1,x2,y2,X2,Y2):
xx=max(x1,x2)
XX=min(X1,X2)
yy=max(y1,y2)
YY=min(Y1,Y2)
m=max(0,XX-xx)
n=max(0,YY-yy)
jiao=m*n
bing=(X1-x1+1)*(Y1-y1+1)+(X2-x2+1)*(Y2-y2+1)-jiao #+ 1 避免为 0
return jiao/bing
NMS
def py_cpu_nms(dets, thresh):
#首先数据赋值和计算对应矩形框的面积
#dets 的数据格式是 dets[[xmin,ymin,xmax,ymax,scores]....]
x1 = dets[:,0]
y1 = dets[:,1]
x2 = dets[:,2]
y2 = dets[:,3]
areas = (y2-y1+1) * (x2-x1+1)
scores = dets[:,4]
print('areas',areas)
print('scores',scores)
#这边的 keep 用于寄存,NMS 后残余的方框
keep = []
#取出分数从大到小排列的索引。.argsort() 是从小到大排列,[::-1] 是列表头和尾颠倒一下。index = scores.argsort()[::-1]
print(index)
#下面这两句比方分数 [0.72 0.8 0.92 0.72 0.81 0.9]
# 对应的索引 index[2 5 4 1 3 0] 记住是取出索引,scores 列表没变。#index 会剔除遍历过的方框,和合并过的方框。while index.size >0:
print(index.size)
#取出第一个方框进行和其余方框比对,看有没有能够合并的
i = index[0] # every time the first is the biggst, and add it directly
#因为咱们这边分数曾经按从大到小排列了。#所以如果有合并存在,也是保留分数最高的这个,也就是咱们当初那个这个
#keep 保留的是索引值,不是具体的分数。keep.append(i)
print(keep)
print('x1',x1[i])
print(x1[index[1:]])
#计算交加的左上角和右下角
#这里要留神,比方 x1[i] 这个方框的左上角 x 和所有其余的方框的左上角 x 的
x11 = np.maximum(x1[i], x1[index[1:]]) # calculate the points of overlap
y11 = np.maximum(y1[i], y1[index[1:]])
x22 = np.minimum(x2[i], x2[index[1:]])
y22 = np.minimum(y2[i], y2[index[1:]])
print(x11,y11,x22,y22)
#这边要留神,如果两个方框相交,X22-X11 和 Y22-Y11 是正的。#如果两个方框不相交,X22-X11 和 Y22-Y11 是负的,咱们把不相交的 W 和 H 设为 0.
w = np.maximum(0, x22-x11+1)
h = np.maximum(0, y22-y11+1)
#计算重叠面积就是下面说的交加面积。不相交因为 W 和 H 都是 0,所以不相交面积为 0
overlaps = w*h
print('overlaps is',overlaps)
#这个就是 IOU 公式(交并比)。#得进去的 ious 是一个列表,外面领有以后方框和其余所有方框的 IOU 后果。ious = overlaps / (areas[i]+areas[index[1:]] - overlaps)
print('ious is',ious)
#接下来是合并重叠度最大的方框,也就是合并 ious 中值大于 thresh 的方框
#咱们合并的操作就是把他们剔除,因为咱们合并这些方框只保留下分数最高的。#咱们通过排序以后咱们操作的方框就是分数最高的,所以咱们剔除其余和以后重叠度最高的方框
#这里 np.where(ious<=thresh)[0] 是一个固定写法。idx = np.where(ious<=thresh)[0]
print(idx)
#把留下来框在进行 NMS 操作
#这边留下的框是去除以后操作的框,和以后操作的框重叠度大于 thresh 的框
#每一次都会先去除以后操作框,所以索引的列表就会向前挪动移位,要还原就 +1,向后挪动一位
index = index[idx+1] # because index start from 1
print(index)
return keep
BatchNormalization
def Batchnorm_simple_for_train(x, gamma, beta, bn_param):
"""
param:x : 输出数据,设 shape(B,L)
param:gama : 缩放因子 γ
param:beta : 平移因子 β
param:bn_param : batchnorm 所须要的一些参数
eps : 靠近 0 的数,避免分母呈现 0
momentum : 动量参数,个别为 0.9,0.99,0.999
running_mean:滑动均匀的形式计算新的均值,训练时计算,为测试数据做筹备
running_var : 滑动均匀的形式计算新的方差,训练时计算,为测试数据做筹备
"""running_mean = bn_param['running_mean'] #shape = [B]
running_var = bn_param['running_var'] #shape = [B]
momentun = bn_param['momentun'] #shape = [B]
results = 0. # 建设一个新的变量
x_mean=x.mean(axis=0) # 计算 x 的均值
x_var=x.var(axis=0) # 计算方差
running_mean = momentum * running_mean + (1 - momentum) * x_mean
running_var = momentum * running_var + (1 - momentum) * x_var
x_normalized=(x - running_mean)/np.sqrt(running_var + eps) # 归一化
results = gamma * x_normalized + beta # 缩放平移
#记录新的值
bn_param['running_mean'] = running_mean
bn_param['running_var'] = running_var
return results , bn_param
def Batchnorm_simple_for_test(x, gamma, beta, bn_param):
"""
param:x : 输出数据,设 shape(B,L)
param:gama : 缩放因子 γ
param:beta : 平移因子 β
param:bn_param : batchnorm 所须要的一些参数
eps : 靠近 0 的数,避免分母呈现 0
momentum : 动量参数,个别为 0.9,0.99,0.999
running_mean:滑动均匀的形式计算新的均值,训练时计算,为测试数据做筹备
running_var : 滑动均匀的形式计算新的方差,训练时计算,为测试数据做筹备
"""running_mean = bn_param['running_mean'] #shape = [B]
running_var = bn_param['running_var'] #shape = [B]
results = 0. # 建设一个新的变量
x_normalized=(x-running_mean)/np.sqrt(running_var +eps) # 归一化
results = gamma * x_normalized + beta # 缩放平移
return results , bn_param
正文完