如何把一个深度学习代码从torch框架改成mindspore框架

最重要的如何创建数据集和dataloader

在 MindSpore 静态图模式(@ms_function 或默认图模式)中是不允许 del xxx

MindSpore 不支持detach()

1
2
3
4
# torch版本
cur_depth = cur_depth.detach()
# mindspore版本
cur_depth = ops.stop_gradient(cur_depth)

MindSpore 中调用了 imgs.size(1),但 MindSpore 的 Tensor 没有 size() 方法,应该用 shape 属性

1
2
3
4
# torch版本
for nview_idx in range(imgs.size(1)):
# mindspore版本
for nview_idx in range(imgs.shape[1]):

ops.split 不支持 output_num 而是使用 split_size_or_sections

1
hidden_d, inp_d = ops.split(cnet_depth_stage, axis=1, split_size_or_sections=2)

tensor.repeat不支持axis

1
2
3
4
5
6
7
8
9
10
11
12
# torch版本
xyz = ops.stack((x, y, ops.ones_like(x))) # [3, H*W]
print("xyz.shape:",xyz.shape)
xyz = ops.expand_dims(xyz, 0).repeat(batch, axis=0) # [B, 3, H*W]
print("xyz.shape:",xyz.shape)

# mindspore版本
xyz = ops.stack((x, y, ops.ones_like(x))) # [3, H*W]
print("xyz.shape:",xyz.shape)
xyz = ops.expand_dims(xyz, 0) # [1, 3, H*W]
xyz = ops.tile(xyz, (batch, 1, 1)) # [B, 3, H*W]
print("xyz.shape:",xyz.shape)

forward函数命名为construct函数

原继承nn.module,现在改为继承nn.Cell,继承之后需要把原先的forward函数改名为construct

1
2
3
4
5
6
lass DepthNet(nn.Cell):
def __init__(self, cnnpixel=False):
super(DepthNet, self).__init__()

def construct(self, features, proj_matrices, depth_values, num_depth, cost_regularization, pixel_wise_net, G=8):
return

torch.nn.Sequential 改为mindspore.nn.SequentialCell

nn.ModuleList改为nn.CellList

sequence改为ops.sequence

1
2
3
4
# torch版本
prob_volume_pre = prob_volume_pre.squeeze(1)
# mindspore版本
prob_volume_pre = ops.squeeze(prob_volume_pre, axis=1)

F变ops

1
2
3
4
# torch版本
prob_volume_ = F.softmax(prob_volume_pre*5.0, dim=1)
# mindspore版本
prob_volume = ops.softmax(prob_volume_pre, axis=1)

padding要加pad_mode

1
2
3
4
# torch版本
self.convc1 = nn.Conv2d(cost_dim, hidden_dim, 1, padding=0)
# mindspore版本
nn.Conv2d(cost_dim, hidden_dim, 1, padding=0, pad_mode='pad')

relu要创建后才能使用,且没有inplace

激活函数都需要先初始化才能用不能直接用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# torch版本有inplace参数并且relu可以直接运算
x = F.relu(x, inplace=True)
return F.relu(self.bn(self.conv(x)), inplace=True)
以下啊是错误的
class ConvBnReLU3D(nn.Cell):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, pad=1):
super(ConvBnReLU3D, self).__init__()
self.conv = nn.Conv3d(in_channels, out_channels, kernel_size, stride=stride, padding=pad, pad_mode='pad', has_bias=False)
self.bn = nn.BatchNorm3d(out_channels)
def forward(self, x):
return nn.ReLU(self.bn(self.conv(x)))

# 要先创建一个relu,才能使用
class ConvBnReLU3D(nn.Cell):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, pad=1):
super(ConvBnReLU3D, self).__init__()
self.conv = nn.Conv3d(in_channels, out_channels, kernel_size, stride=stride, padding=pad, pad_mode='pad', has_bias=False)
self.bn = nn.BatchNorm3d(out_channels)
self.relu = nn.ReLU()
def forward(self, x):
return self.relu(self.bn(self.conv(x)))

bias参数改名为has_bias

1
2
3
4
# torch版本
self.conv = nn.Conv2dTranspose(in_channels, out_channels, kernel_size, stride=stride,bias=(not bn), **kwargs)
# mindspore版本
self.conv = nn.Conv2dTranspose(in_channels, out_channels, kernel_size, stride=stride,has_bias=(not bn), **kwargs)

cat指定维度不用dim,改名为axis

1
2
3
4
# torch版本
ops.cat([conv0, IGEV_cost_], dim=1)
# mindspore版本
ops.cat([conv0, IGEV_cost_], axis=1)

所有nrom的操作中weight和bias改名为gamma和beta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 针对bn层进行初始化
bn_module = nn.BatchNorm2d(out_channels, momentum=bn_momentum)
# torch版本
def init_bn(module):
if module.weight is not None:
nn.init.ones_(module.weight)
if module.bias is not None:
nn.init.zeros_(module.bias)
return

# mindspore版本
def init_bn(module):
# 用gamma和beta取代wight和bias
# 没有init函数,只有set_data和initializer
if module.gamma is not None:
module.gamma.set_data(initializer(One(), module.gamma.shape, module.gamma.dtype))
if module.beta is not None:
module.beta.set_data(initializer(Zero(), module.beta.shape, module.beta.dtype))
return