Convert/import Torch model to PyTorch
Hi, Great library! I’d like to ask if it is possible to import a trained Torch model to PyTorch… Thanks
miliadis
As of today, you can deserialize Lua’s .t7 files into PyTorch containing Tensors, numbers, tables, nn models (no nngraph), strings. Here’s an example of saving a tensor in Torch and loading it back in PyTorch <SCODE>
th> a = torch.randn(10)
                                                                      [0.0027s]
th> torch.save('a.t7', a)
                                                                      [0.0010s]
th> a
-1.4479
 1.3707
 0.5663
-1.0590
 0.0706
-1.6495
-1.0805
 0.8277
-0.4595
 0.1237
[torch.DoubleTensor of size 10]

                                                                      [0.0033s]
<ECODE> <SCODE>In [1]: import torch

In [2]: from torch.utils.serialization import load_lua

In [3]: a = load_lua('a.t7')

In [4]: a
Out[4]:

-1.4479
 1.3707
 0.5663
-1.0590
 0.0706
-1.6495
-1.0805
 0.8277
-0.4595
 0.1237
[torch.DoubleTensor of size 10]
<ECODE> Here’s an example of loading a 2 layer sequential neural network: <SCODE>th> a = nn.Sequential():add(nn.Linear(10, 20)):add(nn.ReLU())
                                                                      [0.0001s]
th> a
nn.Sequential {
  [input -> (1) -> (2) -> output]
  (1): nn.Linear(10 -> 20)
  (2): nn.ReLU
}
                                                                      [0.0001s]
th> torch.save('a.t7', a)
                                                                      [0.0008s]
th>
<ECODE> <SCODE>In [5]: a = load_lua('a.t7')

In [6]: a
Out[6]:
nn.Sequential {
  [input -> (0) -> (1) -> output]
  (0): nn.Linear(10 -> 20)
  (1): nn.ReLU
}

In [7]: a.__class__
Out[7]: torch.legacy.nn.Sequential.Sequential
<ECODE>
smth
Hi, Is there a simple way to convert a torch.legacy.nn module into a torch.nn module ?
alexis-jacq
No, unfortunately we don’t have an automatic converter at the moment.
apaszke
But it should be quite simple to add.
apaszke
<SCODE>>>> n=load_lua('/Users/eugenioculurciello/Dropbox/shared/models/enet128-demo-46/model.net')
>>> n.forward(torch.FloatTensor(1,3,128,128))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Module.py", line 32, in forward
    return self.updateOutput(input)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Sequential.py", line 35, in updateOutput
    currentOutput = module.updateOutput(currentOutput)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/ConcatTable.py", line 12, in updateOutput
    self.output = [module.updateOutput(input) for module in self.modules]
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/ConcatTable.py", line 12, in <listcomp>
    self.output = [module.updateOutput(input) for module in self.modules]
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/SpatialMaxPooling.py", line 33, in updateOutput
    if self.indices is None:
AttributeError: 'SpatialMaxPooling' object has no attribute 'indices'
<ECODE> also on an AlexNet: <SCODE>>>> n=load_lua('/Users/eugenioculurciello/Dropbox/shared/models/elab-alexowt-46/model.net')
>>> n
nn.Sequential {
  [input -> (0) -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> (11) -> (12) -> (13) -> (14) -> (15) -> (16) -> (17) -> (18) -> (19) -> output]
  (0): nn.SpatialConvolution(3 -> 64, 11x11, 4, 4, 2, 2)
  (1): nn.ReLU
  (2): nn.SpatialMaxPooling(3x3, 2, 2)
  (3): nn.SpatialConvolution(64 -> 192, 5x5, 1, 1, 2, 2)
  (4): nn.ReLU
  (5): nn.SpatialMaxPooling(3x3, 2, 2)
  (6): nn.SpatialConvolution(192 -> 384, 3x3, 1, 1, 1, 1)
  (7): nn.ReLU
  (8): nn.SpatialConvolution(384 -> 256, 3x3, 1, 1, 1, 1)
  (9): nn.ReLU
  (10): nn.SpatialConvolution(256 -> 256, 3x3, 1, 1, 1, 1)
  (11): nn.ReLU
  (12): nn.SpatialMaxPooling(3x3, 2, 2)
  (13): nn.View(9216)
  (14): nn.Linear(9216 -> 4096)
  (15): nn.ReLU
  (16): nn.Linear(4096 -> 4096)
  (17): nn.ReLU
  (18): nn.Linear(4096 -> 46)
  (19): nn.SoftMax
}
>>> n.forward(torch.FloatTensor(1,3,224,224))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Module.py", line 32, in forward
    return self.updateOutput(input)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Sequential.py", line 35, in updateOutput
    currentOutput = module.updateOutput(currentOutput)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Linear.py", line 43, in updateOutput
    assert input.dim() == 2
AssertionError
>>> n.forward(torch.FloatTensor(3,224,224))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Module.py", line 32, in forward
    return self.updateOutput(input)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Sequential.py", line 35, in updateOutput
    currentOutput = module.updateOutput(currentOutput)
  File "/usr/local/lib/python3.6/site-packages/torch/legacy/nn/Linear.py", line 43, in updateOutput
    assert input.dim() == 2
AssertionError
<ECODE> Can you explain how to run old networks here? Or how to go about doing that?
Eugenio_Culurciello
For Alexnet just do: (instead of nn.View(9216)) For enet it’s trickier. There are several errors in the pytorch legacy code. Then you have again the View issue at the end. After all these changes, it will run.
mvitez
apaszke
Sure, I will. This forum wants 20 characters to answer.
mvitez
Modify your Torch according to this PR <SCODE>function patch(m)
   if torch.type(m) == 'nn.Padding' and m.nInputDim == 3 then
      m.dim = m.dim+1
      m.nInputDim = 4
   end
   if torch.type(m) == 'nn.View' and #m.size == 1 then
      newsize = torch.LongStorage(2)
      newsize[1] = 1
      newsize[2] = m.size[1]
      m.size = newsize
   end
   if m.modules then
      for i =1,#m.modules do
         patch(m.modules[i])
      end
   end
end

require 'nn'
net = torch.load('model.net')
patch(net)
torch.save('model2.net',net)
<ECODE>
mvitez
Can ‘load_lua’ works for model with cudnn layers ? I am getting some serialization issues in read_lua_file.py. I had to use cudnn.convert(model,nn) and load_lua.
HarshaVardhanP
No, it doesn’t support cudnn layers at the moment.
apaszke
clcarwin
pronics2004
I think the serialization of GPU models might not be implemented. A quick workaround would be to load the checkpoint in Lua, cast it to CPU float, and try loading in PyTorch then.
apaszke
When using load_lua, I got an error AttributeError: type object ‘FloatStorage’ has no attribute ‘from_buffer’, how can I solve this problem?
liuhantang
Is there any chance your model contains CUDA tensors?
apaszke
I got the same problem. Any solutions?
melody-rain
Yes, do you have any CUDA tensors in your model?
apaszke
Thanks, that solves my problem. Previously I used cudnn.convert(model, nn), but did not use model:float(), so there was still cuda tensor.
liuhantang