百度飞桨顶会论文复现(5):视频分类论文之《Representation Flow for Action Recognition》篇
這次老師在課上總共領(lǐng)讀了4篇分類(lèi)論文,我這里分享其中的一篇論文,是關(guān)于使用神經(jīng)網(wǎng)絡(luò)對(duì)光流進(jìn)行學(xué)習(xí)。
課程地址是:https://aistudio.baidu.com/aistudio/education/group/info/1340。
論文地址是:https://arxiv.org/abs/1810.01455。
Github地址是:https://github.com/piergiaj/representation-flow-cvpr19。
論文中文翻譯地址:https://blog.csdn.net/qq_42037746/article/details/107411080。
文章目錄
- 1.相關(guān)介紹
- 2.本文方法
- 2.1 光流法介紹
- 2.2 光流層細(xì)節(jié)
- 3.結(jié)果展示
1.相關(guān)介紹
這里我將按照老師上課領(lǐng)讀的順序來(lái)進(jìn)行介紹。
過(guò)去在對(duì)視頻進(jìn)行分類(lèi)時(shí),一般需要設(shè)計(jì)兩個(gè)網(wǎng)絡(luò),一個(gè)網(wǎng)路輸入靜態(tài)圖像得到圖像特征;另一個(gè)網(wǎng)絡(luò)輸入兩張圖像之間的光流,學(xué)習(xí)運(yùn)動(dòng)特征;然后對(duì)兩個(gè)特征進(jìn)行融合,進(jìn)行最終的視頻分類(lèi)。這里最主要的問(wèn)題是光流的計(jì)算成本比較高,通常需要上百次的迭代優(yōu)化;另一個(gè)是需要訓(xùn)練兩個(gè)網(wǎng)絡(luò),這使得模型在推理時(shí)資源消耗較大,限制了其應(yīng)用。因此本文作者設(shè)計(jì)了一種CNN層:表示光流層,對(duì)光流進(jìn)行學(xué)習(xí),并且表示光流層可以對(duì)任意一層特征圖進(jìn)行學(xué)習(xí)。
2.本文方法
2.1 光流法介紹
在介紹本文方法之前首先回顧下什么是光流?光流是用來(lái)描述像素隨時(shí)間在圖像之間運(yùn)動(dòng)的方法。
在光流法中一個(gè)基本假設(shè)是:同一個(gè)空間點(diǎn)的像素灰度值,在各個(gè)圖像中是固定不變的,可以用I(x,y,t)I(x,y,t)I(x,y,t)來(lái)表示像素灰度。
下圖中,ttt時(shí)刻圖像中像素位置為(x,y)(x,y)(x,y),在t+dtt+dtt+dt時(shí)刻運(yùn)動(dòng)到(x+dx,y+dy)(x+dx,y+dy)(x+dx,y+dy),由于灰度不變可得:
I(x,y,t)=I(x+dx,y+dy,t+dt)I(x,y,t)=I(x+dx,y+dy,t+dt)I(x,y,t)=I(x+dx,y+dy,t+dt)
泰勒一階展開(kāi),像素運(yùn)動(dòng)(u1,u2)(u_1,u_2)(u1?,u2?)即為光流矢量。
2.2 光流層細(xì)節(jié)
論文的整體網(wǎng)絡(luò)結(jié)構(gòu)如下,可以看到輸入只有圖片,與以往的分類(lèi)網(wǎng)絡(luò)不同的是多了一個(gè)Flow Layer,這也是整個(gè)網(wǎng)絡(luò)的核心部分。
下圖為光流層迭代計(jì)算過(guò)程,這里F1,F2F_1,F_2F1?,F2?為兩張圖片的特征圖。
初始時(shí)u=0,p=0,pc=F2?F1u=0,p=0,p_c=F_2-F_1u=0,p=0,pc?=F2??F1?;然后進(jìn)行nnn次迭代計(jì)算;
計(jì)算特征圖F2F_2F2?的梯度,這里的梯度是通過(guò)卷積操作計(jì)算的,下面的矩陣表示為卷積核 。?F2x=[10?120?210?1]?F2,?F2y=[121000?1?2?1]?F2\nabla{F_{2x}}=\begin{bmatrix}1&0&-1\\2&0&-2\\1&0&-1\end{bmatrix}*F_2,\nabla{F_{2y}}=\begin{bmatrix}1&2&1\\0&0&0\\-1&-2&-1\end{bmatrix}*F_2?F2x?=???121?000??1?2?1?????F2?,?F2y?=???10?1?20?2?10?1?????F2?
然后是更新vvv的值;
計(jì)算ppp的散度:divergence(p)=px?wx+py?wydivergence(p)=p_x*w_x+p_y*w_ydivergence(p)=px??wx?+py??wy?
然后是計(jì)算速度梯度,操作和求F2F_2F2?梯度類(lèi)似: ?ux=[10?120?210?1]?ux,?uy=[121000?1?2?1]?uy\nabla{u_{x}}=\begin{bmatrix}1&0&-1\\2&0&-2\\1&0&-1\end{bmatrix}*u_x,\nabla{u_{y}}=\begin{bmatrix}1&2&1\\0&0&0\\-1&-2&-1\end{bmatrix}*u_y?ux?=???121?000??1?2?1?????ux?,?uy?=???10?1?20?2?10?1?????uy?
跟新p的值;
最終,經(jīng)過(guò)nnn次迭代即可得到最終的像素運(yùn)動(dòng)速度uuu。
下面是原作者光流層實(shí)現(xiàn)代碼,首先網(wǎng)絡(luò)的定義:
前向傳播:
def forward(self, x):residual = x[:,:,:-1]x = self.bottleneck(x)inp = self.norm_img(x)x = inp[:,:,:-1]y = inp[:,:,1:]b,c,t,h,w = x.size()x = x.permute(0,2,1,3,4).contiguous().view(b*t,c,h,w)y = y.permute(0,2,1,3,4).contiguous().view(b*t,c,h,w)u1 = torch.zeros_like(x)u2 = torch.zeros_like(x)l_t = self.l * self.ttaut = self.a/self.tgrad2_x = F.conv2d(F.pad(y,(1,1,0,0)), self.img_grad, padding=0, stride=1)#, groups=self.channels)grad2_x[:,:,:,0] = 0.5 * (x[:,:,:,1] - x[:,:,:,0])grad2_x[:,:,:,-1] = 0.5 * (x[:,:,:,-1] - x[:,:,:,-2])grad2_y = F.conv2d(F.pad(y, (0,0,1,1)), self.img_grad2, padding=0, stride=1)#, groups=self.channels)grad2_y[:,:,0,:] = 0.5 * (x[:,:,1,:] - x[:,:,0,:])grad2_y[:,:,-1,:] = 0.5 * (x[:,:,-1,:] - x[:,:,-2,:])p11 = torch.zeros_like(x.data)p12 = torch.zeros_like(x.data)p21 = torch.zeros_like(x.data)p22 = torch.zeros_like(x.data)gsqx = grad2_x**2gsqy = grad2_y**2grad = gsqx + gsqy + 1e-12rho_c = y - grad2_x * u1 - grad2_y * u2 - xfor i in range(self.n_iter):rho = rho_c + grad2_x * u1 + grad2_y * u2 + 1e-12v1 = torch.zeros_like(x.data)v2 = torch.zeros_like(x.data)mask1 = (rho < -l_t*grad).detach()v1[mask1] = (l_t * grad2_x)[mask1]v2[mask1] = (l_t * grad2_y)[mask1]mask2 = (rho > l_t*grad).detach()v1[mask2] = (-l_t * grad2_x)[mask2]v2[mask2] = (-l_t * grad2_y)[mask2]mask3 = ((mask1^1) & (mask2^1) & (grad > 1e-12)).detach()v1[mask3] = ((-rho/grad) * grad2_x)[mask3]v2[mask3] = ((-rho/grad) * grad2_y)[mask3]del rhodel mask1del mask2del mask3v1 += u1v2 += u2u1 = v1 + self.t * self.divergence(p11, p12)u2 = v2 + self.t * self.divergence(p21, p22)del v1del v2u1 = u1u2 = u2u1x, u1y = self.forward_grad(u1)u2x, u2y = self.forward_grad(u2)p11 = (p11 + taut * u1x) / (1. + taut * torch.sqrt(u1x**2 + u1y**2 + 1e-12))p12 = (p12 + taut * u1y) / (1. + taut * torch.sqrt(u1x**2 + u1y**2 + 1e-12))p21 = (p21 + taut * u2x) / (1. + taut * torch.sqrt(u2x**2 + u2y**2 + 1e-12))p22 = (p22 + taut * u2y) / (1. + taut * torch.sqrt(u2x**2 + u2y**2 + 1e-12))del u1xdel u1ydel u2xdel u2yflow = torch.cat([u1,u2], dim=1)flow = flow.view(b,t,c*2,h,w).contiguous().permute(0,2,1,3,4)flow = self.unbottleneck(flow)flow = self.bn(flow)return F.relu(residual+flow)3.結(jié)果展示
首先作者分析了對(duì)不同特征層使用光流層的分類(lèi)結(jié)果:可以看出在第三個(gè)殘差塊后面使用光流層效果最好。
然后作者討論了不同結(jié)構(gòu)光流層的分類(lèi)結(jié)果,可看到Flow-Conv-Flow的分類(lèi)效果是最好的。
最后作者與現(xiàn)有的SOTA模型進(jìn)行了對(duì)比,可以看到,FCF+(2+1)D的效果是最好的。
這里簡(jiǎn)單對(duì)《Representation Flow for Action Recognition》論文進(jìn)行了介紹,更多理解還需要反復(fù)閱讀論文和閱讀源碼。
總結(jié)
以上是生活随笔為你收集整理的百度飞桨顶会论文复现(5):视频分类论文之《Representation Flow for Action Recognition》篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: launcher.exe是什么进程 la
- 下一篇: sdut 2074 区间覆盖问题(贪心)