pytorch2keras
pytorch2keras copied to clipboard
Can't convert the official mobilenet model
Describe the bug I can't convert mobilenet V2 pytorch official model.
To Reproduce
from mobilenet_helper import *
from torch.autograd import Variable
from pytorch2keras.converter import pytorch_to_keras
from torchvision.models import mobilenet_v2
model = mobilenet_v2(pretrained=True)
dummy_input = Variable(torch.randn(1, 3, 224, 224))
# we should specify shape of the input tensor
k_model = pytorch_to_keras(model, dummy_input, [(3, sz, sz,)], verbose=True)
Expected behavior Model converted without errors
Logs
....
____
graph node: Sequential/Sequential[0]/Sequential[0]/InvertedResidual[1]/Sequential[conv]/Conv2d[1]
node id: 363
type: onnx::Conv
inputs: ['352', '13']
outputs: ['Sequential/Sequential[0]/Sequential[0]/InvertedResidual[1]/Sequential[conv]/Conv2d[1]']
name in state_dict: 0.0.1.conv.0
attrs: {'dilations': [1, 1], 'group': 1, 'kernel_shape': [1, 1], 'pads': [0, 0, 0, 0], 'strides': [1, 1]}
is_terminal: False
Converting convolution ...
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
...
/opt/anaconda3/lib/python3.7/site-packages/pytorch2keras/convolution_layers.py in convert_conv(params, w_name, scope_name, inputs, layers, weights, names)
33 input_name = inputs[0]
34
---> 35 if len(weights[weights_name].numpy().shape) == 5: # 3D conv
36 W = weights[weights_name].numpy().transpose(2, 3, 4, 1, 0)
37 height, width, channels, n_layers, n_filters = W.shape
KeyError: '0.0.1.conv.0.weight'
Environment (please complete the following information):
- OS: debian
- Python: Python 3.7
- Version pytorch 1.1.0, pytorch2keras 0.1.19
Additional context I think that the problem is in converter.py module, lines 279 - 294 (see me inline comment)
try:
int(node_name_regex[-1])
node_weigth_group_name = '.'.join(
node_name_regex[:-1]
)
# My comment: state dict keys goes from '0.0.1.conv.0.1.num_batches_tracked' to
#'0.0.1.conv.1.weight' but here it's assume that will start at 0 ('0.0.1.conv.0.weight') and
# don't perform any validation. Doing: node_weights_name = '.'.join(node_name_regex)
# would work.
node_weights_name = node_weigth_group_name + '.' + str(group_indices[node_weigth_group_name])
group_indices[node_weigth_group_name] += 1
except ValueError:
node_weights_name = '.'.join(
node_name_regex
)
except IndexError:
Pytorch State dict: ... '0.0.0.1.bias', '0.0.0.1.running_mean', '0.0.0.1.running_var', '0.0.0.1.num_batches_tracked', '0.0.1.conv.0.0.weight', '0.0.1.conv.0.1.weight', '0.0.1.conv.0.1.bias', '0.0.1.conv.0.1.running_mean', '0.0.1.conv.0.1.running_var', '0.0.1.conv.0.1.num_batches_tracked', '0.0.1.conv.1.weight', '0.0.1.conv.2.weight', '0.0.1.conv.2.bias', '0.0.1.conv.2.running_mean', '0.0.1.conv.2.running_var', '0.0.1.conv.2.num_batches_tracked', '0.0.2.conv.0.0.weight', ...
The model is defined in https://github.com/pytorch/vision/blob/master/torchvision/models/mobilenet.py and the problematic region is in the InvertedResidual block, the Conv2D just after ConvBNRelU block.
Hello @Apollo-XI. I'm back with some updates:
- Yes, it's known problem with wrong weight names parsing
- You can watch updates on #84 issue. It will be a new module for onnx->keras conversion, I plan to done it this week and keep this repository as high-level wrapper. Probably I'll break some API, but it worth the updates.
@Apollo-XI I successfully converted mobilenet from torchvision, with one modification. By default it uses:
x = x.mean([2, 3])
To calculate mean by 2 dimensions at once. Just replace it with:
x = x.mean(3).mean(2)
You can check it's equal:
a = torch.rand((1, 3, 224, 224))
a.mean(3).mean(2)
>> tensor([[0.4997, 0.5013, 0.4972]])
a.mean([2, 3])
>> tensor([[0.4997, 0.5013, 0.4972]])
@Apollo-XI
You can update your version of pytorch2keras and try to convert the model.
Hi @nerox8664
I updated to version 0.2.1 and I could convert the model successfully. However, I don't know if it's another bug but I'm using "channel_last" in keras config but I needed to specify input_shapes manually:
k_model = pytorch_to_keras(model, dummy_input, input_shapes=[(3, HEIGHT, WIDHT,)], change_ordering=True)
# If I run this:
# k_model = pytorch_to_keras(model, dummy_input, change_ordering=True)
# I get a Value error:
ValueError: An Input layer should be passed either a `batch_input_shape` or an `input_shape`.
Thanks for all!
@Apollo-XI.
I fixed the problem with input_shapes in the latest version.
Yes, there are some problems with change_ordering
, so, basically, it's not supported by now. I plan to fix it ASAP.
If anyone wanna convert MobilenetV2 from PyTorch to Tensorflow. https://github.com/CR-Ko/Pytorch2TF This might help.
But it require to modify onnx-tf.