一、pth2caffe

Net:定义的网络结构,pth存储的模型路径

  1. def pth2caffe(Net,pth):
  2. from pytorch2caffe import pytorch2caffe
  3. name = 'yolov3_2'
  4. model = Net
  5. #将权重加载到网络中
  6. model_dict = model.state_dict()
  7. pretrained_dict = torch.load(pth, map_location=torch.device('cpu'))
  8. pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
  9. model_dict.update(pretrained_dict)
  10. model.load_state_dict(model_dict)
  11. model.eval()
  12. #定义转换格式后的输入数据大小
  13. dummy_input = torch.ones([1, 3, 40, 40])
  14. pytorch2caffe.trans_net(model, dummy_input, name)
  15. pytorch2caffe.save_prototxt('{}.prototxt'.format(name))
  16. pytorch2caffe.save_caffemodel('{}.caffemodel'.format(name))

二、测试模型生成

  1. import numpy as np
  2. import torch
  3. import torch.nn as nn
  4. #定义网络结构
  5. class YoloBody(nn.Module):
  6. def __init__(self, anchors_mask, num_classes):
  7. super(YoloBody, self).__init__()
  8. self.last_layer0 = nn.Conv2d(3, len(anchors_mask[0]) * (num_classes + 5), kernel_size=1, stride=1)
  9. self.last_layer1 = nn.Conv2d(3, len(anchors_mask[0]) * (num_classes + 5), kernel_size=1, stride=1)
  10. self.last_layer2 = nn.Conv2d(3, len(anchors_mask[0]) * (num_classes + 5), kernel_size=1, stride=1)
  11. def forward(self, x):
  12. out0 = self.last_layer0(x)
  13. out1 = self.last_layer1(x)
  14. out2 = self.last_layer2(x)
  15. return out0, out1, out2
  16. #网络参数初始化
  17. def weights_init(net, init_type='kaiming', init_gain = 0.02):
  18. def init_func(m):
  19. classname = m.__class__.__name__
  20. if hasattr(m, 'weight') and classname.find('Conv') != -1:
  21. if init_type == 'normal':
  22. torch.nn.init.normal_(m.weight.data, 0.0, init_gain)
  23. elif init_type == 'xavier':
  24. torch.nn.init.xavier_normal_(m.weight.data, gain=init_gain)
  25. elif init_type == 'kaiming':
  26. torch.nn.init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
  27. elif init_type == 'orthogonal':
  28. torch.nn.init.orthogonal_(m.weight.data, gain=init_gain)
  29. else:
  30. raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
  31. elif classname.find('BatchNorm2d') != -1:
  32. torch.nn.init.normal_(m.weight.data, 1.0, 0.02)
  33. torch.nn.init.constant_(m.bias.data, 0.0)
  34. print('initialize network with %s type' % init_type)
  35. net.apply(init_func)
  36. def pth2caffe(Net,pth):
  37. from pytorch2caffe import pytorch2caffe
  38. name = 'yolov3_2'
  39. model = Net
  40. model_dict = model.state_dict()
  41. pretrained_dict = torch.load(pth, map_location=torch.device('cpu'))
  42. pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
  43. model_dict.update(pretrained_dict)
  44. model.load_state_dict(model_dict)
  45. model.eval()
  46. #转换格式后的输入
  47. dummy_input = torch.ones([1, 3, 40, 40])
  48. pytorch2caffe.trans_net(model, dummy_input, name)
  49. pytorch2caffe.save_prototxt('{}.prototxt'.format(name))
  50. pytorch2caffe.save_caffemodel('{}.caffemodel'.format(name))
  51. if __name__ == "__main__":
  52. anchors_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]]
  53. #网络结构定义
  54. Net = YoloBody(anchors_mask,20)
  55. #自定义模型路径
  56. modelpath = "xx/xx/yolo.pth"
  57. weights_init(Net)
  58. Net.train()
  59. #保存pytorch模型
  60. torch.save(Net.state_dict(),modelpath)
  61. #转换格式
  62. pth2caffe(Net,modelpath)