flownet2网络迁移笔记pytorch to mindspore(1)

flownet2网络是什么

flownet2网络是一个对光流进行深度学习的网络,flownet2实际上是在flownet的基础上对网络的结构和训练方法进行了优化。
flownet提出两种新的网络结构分别为flownetC和flownetS,其中flownetC以一对图片作为输入,先通过卷积提取一部分特征之后,然后通过correlation算子 比较两张图片中的特征。
flownet论文中分别对这两种网络结构进行训练,并且与baseline相比较,都有了较大的提升。
flownetc和flownets结构
flownet2在 flownet的基础上提出了三个新的优化方向:

  1. 网络训练时使用的数据集的顺序也会影响训练结果。使用flyingChairs作为初始训练集,训练Slong阶段,使用flyingthings3d作为Sfine阶段的训练数据集,并且在训练的过程中对学习率逐步减半,论文给出了以下最优训练步骤
    请添加图片描述

  2. 使用堆叠网络的方式来优化训练结果,即不仅仅用单个的flownetC 或 flownetS 来训练,而是将这些网络堆叠起来,一个网络的训练结果输出作为下一个网络的输入使用,那这个中间需要做什么处理呢?论文提出新的warp算子用于融合前一个网络输出flow和初始输入image2,并由初始输入image1减去对应的warp的结果,得到Brightness Error, 并将这些一起作为下一个网络的输入。
    flownet2网络结构

  3. 新创建了一个网络用于学习图片中的小位移 – flownetSD

网络迁移难点

网络迁移过程使用nvidia官方发布的flownet2-pytorch作为参考flownet2-pytorch
网络分数据处理,网络对应算子迁移,loss,优化器等。

nvidia发布的代码已经封装的很完整了,使用的优化器和loss函数也都是常用的,通过参考mindspore提供教程和算子api对应,进行替换即可。

网络中除了基础的网络结构之外,除了基础的网络结构,比较麻烦的是需要将pytorch实现的自定义算子在mindspore中实现,pytorch中的自定义算子可以通过pip 的方式进行安装,所以可以放在项目中的子文件夹中,灵活性更强。而mindspore中的自定义算子需要写在源码中,并且mindspore中的算子结构与tf中的算子结构更相似。但是不管怎样,基本上都是由python 前端定义和 c++和cuda 算子后端逻辑实现共同组成。
具体如何实现,将在下一篇中详细介绍。

[1]: FlowNet: Learning Optical Flow with Convolutional Networks
[2]: FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks

以下是使用PyTorch实现的Flownet中的correlation代码: ```python import torch def correlation(x1, x2, kernel_size=1, stride=1, padding=0, dilation=1): # x1, x2: [batch_size, channel, height, width] # kernel_size: kernel size of cross-correlation # stride: stride of cross-correlation # padding: padding of cross-correlation # dilation: dilation of cross-correlation batch_size, channels, height, width = x1.size() # pad input tensors padding_size = kernel_size // 2 x1 = torch.nn.functional.pad(x1, (padding_size, padding_size, padding_size, padding_size)) x2 = torch.nn.functional.pad(x2, (padding_size, padding_size, padding_size, padding_size)) # create output tensor out_channels = channels * kernel_size * kernel_size out_height = (height + 2 * padding - kernel_size) // stride + 1 out_width = (width + 2 * padding - kernel_size) // stride + 1 output = torch.zeros(batch_size, out_channels, out_height, out_width).to(x1.device) # cross-correlate for i in range(kernel_size): for j in range(kernel_size): x1_shifted = x1[:, :, i:i+out_height*stride:stride, j:j+out_width*stride:stride].reshape(batch_size, channels, -1) x2_shifted = x2[:, :, i:i+out_height*stride:stride, j:j+out_width*stride:stride].reshape(batch_size, channels, -1) output[:, (i*kernel_size+j)*channels:(i*kernel_size+j+1)*channels, :, :] = torch.bmm(x1_shifted.permute(0,2,1), x2_shifted) return output.reshape(batch_size, out_channels, out_height, out_width) ``` 该函数接受两个输入张量x1和x2,以及卷积核大小kernel_size,步长stride,填充padding和膨胀dilation。它返回x1和x2之间的相互关系张量。 在该函数中,我们首先对输入张量进行填充以使其与卷积核大小对齐。然后,我们根据卷积核大小和步长计算输出张量的大小,并创建一个全零张量作为输出。最后,我们遍历卷积核的所有位置并计算x1和x2之间的相互关系,将结果存储在输出张量中。 我们可以使用该函数来实现Flownet中的correlation层。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值