Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: Can't pickle local object 'TrainAugmentation.__init__.<locals>.<lambda>' #71

Open
Zx117x opened this issue Sep 4, 2019 · 10 comments

Comments

@Zx117x
Copy link

Zx117x commented Sep 4, 2019

The following error occurred during training(python train_ssd.py)
AttributeError: Can't pickle local object 'TrainAugmentation.init..'
EOFError: Ran out of input

@littlerain2310
Copy link

can u fix it ?? i have the same issue

@wangwangww
Copy link

I also have this quesion.

@littlerain2310
Copy link

i read a comment saying that this program need the Os to be Linux(It doesnt work on Window)

@EnricoBeltramo
Copy link

add to command line option: --num_workers=0
similar issue:
pyg-team/pytorch_geometric#366

@laolihaile
Copy link

I also have this quesion.

@kueblert
Copy link

kueblert commented Sep 7, 2021

Replacing the lambda function in TrainAugmentation with the following function worked for me:

class ScaleByStd:
def init(self, std):
self.std = std

def __call__(self, image, boxes=None, labels=None):
    return image / self.std, boxes, labels

@jamespreed
Copy link

jamespreed commented Oct 20, 2021

Full instructions based on @kueblert 's answer:

In the file vision\ssd\data_preprocessing.py insert the following lines after the import statement:

class ScaleByStd:
    def __init__(self, std: float):
        self.std = std

    def __call__(self, img, boxes=None, labels=None):
        return (img / self.std, boxes, labels)

Next modify the definitions of the TrainAugmentation, TestTransform and PredictionTransform classes by replacing the lines:

lambda img, boxes=None, labels=None: (img / std, boxes, labels),

with

ScaleByStd(std),

The top of the file should look like this:

from ..transforms.transforms import *


class ScaleByStd:
    def __init__(self, std: float):
        self.std = std

    def __call__(self, img, boxes=None, labels=None):
        return (img / self.std, boxes, labels)


class TrainAugmentation:
    def __init__(self, size, mean=0, std=1.0):
        """
        Args:
            size: the size the of final image.
            mean: mean pixel value per channel.
        """
        self.mean = mean
        self.size = size
        self.augment = Compose([
            ConvertFromInts(),
            PhotometricDistort(),
            Expand(self.mean),
            RandomSampleCrop(),
            RandomMirror(),
            ToPercentCoords(),
            Resize(self.size),
            SubtractMeans(self.mean),
            ScaleByStd(std),
            ToTensor(),
        ])

    def __call__(self, img, boxes, labels):
        """

        Args:
            img: the output of cv.imread in RGB layout.
            boxes: boundding boxes in the form of (x1, y1, x2, y2).
            labels: labels of boxes.
        """
        return self.augment(img, boxes, labels)


class TestTransform:
    def __init__(self, size, mean=0.0, std=1.0):
        self.transform = Compose([
            ToPercentCoords(),
            Resize(size),
            SubtractMeans(mean),
            ScaleByStd(std),
            ToTensor(),
        ])

    def __call__(self, image, boxes, labels):
        return self.transform(image, boxes, labels)


class PredictionTransform:
    def __init__(self, size, mean=0.0, std=1.0):
        self.transform = Compose([
            Resize(size),
            SubtractMeans(mean),
            ScaleByStd(std),
            ToTensor()
        ])

    def __call__(self, image):
        image, _, _ = self.transform(image)
        return image

@rsamvelyan
Copy link

Full instructions based on @kueblert 's answer:

In the file vision\ssd\data_preprocessing.py insert the following lines after the import statement:

class ScaleByStd:
    def __init__(self, std: float):
        self.std = std

    def __call__(self, img, boxes=None, labels=None):
        return (img / self.std, boxes, labels)

Next modify the definitions of the TrainAugmentation, TestTransform and PredictionTransform classes by replacing the lines:

lambda img, boxes=None, labels=None: (img / std, boxes, labels),

with

ScaleByStd(std),

The top of the file should look like this:

from ..transforms.transforms import *


class ScaleByStd:
    def __init__(self, std: float):
        self.std = std

    def __call__(self, img, boxes=None, labels=None):
        return (img / self.std, boxes, labels)


class TrainAugmentation:
    def __init__(self, size, mean=0, std=1.0):
        """
        Args:
            size: the size the of final image.
            mean: mean pixel value per channel.
        """
        self.mean = mean
        self.size = size
        self.augment = Compose([
            ConvertFromInts(),
            PhotometricDistort(),
            Expand(self.mean),
            RandomSampleCrop(),
            RandomMirror(),
            ToPercentCoords(),
            Resize(self.size),
            SubtractMeans(self.mean),
            ScaleByStd(std),
            ToTensor(),
        ])

    def __call__(self, img, boxes, labels):
        """

        Args:
            img: the output of cv.imread in RGB layout.
            boxes: boundding boxes in the form of (x1, y1, x2, y2).
            labels: labels of boxes.
        """
        return self.augment(img, boxes, labels)


class TestTransform:
    def __init__(self, size, mean=0.0, std=1.0):
        self.transform = Compose([
            ToPercentCoords(),
            Resize(size),
            SubtractMeans(mean),
            ScaleByStd(std),
            ToTensor(),
        ])

    def __call__(self, image, boxes, labels):
        return self.transform(image, boxes, labels)


class PredictionTransform:
    def __init__(self, size, mean=0.0, std=1.0):
        self.transform = Compose([
            Resize(size),
            SubtractMeans(mean),
            ScaleByStd(std),
            ToTensor()
        ])

    def __call__(self, image):
        image, _, _ = self.transform(image)
        return image

It worked for me!
I'm getting a warning though on line 247 of transforms.py:

...you must specify data type=object when creating the ndarray...

@Zx117x
Copy link
Author

Zx117x commented Dec 8, 2021 via email

@Neltherion
Copy link

@rsamvelyan Thanks. Any idea why your code change made the error go away?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants