different output if convert model to mlprogram
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 850
- Avg merge
- 4d 5h
- Merged PRs (30d)
- 10
Description
## 🐞Describing the bug
I try to convert PyTorch model to mlprogram but got different prediction than PyTorch prediction.
## To Reproduce
```python
import torch
import torch.nn as nn
import coremltools as ct
import numpy as np
class test_module(nn.Module):
def __init__(self, F = 961 , device="cpu"):
super(test_module, self).__init__()
self.F = F
self.C = self._build_C(self.F)
self.device = device
self.register_buffer(
"mat",
torch.tensor(self._build_inv_delta_C(self.F, self.C),
dtype=torch.float,
device=self.device)
)
def _build_C(self, F):
im_x, im_y = np.mgrid[-1:1:complex(31), -1:1:complex(31)]
C = np.stack((im_y,im_x), axis=2).reshape(-1,2)
return C
def _build_inv_delta_C(self, F, C):
hat_C = np.zeros((F, F), dtype=float) # F x F
for i in range(0, F):
for j in range(i, F):
r = np.linalg.norm(C[i] - C[j])
hat_C[i, j] = r
hat_C[j, i] = r
np.fill_diagonal(hat_C, 1)
hat_C = (hat_C ** 2) * np.log(hat_C ** 2)
delta_C = np.concatenate( # F+3 x F+3
[
np.concatenate([np.ones((F, 1)), C, hat_C], axis=1), # F x F+3
np.concatenate([np.zeros((1, 3)), np.ones((1, F))], axis=1), # 1 x F+3
np.concatenate([np.zeros((2, 3)), np.transpose(C)], axis=1), # 2 x F+3
],
axis=0
)
mat = np.linalg.inv(delta_C)
return mat # F+3 x F+3
def forward(self, batch_C_prime):
batch_size = batch_C_prime.size(0)
batch_C_prime_with_zeros = torch.cat((batch_C_prime[0], torch.zeros(
batch_size, 3, 2).float().to(self.device)), dim=1) # batch_size x F+3 x 2
batch_T = torch.matmul(self.mat, batch_C_prime_with_zeros) # batch_size x F+3 x 2
return torch.matmul(torch.ones((1024, 964)).float() , torch.clone(batch_T))
m = test_module()
test_input = torch.ones([1,1,961, 2])
traced = torch.jit.trace(m, [test_input])
program = ct.convert(
traced,
convert_to="mlprogram",
# minimum_deployment_target = ct.target.macOS12,
# compute_precision=ct.precision.FLOAT16,
inputs=[
ct.TensorType(name='input', shape=(ct.RangeDim(), *test_input.shape[1:])),
],
)
input_name = program._spec.description.input[0].name
output_name = program._spec.description.output[0].name
program_output = program.predict({input_name: test_input})[output_name]
print(program_output)
mlmodel = ct.convert(
traced,
inputs=[
ct.TensorType(name='input', shape=(ct.RangeDim(), *test_input.shape[1:])),
],
)
input_name = mlmodel._spec.description.input[0].name
output_name = mlmodel._spec.description.output[0].name
mlmodel_output = mlmodel.predict({input_name: test_input})[output_name]
print(mlmodel_output)
```
mlprogram result
```
[[[17.709187 17.709187]
[17.709187 17.709187]
[17.709187 17.709187]
...
[17.709187 17.709187]
[17.709187 17.709187]
[17.709187 17.709187]]]
```
and mlmodel result
```
[[[1.003938 1.003938]
[1.003938 1.003938]
[1.003938 1.003938]
...
[1.003938 1.003938]
[1.003938 1.003938]
[1.003938 1.003938]]]
```
## System environment (please complete the following information):
- coremltools version: 6.0b2
- PyTorch: 1.10.0
Contributor guide
Research direction
Start by running the supplied Python reproducer with PyTorch 1.10.0 and coremltools 6.0b2, comparing ct.convert(..., convert_to="mlprogram") with the default conversion. Investigate the conversion paths for the shown matmul operations and dynamic batch input. Done means the converted outputs match the PyTorch result, with a regression check for this reproducer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- machine-learning, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100