[Bug] Pytorch, AttributeError: module ‘torch‘ has no attribute ‘_six‘

实验环境

Torch1.10py3.8,

问题描述

Bug: Pytorch, AttributeError: module ‘torch’ has no attribute ‘_six’, 确认了配置的Environment下torch包下面确实没有_six.py文件,

网上搜了下,有的是Pytorch, AttributeError: module ‘torch._six’ has no attribute ‘PY37’, 这个时python版本的问题,只需要在_six.py改一行代码即可, 我的问题于这个不太一样.

原因分析:

环境问题,由于该环境下已经撞了很多其他的工具包,再去重新装新的版本太麻烦,
报错位置位于vision.py文件下的

class VisionDataset(data.Dataset):
    """
    Base Class For making datasets which are compatible with torchvision.
    It is necessary to override the ``__getitem__`` and ``__len__`` method.

    Args:
        root (string): Root directory of dataset.
        transforms (callable, optional): A function/transforms that takes in
            an image and a label and returns the transformed versions of both.
        transform (callable, optional): A function/transform that  takes in an PIL image
            and returns a transformed version. E.g, ``transforms.RandomCrop``
        target_transform (callable, optional): A function/transform that takes in the
            target and transforms it.

    .. note::

        :attr:`transforms` and the combination of :attr:`transform` and :attr:`target_transform` are mutually exclusive.
    """
    _repr_indent = 4

    def __init__(
            self,
            root: str,
            transforms: Optional[Callable] = None,
            transform: Optional[Callable] = None,
            target_transform: Optional[Callable] = None,
    ) -> None:
        torch._C._log_api_usage_once(f"torchvision.datasets.{self.__class__.__name__}")
        if isinstance(root, torch._six.string_classes):

可以看到实际上就使用了_six文件下定义的一个类别:torch._six.string_classes,

解决方案:

Step1. 我在另一个Environment: torch1.10py3.6下找到了_six.py, 内容如下:

import math
import sys

inf = math.inf
nan = math.nan
string_classes = (str, bytes)
PY37 = sys.version_info[0] == 3 and sys.version_info[1] >= 7

def with_metaclass(meta: type, *bases) -> type:
    """Create a base class with a metaclass."""
    # This requires a bit of explanation: the basic idea is to make a dummy
    # metaclass for one level of class instantiation that replaces itself with
    # the actual metaclass.
    class metaclass(meta):  # type: ignore[misc, valid-type]

        def __new__(cls, name, this_bases, d):
            return meta(name, bases, d)

        @classmethod
        def __prepare__(cls, name, this_bases):
            return meta.__prepare__(name, bases)

    return type.__new__(metaclass, 'temporary_class', (), {})

然后将其拷贝到目标环境的torch包下面,

Step 2: 修改vision中引用_six.py的地方, 如下,
from torch._six import string_classes as string_classes
#if isinstance(root, torch._six.string_classes): # before
if isinstance(root, string_classes): # after

OK.

你可能感兴趣的:(pytorch,bug,深度学习)