* 目的:
Yolov4/v5 是個強大的物件偵測程式,值得深入研究其結構與效能,最好的方式就是修改其架構然後測試看其效果。 最容易修改的Backbone就是 VGG 系列(vgg11, vgg13, vgg16, vgg19),這邊嘗試著以此將 Yolov4 的 backbone 做修改。
* Backbone 替換
Yolov4:
* yaml 檔修改
原始的 Yolov4_L yaml 檔案的 backbone
修改後的 Yolov4_L_vgg11 yaml: number 表示幾個 CR blocks, args 則包含 channel output 和 stride。
修改後的 Yolov4_L_vgg13 yaml:
修改後的 Yolov4_L_vgg16 yaml:
修改後的 Yolov4_L_vgg19 yaml:
* 程式修改
yolo.py, parse_model() 增加:
vgg_n=n
elif m is vggLayer:
c1=ch[f if f<0 else f+1] # input channel
c2=args[0] # output channel, defined in args of yaml file
args=[c1,c2,vgg_n,*args[1:]] # modify args as [ch_in, ch_out, num_blocks, stride]
if m is vggLayer:
m_=m(*args) # create nn module
common.py 增加:
class vggLayer(nn.Module):
def __init__(self, c1, c2, n=1, s=2): #chin, chout, block_nums, stride
super(vggLayer,self).__init__()
blocks=[nn.Conv2d(c1, c2, kernel_size=3, stride=1, padding=1, bias=True),nn.ReLU(inplace=True)]
for _ in range(n-1):
blocks+=[nn.Conv2d(c2, c2, kernel_size=3, stride=1, padding=1, bias=True),nn.ReLU(inplace=True)]
blocks.append(nn.MaxPool2d(kernel_size=2, stride=s, padding=0, dilation=1))
self.layers = nn.Sequential(*blocks)
def forward(self, x):
return self.layers(x)
* parameter 變化量
原始的 Yolov4_S:
原始的 Yolov4_L:
修改後的 Yolov4_vgg11:
修改後的 Yolov4_vgg13:
修改後的 Yolov4_vgg16:
修改後的 Yolov4_vgg19:
* 測試結果
因為coco 圖片集太多,為實驗方便,此處依舊僅取其車輛部分 [‘motorcycle’,’car’,’bus’,’truck’], 測試結果如下: