AttributeError: 'NoneType' object has no attribute 'take'

I want to train an object detector based on the Train a salad detector with TensorFlow Lite Model Maker notebook, but I’m using a dataset in Pascal VOC format.

The dataset can be loaded with

dataloader = object_detector.DataLoader.from_pascal_voc('chess-detection/images', 'chess-detection/annotations', ['white-rook', 'white-knight', 'white-bishop', 'white-king', 'white-queen', 'white-pawn', 'black-rook', 'black-knight', 'black-bishop', 'black-king', 'black-queen', 'black-pawn'])

but when trying to split it into a training and validation set using the split method (train_data, validation_data = dataloader.split(0.8)) im getting the following error:

AttributeError Traceback (most recent call last)

[<ipython-input-21-337838b38d0a>](https://localhost:8080/#) in <module>() ----> 1 train_data, validation_data = dataloader.split(0.8)

1 frames

[/usr/local/lib/python3.7/dist-packages/tensorflow_examples/lite/model_maker/core/data_util/dataloader.py](https://localhost:8080/#) in _split(self, fraction, *args) 145 146 train_size = int(self._size * fraction) --> 147 trainset = self.__class__(ds.take(train_size), train_size, *args) 148 149 test_size = self._size - train_size

AttributeError: 'NoneType' object has no attribute 'take'

Any help is greatly appreciated.

1 Like

Hi @Gi_T
Have you checked version of TensorFlow? Is it 2.5.0? Can you try with this version?

1 Like

Just checked. The Tensorflow version used is 2.5.0.

1 Like

Have you followed all the instructions here ?
It seems that they have an example inside from towardsscience.

1 Like

Yes, I think so. I already managed to train an object detector on my Microcontroller detection dataset. Both these datasets were labeled using LabelImg. The only differences between the two are that the microcontroller dataset is already split into a training and validation/test folder.

But strangely, if I train a model with the dataset loaded with:

dataloader = object_detector.DataLoader.from_pascal_voc('chess-detection/images', 'chess-detection/annotations', ['white-rook', 'white-knight', 'white-bishop', 'white-king', 'white-queen', 'white-pawn', 'black-rook', 'black-knight', 'black-bishop', 'black-king', 'black-queen', 'black-pawn'])

it seems to work. I’m only receiving the error when trying to split the dataset with the split method.

1 Like

If I were in your position I would split the data myself then…and raise an issue at the github page here

2 Likes

Okay. Thanks for the help

1 Like

If anybody is interested I split the data with the following code:

# split data into training and testing set
import os, random, shutil

os.mkdir('chess-detection/train')
os.mkdir('chess-detection/test')

image_paths = os.listdir('chess-detection/images')
random.shuffle(image_paths)

for i, image_path in enumerate(image_paths):
  if i < int(len(image_paths) * 0.8):
    shutil.copy(f'chess-detection/images/{image_path}', 'chess-detection/train')
    shutil.copy(f'chess-detection/annotations/{image_path.replace("JPG", "xml")}', 'chess-detection/train')
  else:
    shutil.copy(f'chess-detection/images/{image_path}', 'chess-detection/test')
    shutil.copy(f'chess-detection/annotations/{image_path.replace("JPG", "xml")}', 'chess-detection/test')

Also @George_Soloupis it seems like you can’t create any issues in the tensorflow/examples repository.

1 Like

@Gi_T I will forward the thread to the TensorFlow Lite team and if I have a response I will get back to you.

1 Like

Thanks a lot @George_Soloupis

1 Like

@Gi_T Dataloader for object detection doesn’t support split for now. We will add an error message if users call the split function first to avoid misleading. We will consider adding this function later.

As for now, If you’d like to split the data into train_data and valdation_data, you need to set annotation_filenames parameter in the from_pascal_voc function (api) to specify which annotation files to be used. For instance, if you have annotation files: 1.xml, 2.xml, 3.xml. You can use

train_dataloader = object_detector.DataLoader.from_pascal_voc(..., annotation_filenames=['1', '2'])
validation_dataloader = object_detector.DataLoader.from_pascal_voc(..., annotation_filenames=['3'])
3 Likes

Do you know if it is possible to load images in ‘.png’ format from a folder?

Using the object detection model maker tutorial, I was able to train my model, but I had to convert the data to .jpg.

It seems that DataLoader.from_pascal_voc only accepts .jpg due to how it implements the image open from folder using PIL,

Attribute errors in Python are generally raised when you try to access or call an attribute that a particular object type doesn’t possess. It’s simply because there is no attribute with the name you called, for that Object. This means that you got the error when the “module” does not contain the method you are calling. But it is evident that the method is there, which leads to believe that may be the method was added by you in the source code after you had already imported the file (module). Or, some times packages get deprecated and they rename some functions. If that is true, then you may want to exit and reimport the module once again to be able to access the new method .

You can do it in another way to reimport the module with changes without having to exit the interpreter is to do the following:

reload(myModule)

If you are using python 3.2 or 3.3 you should:

import imp
imp.reload(myModule)

If running Python 3.4 and up, do import importlib, then do:

import importlib
importlib.reload(myModule)

The importlib.reload() method reload a previously imported module. The argument must be a module object, so it must have been successfully imported before .