lucidrains/byol-pytorch

RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment

wengooooo opened this issue · 2 comments

I tried the sample code available in README, but i get a error

byol-pytorch  0.5.4
torch              1.7.1
kornia             0.4.1

Code:

import torch
from byol_pytorch import BYOL
from torchvision import models

resnet = models.resnet50(pretrained=True)

learner = BYOL(
    resnet,
    image_size = 256,
    hidden_layer = 'avgpool'
)

opt = torch.optim.Adam(learner.parameters(), lr=3e-4)

def sample_unlabelled_images():
    return torch.randn(20, 3, 256, 256)

for _ in range(100):
    images = sample_unlabelled_images()
    loss = learner(images)
    opt.zero_grad()
    loss.backward()
    opt.step()
    learner.update_moving_average() # update moving average of target encoder

# save your improved network
torch.save(resnet.state_dict(), './improved-net.pt')

Error

Traceback (most recent call last):
  File "demo.py", line 12, in <module>
    hidden_layer = 'avgpool'
  File "/cloud/byol-pytorch/byol_pytorch/byol_pytorch.py", line 224, in __init__
    self.forward(torch.randn(2, 3, image_size, image_size, device=device))
  File "/cloud/byol-pytorch/byol_pytorch/byol_pytorch.py", line 256, in forward
    target_encoder = self._get_target_encoder() if self.use_momentum else self.online_encoder
  File "/cloud/byol-pytorch/byol_pytorch/byol_pytorch.py", line 28, in wrapper
    instance = fn(self, *args, **kwargs)
  File "/cloud/byol-pytorch/byol_pytorch/byol_pytorch.py", line 229, in _get_target_encoder
    target_encoder = copy.deepcopy(self.online_encoder)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 280, in _reconstruct
    state = deepcopy(state, memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 150, in deepcopy
    y = copier(x, memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 240, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/copy.py", line 161, in deepcopy
    y = copier(memo)
  File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/tensor.py", line 47, in __deepcopy__
    raise RuntimeError("Only Tensors created explicitly by the user "
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment

Did you resolve it? What helped?

In my Jupyter notebook, this happens to me if I run the BYOL constructor twice, reusing the network passed to it.
The solution is to recreate the resnet as well.
i.e. keep these lines together

resnet = models.resnet50(pretrained=True)

learner = BYOL(
    resnet,
    image_size = 256,
    hidden_layer = 'avgpool'
)