Tensorflow Object Detection API: "FailedPreconditionError: HashTable has different value for same key. Key item { has 0 and trying to add value 4"

Viewed 166

I am trying to work with this yolov4 in tensorflow 2.0 model it requires the dataset to be in Tensorflow Object Detection API format. Since I had no prior experience with this api so I was following Adrian Rosebrock's tutorial in his ImageNet bundle book. I'm working with crowdHuman dataset, and I've simplified its annotations a bit. Like in this format below,

/content/gdrive/MyDrive/Datasets/CrowdHuman/crowdHuman_2671.jpg,head,126,243,133,251 /content/gdrive/MyDrive/Datasets/CrowdHuman/crowdHuman_2671.jpg,person,-20,241,19,343 /content/gdrive/MyDrive/Datasets/CrowdHuman/crowdHuman_2671.jpg,head,-12,242,0,254 /content/gdrive/MyDrive/Datasets/CrowdHuman/crowdHuman_1343.jpg,person,-10,281,203,825 /content/gdrive/MyDrive/Datasets/CrowdHuman/crowdHuman_1343.jpg,head,65,293,127,374

I barely changed the code in tutorial other than changing paths and file names, the code files I used are as follows

1 Config.py

import os

BASE_PATH = "/content/gdrive/MyDrive/Datasets/CrowdHuman/"

ANNOT_PATH = BASE_PATH + "annot_train_final.txt"

# Output paths
TRAIN_RECORD = BASE_PATH + "records/training.record"
TEST_RECORD = BASE_PATH + "records/testing.record"
CLASSES_FILE = BASE_PATH + "records/classes.pbtxt"

TEST_SIZE = 0.10

CLASSES = {"person": 1, "head": 2}

2 tfAnnotations.py

from object_detection.utils.dataset_util import bytes_list_feature
from object_detection.utils.dataset_util import float_list_feature
from object_detection.utils.dataset_util import int64_list_feature
from object_detection.utils.dataset_util import int64_feature
from object_detection.utils.dataset_util import bytes_feature

class TFAnnotation:
    def __init__(self):
        # initializing bbox and labels lists
        self.xMins = []
        self.xMaxs = []
        self.yMins = []
        self.yMaxs = []
        self.textLabels = []
        self.classes = []
        self.difficult = []

        # initializing additional variables including image itself
        # spatial dims, encoding and filename

        self.image = None
        self.width = None
        self.height = None
        self.encoding = None
        self.filename = None

    def build(self):
        # now we encode the attributes using their respective
        # Tensorflow encoding function
        w = int64_feature(self.width)
        h = int64_feature(self.height)
        filename = bytes_feature(self.filename.encode("utf8"))
        encoding = bytes_feature(self.encoding.encode("utf8"))
        image = bytes_feature(self.image)
        xMins = float_list_feature(self.xMins)
        xMaxs = float_list_feature(self.xMaxs)
        yMins = float_list_feature(self.yMins)
        yMaxs = float_list_feature(self.yMaxs)
        textLabels = bytes_list_feature(self.textLabels)
        classes = int64_list_feature(self.classes)
        difficult = int64_list_feature(self.difficult)

        # Construct the TensorFlow compatible data dict
        data = {
            "image/height": h,
            "image/width": w,
            "image/filename": filename,
            "image/source_id": filename,
            "image/encode": image,
            "image/format": encoding,
            "image/object/bbox/xmin": xMins,
            "image/object/bbox/xmax": xMaxs,
            "image/object/bbox/ymin": yMins,
            "image/object/bbox/ymax": yMaxs,
            "image/object/class/text": textLabels,
            "image/object/class/label": classes,
            "image/object/difficult": difficult,
        }

        return data

3 records_builder.py

import crowdHuman_config as config
from tfAnnotation import TFAnnotation
from sklearn.model_selection import train_test_split
from PIL import Image
import tensorflow.compat.v1 as tf
import os


def main(_):
    # open classes output file
    f = open(config.CLASSES_FILE, "w")

    # loop over the classes
    for (k, v) in config.CLASSES.items():
        # construct the class info and write to file
        item = ("item {\n"
                "\tid: " + str(v) + "\n"
                "\tname: '" + k + "'\n"
                "}\n")
        f.write(item)
    f.close()

    # initialize a data dict used to map each image filename to
    # all bboxes associated with the image and then load the
    # contents of the annot file
    D = {}
    rows = open(config.ANNOT_PATH).read().strip().split('\n')

    # loop over the individual rows
    for row in rows:
        # break the ewo into compenents
        row = row.split(",")
        (imagePath, label, startX, startY, endX, endY) = row
        (startX, startY) =  (float(startX), float(startY))
        (endX, endY) = (float(endX), float(endY))

        # if we are not interested in the label, ignore it
        if label not in config.CLASSES:
            continue

        # build the path to the input image and then grap any
        # other boxes and labels associated with the image
        # path, labels and bbx lists respectively

        #p = os.path.sep.join([config.BASE_PATH, imagePath])
        p = imagePath
        b = D.get(p,[])

        # build a tuple consisting of the label and bbox
        # then update the list and store it in the dict
        b.append((label, (startX, startY, endX, endY)))
        D[p] = b

    #print("[INFO] list(D.keys()): {}".format(list(D.keys())))

    # create training and testing splits from our data dict
    (trainKeys, testKeys) = train_test_split(list(D.keys()),
                test_size=config.TEST_SIZE, random_state=42)

    # initialize the data split files
    datasets = [
        ("train", trainKeys, config.TRAIN_RECORD),
        ("test", testKeys, config.TEST_RECORD)
    ]

    # loop over the datasets
    for (dType, keys, outputPath) in datasets:
        # intialize the Tensorflow writer and initialize the
        # total number of examples written to file
        print("[INFO] processing '{}'...".format(dType))
        writer = tf.python_io.TFRecordWriter(outputPath)
        total = 0

        # loop over all the kerys in the current set
        for k in keys:
            # load the input image from disk as a tensorflow obj
            encoded = tf.gfile.GFile(k, "rb").read()
            encoded = bytes(encoded)

            # load the image from disk again, this time as a PIL
            # object
            pilImage = Image.open(k)
            (w, h) = pilImage.size[:2]

            # parse the filename and encoding from the input path
            filename = k.split(os.path.sep)[-1]
            encoding = filename[filename.rfind(".")+1:]

            # intialize the annotattion object used to store
            # info regarding the bbox and labels
            tfAnnot = TFAnnotation()
            tfAnnot.image = encoded
            tfAnnot.encoding = encoding
            tfAnnot.filename = filename
            tfAnnot.width = w
            tfAnnot.height = h

            #loop over the bbox and labels associated with the img
            for (label, (startX, startY, endX, endY)) in D[k]:
                # tensorflow assumes all bbox are in the range
                # [0,1] so we need to scale them
                xMin = startX / w
                xMax = endX / w
                yMin = startY / h
                yMax = endY / h

                # update the bbox and labels lists
                tfAnnot.xMins.append(xMin)
                tfAnnot.xMaxs.append(xMax)
                tfAnnot.yMins.append(yMin)
                tfAnnot.yMaxs.append(yMax)
                tfAnnot.textLabels.append(label.encode("utf8"))
                tfAnnot.classes.append(config.CLASSES[label])
                tfAnnot.difficult.append(0)

                # increment the total number of examples
                total += 1

            # encode the data point attributes using the Tensorflow
            # helper functions
            features = tf.train.Features(feature=tfAnnot.build())
            example = tf.train.Example(features=features)

            # add the example to the writer
            writer.write(example.SerializeToString())

        # close the writer and print the diagnostic info to the user
        writer.close()
        print("[INFO] {} examples saved for '{}'".format(total, dType))

# check to see if the main thread should be started
if __name__ == "__main__":
    tf.app.run()

All these scripts ran successfully and produced the desired files but when I tried using this dataset in the model mentioned above, it gave me this error. There's no really relatable solution that I could find. So I'd really appreciate the help.

ERROR:

Traceback (most recent call last):
  File "train.py", line 195, in <module>
    app.run(main)
  File "/usr/local/lib/python3.7/dist-packages/absl/app.py", line 303, in run
    _run_main(main, args)
  File "/usr/local/lib/python3.7/dist-packages/absl/app.py", line 251, in _run_main
    sys.exit(main(argv))
  File "train.py", line 64, in main
    FLAGS.dataset, FLAGS.classes, FLAGS.size)
  File "/content/yolov3-tf2/yolov3_tf2/dataset.py", line 124, in load_tfrecord_dataset
    class_file, tf.string, 0, tf.int64, LINE_NUMBER, delimiter="\n"), -1)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 314, in __init__
    super(StaticHashTable, self).__init__(default_value, initializer)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 185, in __init__
    self._init_op = self._initialize()
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 188, in _initialize
    return self._initializer.initialize(self)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 744, in initialize
    -1 if self._vocab_size is None else self._vocab_size, self._delimiter)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/gen_lookup_ops.py", line 363, in initialize_table_from_text_file_v2
    _ops.raise_from_not_ok_status(e, name)
  File "/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py", line 6862, in raise_from_not_ok_status
    six.raise_from(core._status_to_exception(e.code, message), None)
  File "<string>", line 3, in raise_from
tensorflow.python.framework.errors_impl.FailedPreconditionError: HashTable has different value for same key. Key item { has 0 and trying to add value 4 [Op:InitializeTableFromTextFileV2]
0 Answers
Related