目前网上使用torchscript导出实际模型的案例比较少,以下遇到的问题均是本人导出PatchmatchNet过程中遇到的问题
欢迎使用torchscript导出模型的同学们一起在评论区中讨论遇到的问题,尽量使得本文提出的问题能为我们以后避坑
channel, self.G, rounding_mode='trunc')
整个改成
int(feature_channel/self.G)
出错提示 RuntimeError: undefined value warped_feature
355行注释掉 del warped_feature, src_feature, src_proj, similarity, view_weight
出错提示’int’ object has no attribute or method ‘div_’.:
similarity = similarity_sum.di
v_(pixel_wise_weight_sum)
改成
similarity = torch.div(similarity_sum, pixel_wise_weight_sum)
或(两个重建的效果不同)
similarity = torch.div(similarity_sum, pixel_wise_weight_sum, rounding_mode='trunc')
patchmatch.py 364行
score = self.similarity_net(similarity, grid, weight) # [B, Nde
pth, H, W]
改成
score = self.similarity_net(torch.tensor(similarity), grid, weight) # [B, Ndepth, H, W]
softmax = nn.LogSoftmax(dim=1)
score = softmax(score)
改成
score = F.log_softmax(score, dim=1)
grid: torch.Tensor = None,
weight: torch.Tensor = None,
view_weights: torch.Tensor = None,
改成
grid: torch.Tensor,
weight: torch.Tensor,
view_weights: torch.Tensor,
还有一个原因就是,torchscript中模型里面的变量,必须是唯一的,不能一个变量对应不同参数的类的实例化,不同参数的类的实例化要用不同名字的变量名来接收
if self.propagate_neighbors > 0:
# last iteration on stage 1 does not have propagation (photometric consistency filtering)
# stage 1 的最后一次迭代不需要传播所以无需计算偏移量
if not (self.stage == 1 and self.patchmatch_iteration == 1):
propa_offset = self.propa_conv(ref_feature)
propa_offset = propa_offset.view(batch, 2 * self.propagate_neighbors, height * width)#2是[Δx,Δy]两个方向的偏移
propa_grid = self.get_propagation_grid(batch, height, width, propa_offset, device, img)
output = nn.Sigmoid()
x1 = output(x1)
改成
x1 = F.sigmoid(x1)
心得,以后遇到torch.nn的函数当script导出出错时,都用
import torch.nn.functional as F
然后F点出对应的函数,基本都支持的,这样就能通过了,运行测试的结果也是正确的
patchmatch.py 38行
self.pre_processing = Pre_processing_img()
改成
self.pre_processing = torch.jit.trace(Pre_processing_img(), torch.rand(1, 5, 3, 480, 640), strict=False)
就是返回的数量只能是固定的
depth_sample, score, view_weights = self.evaluation(...)
改成
depth_sample, score = self.evaluation(...)
depth_sample, score = self.evaluation(...)
使用script导出时这样是无法返回的,会出现上述报错
我的解决方案,使用trace将该函数单独封装,就是该函数使用trace导出的模型,但是前提是要确保这个函数里面没有if结构
还有就是由于在模型中生成子模型,这个函数默认是在cpu上面的,要添加到gpu上面,否则会出现如下错误提示
Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! (when checking argument for argument mat2 in method wrapper__bmm)
解决方案示例:
注释掉的是原本的
# self.evaluation = Evaluation_1_return2(self.G, self.stage, self.evaluate_neighbors, self.patchmatch_iteration) # 4 1 9 1
src = [torch.rand(1, 16, 240, 320), torch.rand(1, 16, 240, 320), torch.rand(1, 16, 240, 320), torch.rand(1, 16, 240, 320)]
src_p = [torch.rand(1, 4, 4), torch.rand(1, 4, 4), torch.rand(1, 4, 4), torch.rand(1, 4, 4)]
example_input = (
tocuda(torch.rand(1, 16, 240, 320)),
tocuda(src),
tocuda(torch.rand(1, 4, 4)),
tocuda(src_p),
tocuda(torch.rand(1, 8, 240, 320)),
# torch.rand(1),
# torch.rand(1),
tocuda(torch.rand(1, 2160, 320, 2)),
tocuda(torch.rand(1, 8, 9, 240, 320)),
tocuda(torch.rand(1, 4, 240, 320))
)
self.evaluation = torch.jit.trace(Evaluation_1_return2().cuda(), example_input, strict=False)
提示:如果不用上述方法,就算用以下方法来对返回的Tensor取值也是操作不了的
会报如下错误
score = receive[0:8, :, :]
depth_sample = receive[8, :, :]
score, depth_sample = torch.split(receive, [8, 1], dim=0)
depth_sample = receive[0]