{
  "id": 309611,
  "title": "TF records with Detic Crop",
  "url": "/competitions/happy-whale-and-dolphin/discussion/309611",
  "author_name": "Martin Kovacevic Buvinic",
  "post_date": "2022-02-24T11:59:49.197000",
  "votes": 37,
  "comment_count": 14,
  "views": 0,
  "content": "<p>This datasets provide images with detic crop, the differences with shared datasets is that this images are already cropped and resize. This will lead to a faster training pipeline because you don't need to resize.</p>\n<p>Here are the links for different image size</p>\n<p><a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280</a></p>\n<p>This are the key columns for each set</p>\n<p>Train: [\"image_id\", \"image\", \"species\",\"individual_id\"]<br>\nTest: [\"image_id\", \"image\"]<br>\nFor mapping the classes you can use the csv file store in the same dataset named train_encoded.csv</p>\n<p>I already tried them and with my pipeline the cv score is similar to the best public score script.</p>\n<p>Cheers</p>",
  "messages": [
    {
      "id": 1703352,
      "postDate": "2022-02-24T11:59:49.197Z",
      "content": "<p>This datasets provide images with detic crop, the differences with shared datasets is that this images are already cropped and resize. This will lead to a faster training pipeline because you don't need to resize.</p>\n<p>Here are the links for different image size</p>\n<p><a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024</a><br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280</a></p>\n<p>This are the key columns for each set</p>\n<p>Train: [\"image_id\", \"image\", \"species\",\"individual_id\"]<br>\nTest: [\"image_id\", \"image\"]<br>\nFor mapping the classes you can use the csv file store in the same dataset named train_encoded.csv</p>\n<p>I already tried them and with my pipeline the cv score is similar to the best public score script.</p>\n<p>Cheers</p>",
      "rawMarkdown": "This datasets provide images with detic crop, the differences with shared datasets is that this images are already cropped and resize. This will lead to a faster training pipeline because you don't need to resize.\n\nHere are the links for different image size\n\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280\n\nThis are the key columns for each set\n\nTrain: [\"image_id\", \"image\", \"species\",\"individual_id\"]\nTest: [\"image_id\", \"image\"]\nFor mapping the classes you can use the csv file store in the same dataset named train_encoded.csv\n\nI already tried them and with my pipeline the cv score is similar to the best public score script.\n\nCheers",
      "votes": 37
    },
    {
      "id": 1710255,
      "postDate": "2022-03-02T21:16:52.720Z",
      "content": "<p><a href=\"https://www.kaggle.com/ragnar123\" target=\"_blank\">@ragnar123</a> , if you think it's possible and sharable , can you please let me know how you have applied detic crop before encoding them into TF dataset?</p>",
      "rawMarkdown": "@ragnar123 , if you think it's possible and sharable , can you please let me know how you have applied detic crop before encoding them into TF dataset?",
      "votes": 1,
      "replies": [
        {
          "id": 1711500,
          "postDate": "2022-03-04T04:03:15.887Z",
          "content": "<p>Sure, here si the notebook<br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tf-records-detic-box-768x768\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tf-records-detic-box-768x768</a></p>",
          "rawMarkdown": "Sure, here si the notebook\nhttps://www.kaggle.com/ragnar123/happywhale-tf-records-detic-box-768x768",
          "votes": 1
        }
      ]
    },
    {
      "id": 1707760,
      "postDate": "2022-02-28T18:37:20.120Z",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/ragnar123\" target=\"_blank\">@ragnar123</a> <br>\nI tried to use your dataset in place of the happywhale-tfrecords-bb<br>\nI made some changes to the code for processing the dataset. <br>\nMy training and validation seem good. But when I submit, my LB is 0.089<br>\nSame model and same setup with happywhale-tfrecords-bb gave 0.691. <br>\nCan you mention whether I did some mistake in handling your dataset</p>\n<p><strong>No Changes</strong></p>\n<pre><code>def arcface_format(posting_id, image, label_group, matches):\n    return posting_id, {'inp1': image, 'inp2': label_group}, label_group, matches\n\ndef arcface_inference_format(posting_id, image, label_group, matches):\n    return image,posting_id\n\ndef arcface_eval_format(posting_id, image, label_group, matches):\n    return image,label_group\n\n# Data augmentation function\ndef data_augment(posting_id, image, label_group, matches):\n\n    ### CUTOUT\n    if tf.random.uniform([])&gt;0.5 and config.CUTOUT:\n      N_CUTOUT = 6\n      for cutouts in range(N_CUTOUT):\n        if tf.random.uniform([])&gt;0.5:\n           DIM = config.IMAGE_SIZE\n           CUTOUT_LENGTH = DIM//8\n           x1 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           x2 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           filter_ = tf.concat([tf.zeros((x1,CUTOUT_LENGTH)),tf.ones((CUTOUT_LENGTH,CUTOUT_LENGTH)),tf.zeros((DIM-x1-CUTOUT_LENGTH,CUTOUT_LENGTH))],axis=0)\n           filter_ = tf.concat([tf.zeros((DIM,x2)),filter_,tf.zeros((DIM,DIM-x2-CUTOUT_LENGTH))],axis=1)\n           cutout = tf.reshape(1-filter_,(DIM,DIM,1))\n           image = cutout*image\n\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_hue(image, 0.01)\n    image = tf.image.random_saturation(image, 0.70, 1.30)\n    image = tf.image.random_contrast(image, 0.80, 1.20)\n    image = tf.image.random_brightness(image, 0.10)\n    return posting_id, image, label_group, matches\n</code></pre>\n<p><strong>Changes Made</strong></p>\n<pre><code>def decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels = 3)\n    image = tf.image.resize(image, [config.IMAGE_SIZE , config.IMAGE_SIZE])\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n\ndef read_labeled_tfrecord_train(example):\n\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"species\": tf.io.FixedLenFeature([], tf.int64),\n        'individual_id': tf.io.FixedLenFeature([], tf.int64),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    label_species = tf.cast(example['species'], tf.int32)\n    label_individual_id = tf.cast(example['individual_id'], tf.int32)\n    matches = 1\n    return image_id, image, label_individual_id, matches\n\ndef read_labeled_tfrecord_test(example):\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    return image_id, image, None, None\n\n# This function loads TF Records and parse them into tensors\ndef load_dataset(filenames, ordered = False, is_train=True):\n\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads = AUTO)\n    dataset = dataset.with_options(ignore_order)\n    if is_train:\n        dataset = dataset.map(read_labeled_tfrecord_train, num_parallel_calls = AUTO) \n    else:\n        dataset = dataset.map(read_labeled_tfrecord_test, num_parallel_calls = AUTO) \n    return dataset\n\n# This function is to get our training tensors\ndef get_training_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = False)\n    dataset = dataset.map(data_augment, num_parallel_calls = AUTO)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.repeat()\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_val_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_eval_dataset(filenames, get_targets = True):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_eval_format, num_parallel_calls = AUTO)\n    if not get_targets:\n        dataset = dataset.map(lambda image, target: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_test_dataset(filenames, get_names = True):\n    dataset = load_dataset(filenames, ordered = True, is_train =False)\n    dataset = dataset.map(arcface_inference_format, num_parallel_calls = AUTO)\n    if not get_names:\n        dataset = dataset.map(lambda image, posting_id: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n</code></pre>",
      "rawMarkdown": "Hi @ragnar123 \nI tried to use your dataset in place of the happywhale-tfrecords-bb\nI made some changes to the code for processing the dataset. \nMy training and validation seem good. But when I submit, my LB is 0.089\nSame model and same setup with happywhale-tfrecords-bb gave 0.691. \nCan you mention whether I did some mistake in handling your dataset\n\n**No Changes**\n```\ndef arcface_format(posting_id, image, label_group, matches):\n    return posting_id, {'inp1': image, 'inp2': label_group}, label_group, matches\n\ndef arcface_inference_format(posting_id, image, label_group, matches):\n    return image,posting_id\n\ndef arcface_eval_format(posting_id, image, label_group, matches):\n    return image,label_group\n\n# Data augmentation function\ndef data_augment(posting_id, image, label_group, matches):\n\n    ### CUTOUT\n    if tf.random.uniform([])>0.5 and config.CUTOUT:\n      N_CUTOUT = 6\n      for cutouts in range(N_CUTOUT):\n        if tf.random.uniform([])>0.5:\n           DIM = config.IMAGE_SIZE\n           CUTOUT_LENGTH = DIM//8\n           x1 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           x2 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           filter_ = tf.concat([tf.zeros((x1,CUTOUT_LENGTH)),tf.ones((CUTOUT_LENGTH,CUTOUT_LENGTH)),tf.zeros((DIM-x1-CUTOUT_LENGTH,CUTOUT_LENGTH))],axis=0)\n           filter_ = tf.concat([tf.zeros((DIM,x2)),filter_,tf.zeros((DIM,DIM-x2-CUTOUT_LENGTH))],axis=1)\n           cutout = tf.reshape(1-filter_,(DIM,DIM,1))\n           image = cutout*image\n\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_hue(image, 0.01)\n    image = tf.image.random_saturation(image, 0.70, 1.30)\n    image = tf.image.random_contrast(image, 0.80, 1.20)\n    image = tf.image.random_brightness(image, 0.10)\n    return posting_id, image, label_group, matches\n```\n\n\n**Changes Made**\n\n```\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels = 3)\n    image = tf.image.resize(image, [config.IMAGE_SIZE , config.IMAGE_SIZE])\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n    \ndef read_labeled_tfrecord_train(example):\n    \n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"species\": tf.io.FixedLenFeature([], tf.int64),\n        'individual_id': tf.io.FixedLenFeature([], tf.int64),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    label_species = tf.cast(example['species'], tf.int32)\n    label_individual_id = tf.cast(example['individual_id'], tf.int32)\n    matches = 1\n    return image_id, image, label_individual_id, matches\n\ndef read_labeled_tfrecord_test(example):\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    return image_id, image, None, None\n    \n# This function loads TF Records and parse them into tensors\ndef load_dataset(filenames, ordered = False, is_train=True):\n    \n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n        \n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads = AUTO)\n    dataset = dataset.with_options(ignore_order)\n    if is_train:\n        dataset = dataset.map(read_labeled_tfrecord_train, num_parallel_calls = AUTO) \n    else:\n        dataset = dataset.map(read_labeled_tfrecord_test, num_parallel_calls = AUTO) \n    return dataset\n\n# This function is to get our training tensors\ndef get_training_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = False)\n    dataset = dataset.map(data_augment, num_parallel_calls = AUTO)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.repeat()\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_val_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_eval_dataset(filenames, get_targets = True):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_eval_format, num_parallel_calls = AUTO)\n    if not get_targets:\n        dataset = dataset.map(lambda image, target: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_test_dataset(filenames, get_names = True):\n    dataset = load_dataset(filenames, ordered = True, is_train =False)\n    dataset = dataset.map(arcface_inference_format, num_parallel_calls = AUTO)\n    if not get_names:\n        dataset = dataset.map(lambda image, posting_id: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n```",
      "votes": 1,
      "replies": [
        {
          "id": 1707810,
          "postDate": "2022-02-28T20:24:35.663Z",
          "content": "<p>It looks correct, nevertheless their could be some bug in other parts of your code. I would need to check all the code, my suggestion is that you go line by line, im not using the same code as the public notebook so I could not tell where is the error.</p>",
          "rawMarkdown": "It looks correct, nevertheless their could be some bug in other parts of your code. I would need to check all the code, my suggestion is that you go line by line, im not using the same code as the public notebook so I could not tell where is the error.",
          "votes": 1
        }
      ]
    },
    {
      "id": 1705691,
      "postDate": "2022-02-26T18:11:02.387Z",
      "content": "<p>I appologize if this is a basic question, but I'm very confused with the use of TFRecord. I understand it is a good way to store samples of data, but my confusion is in the use of this data and the records.</p>\n<p>Say I was using a triplet loss and wanted to ensure every batch had valid triplets with like 4 images per individual and 4 individuals per batch for a total of 16 images. How would I use the TFRec dataset in such a way that I can feed these images in and ensure valid batches?</p>",
      "rawMarkdown": "I appologize if this is a basic question, but I'm very confused with the use of TFRecord. I understand it is a good way to store samples of data, but my confusion is in the use of this data and the records.\n\nSay I was using a triplet loss and wanted to ensure every batch had valid triplets with like 4 images per individual and 4 individuals per batch for a total of 16 images. How would I use the TFRec dataset in such a way that I can feed these images in and ensure valid batches?",
      "votes": 1,
      "replies": [
        {
          "id": 1705819,
          "postDate": "2022-02-26T21:02:41.863Z",
          "rawMarkdown": "",
          "votes": 1,
          "isDeleted": true
        },
        {
          "id": 1705890,
          "postDate": "2022-02-27T00:15:41.393Z",
          "content": "<p>Our task in this competition is to match individuals. So, if that's the case, does that mean we can not use the ~9k images? It's just like they even do not have labels. Thank you, if you can reply me.</p>",
          "rawMarkdown": "Our task in this competition is to match individuals. So, if that's the case, does that mean we can not use the ~9k images? It's just like they even do not have labels. Thank you, if you can reply me.",
          "votes": 1
        },
        {
          "id": 1705988,
          "postDate": "2022-02-27T03:54:24.183Z",
          "rawMarkdown": "",
          "votes": 1,
          "isDeleted": true
        },
        {
          "id": 1707610,
          "postDate": "2022-02-28T15:56:15.680Z",
          "content": "<p>I was using triplet loss with image augmentation so the same image could appear a number of times with different augmentations.</p>\n<p>I don’t expect it to be a winner but it’s my initial approach, I want to dive into the arc margin loss afterwards. I was just confused as to how we do this with the tf records, or does the arc margin loss not require this to be the case.</p>\n<p>My question might be completely off because of my low understanding of arcface at the moment. If that is the case could I ask in the Tf records are the images just randomly shuffled into the je dataset and read in some random order?</p>",
          "rawMarkdown": "I was using triplet loss with image augmentation so the same image could appear a number of times with different augmentations.\n\nI don’t expect it to be a winner but it’s my initial approach, I want to dive into the arc margin loss afterwards. I was just confused as to how we do this with the tf records, or does the arc margin loss not require this to be the case.\n\nMy question might be completely off because of my low understanding of arcface at the moment. If that is the case could I ask in the Tf records are the images just randomly shuffled into the je dataset and read in some random order?",
          "votes": 1
        },
        {
          "id": 1707816,
          "postDate": "2022-02-28T20:27:40.683Z",
          "content": "<p>Images are stratified by species_id, you can read them (random or order) depending on you tf.Dataset functions. Their is also a csv file that has all the data with the corresponding folds which is called train_encoded.csv</p>",
          "rawMarkdown": "Images are stratified by species_id, you can read them (random or order) depending on you tf.Dataset functions. Their is also a csv file that has all the data with the corresponding folds which is called train_encoded.csv\n"
        }
      ]
    },
    {
      "id": 1704024,
      "postDate": "2022-02-25T05:06:58.750Z",
      "content": "<p>cheers! I just want to create by myself and found you had already done. many appreciated and very helpful!</p>",
      "rawMarkdown": "cheers! I just want to create by myself and found you had already done. many appreciated and very helpful!",
      "votes": 1
    },
    {
      "id": 1703571,
      "postDate": "2022-02-24T16:24:08.683Z",
      "rawMarkdown": "",
      "votes": 1,
      "isDeleted": true
    },
    {
      "id": 1705722,
      "postDate": "2022-02-26T18:32:39.800Z",
      "content": "<p>Thanks for sharing!</p>",
      "rawMarkdown": "Thanks for sharing!",
      "votes": 1
    },
    {
      "id": 1703511,
      "postDate": "2022-02-24T15:23:50.837Z",
      "content": "<p>thanks for sharing!</p>",
      "rawMarkdown": "thanks for sharing!",
      "votes": 1
    }
  ],
  "comments": [
    {
      "id": 1710255,
      "author_name": "soumya",
      "author_url": "",
      "post_date": "2022-03-02T21:16:52.720000",
      "content": "<p><a href=\"https://www.kaggle.com/ragnar123\" target=\"_blank\">@ragnar123</a> , if you think it's possible and sharable , can you please let me know how you have applied detic crop before encoding them into TF dataset?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1711500,
          "author_name": "Martin Kovacevic Buvinic",
          "author_url": "",
          "post_date": "2022-03-04T04:03:15.887000",
          "content": "<p>Sure, here si the notebook<br>\n<a href=\"https://www.kaggle.com/ragnar123/happywhale-tf-records-detic-box-768x768\" target=\"_blank\">https://www.kaggle.com/ragnar123/happywhale-tf-records-detic-box-768x768</a></p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1707760,
      "author_name": "Balaji Selvaraj",
      "author_url": "",
      "post_date": "2022-02-28T18:37:20.120000",
      "content": "<p>Hi <a href=\"https://www.kaggle.com/ragnar123\" target=\"_blank\">@ragnar123</a> <br>\nI tried to use your dataset in place of the happywhale-tfrecords-bb<br>\nI made some changes to the code for processing the dataset. <br>\nMy training and validation seem good. But when I submit, my LB is 0.089<br>\nSame model and same setup with happywhale-tfrecords-bb gave 0.691. <br>\nCan you mention whether I did some mistake in handling your dataset</p>\n<p><strong>No Changes</strong></p>\n<pre><code>def arcface_format(posting_id, image, label_group, matches):\n    return posting_id, {'inp1': image, 'inp2': label_group}, label_group, matches\n\ndef arcface_inference_format(posting_id, image, label_group, matches):\n    return image,posting_id\n\ndef arcface_eval_format(posting_id, image, label_group, matches):\n    return image,label_group\n\n# Data augmentation function\ndef data_augment(posting_id, image, label_group, matches):\n\n    ### CUTOUT\n    if tf.random.uniform([])&gt;0.5 and config.CUTOUT:\n      N_CUTOUT = 6\n      for cutouts in range(N_CUTOUT):\n        if tf.random.uniform([])&gt;0.5:\n           DIM = config.IMAGE_SIZE\n           CUTOUT_LENGTH = DIM//8\n           x1 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           x2 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           filter_ = tf.concat([tf.zeros((x1,CUTOUT_LENGTH)),tf.ones((CUTOUT_LENGTH,CUTOUT_LENGTH)),tf.zeros((DIM-x1-CUTOUT_LENGTH,CUTOUT_LENGTH))],axis=0)\n           filter_ = tf.concat([tf.zeros((DIM,x2)),filter_,tf.zeros((DIM,DIM-x2-CUTOUT_LENGTH))],axis=1)\n           cutout = tf.reshape(1-filter_,(DIM,DIM,1))\n           image = cutout*image\n\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_hue(image, 0.01)\n    image = tf.image.random_saturation(image, 0.70, 1.30)\n    image = tf.image.random_contrast(image, 0.80, 1.20)\n    image = tf.image.random_brightness(image, 0.10)\n    return posting_id, image, label_group, matches\n</code></pre>\n<p><strong>Changes Made</strong></p>\n<pre><code>def decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels = 3)\n    image = tf.image.resize(image, [config.IMAGE_SIZE , config.IMAGE_SIZE])\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n\ndef read_labeled_tfrecord_train(example):\n\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"species\": tf.io.FixedLenFeature([], tf.int64),\n        'individual_id': tf.io.FixedLenFeature([], tf.int64),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    label_species = tf.cast(example['species'], tf.int32)\n    label_individual_id = tf.cast(example['individual_id'], tf.int32)\n    matches = 1\n    return image_id, image, label_individual_id, matches\n\ndef read_labeled_tfrecord_test(example):\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    return image_id, image, None, None\n\n# This function loads TF Records and parse them into tensors\ndef load_dataset(filenames, ordered = False, is_train=True):\n\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads = AUTO)\n    dataset = dataset.with_options(ignore_order)\n    if is_train:\n        dataset = dataset.map(read_labeled_tfrecord_train, num_parallel_calls = AUTO) \n    else:\n        dataset = dataset.map(read_labeled_tfrecord_test, num_parallel_calls = AUTO) \n    return dataset\n\n# This function is to get our training tensors\ndef get_training_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = False)\n    dataset = dataset.map(data_augment, num_parallel_calls = AUTO)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.repeat()\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_val_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_eval_dataset(filenames, get_targets = True):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_eval_format, num_parallel_calls = AUTO)\n    if not get_targets:\n        dataset = dataset.map(lambda image, target: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_test_dataset(filenames, get_names = True):\n    dataset = load_dataset(filenames, ordered = True, is_train =False)\n    dataset = dataset.map(arcface_inference_format, num_parallel_calls = AUTO)\n    if not get_names:\n        dataset = dataset.map(lambda image, posting_id: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n</code></pre>",
      "votes": 1,
      "replies": [
        {
          "id": 1707810,
          "author_name": "Martin Kovacevic Buvinic",
          "author_url": "",
          "post_date": "2022-02-28T20:24:35.663000",
          "content": "<p>It looks correct, nevertheless their could be some bug in other parts of your code. I would need to check all the code, my suggestion is that you go line by line, im not using the same code as the public notebook so I could not tell where is the error.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1705691,
      "author_name": "Kiernan McGuigan",
      "author_url": "",
      "post_date": "2022-02-26T18:11:02.387000",
      "content": "<p>I appologize if this is a basic question, but I'm very confused with the use of TFRecord. I understand it is a good way to store samples of data, but my confusion is in the use of this data and the records.</p>\n<p>Say I was using a triplet loss and wanted to ensure every batch had valid triplets with like 4 images per individual and 4 individuals per batch for a total of 16 images. How would I use the TFRec dataset in such a way that I can feed these images in and ensure valid batches?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 1705819,
          "author_name": "",
          "author_url": "",
          "post_date": "2022-02-26T21:02:41.863000",
          "content": "",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1705890,
          "author_name": "Trunway",
          "author_url": "",
          "post_date": "2022-02-27T00:15:41.393000",
          "content": "<p>Our task in this competition is to match individuals. So, if that's the case, does that mean we can not use the ~9k images? It's just like they even do not have labels. Thank you, if you can reply me.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1705988,
          "author_name": "",
          "author_url": "",
          "post_date": "2022-02-27T03:54:24.183000",
          "content": "",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1707610,
          "author_name": "Kiernan McGuigan",
          "author_url": "",
          "post_date": "2022-02-28T15:56:15.680000",
          "content": "<p>I was using triplet loss with image augmentation so the same image could appear a number of times with different augmentations.</p>\n<p>I don’t expect it to be a winner but it’s my initial approach, I want to dive into the arc margin loss afterwards. I was just confused as to how we do this with the tf records, or does the arc margin loss not require this to be the case.</p>\n<p>My question might be completely off because of my low understanding of arcface at the moment. If that is the case could I ask in the Tf records are the images just randomly shuffled into the je dataset and read in some random order?</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 1707816,
          "author_name": "Martin Kovacevic Buvinic",
          "author_url": "",
          "post_date": "2022-02-28T20:27:40.683000",
          "content": "<p>Images are stratified by species_id, you can read them (random or order) depending on you tf.Dataset functions. Their is also a csv file that has all the data with the corresponding folds which is called train_encoded.csv</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1704024,
      "author_name": "liuzhangzhen",
      "author_url": "",
      "post_date": "2022-02-25T05:06:58.750000",
      "content": "<p>cheers! I just want to create by myself and found you had already done. many appreciated and very helpful!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1703571,
      "author_name": "",
      "author_url": "",
      "post_date": "2022-02-24T16:24:08.683000",
      "content": "",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1705722,
      "author_name": "Artem Burenok",
      "author_url": "",
      "post_date": "2022-02-26T18:32:39.800000",
      "content": "<p>Thanks for sharing!</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 1703511,
      "author_name": "dragon zhang",
      "author_url": "",
      "post_date": "2022-02-24T15:23:50.837000",
      "content": "<p>thanks for sharing!</p>",
      "votes": 1,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1703352": "This datasets provide images with detic crop, the differences with shared datasets is that this images are already cropped and resize. This will lead to a faster training pipeline because you don't need to resize.\n\nHere are the links for different image size\n\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-256\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-512\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-768\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1024\nhttps://www.kaggle.com/ragnar123/happywhale-tfrecords-detic-box-1280\n\nThis are the key columns for each set\n\nTrain: [\"image_id\", \"image\", \"species\",\"individual_id\"]\nTest: [\"image_id\", \"image\"]\nFor mapping the classes you can use the csv file store in the same dataset named train_encoded.csv\n\nI already tried them and with my pipeline the cv score is similar to the best public score script.\n\nCheers",
    "1710255": "@ragnar123 , if you think it's possible and sharable , can you please let me know how you have applied detic crop before encoding them into TF dataset?",
    "1707760": "Hi @ragnar123 \nI tried to use your dataset in place of the happywhale-tfrecords-bb\nI made some changes to the code for processing the dataset. \nMy training and validation seem good. But when I submit, my LB is 0.089\nSame model and same setup with happywhale-tfrecords-bb gave 0.691. \nCan you mention whether I did some mistake in handling your dataset\n\n**No Changes**\n```\ndef arcface_format(posting_id, image, label_group, matches):\n    return posting_id, {'inp1': image, 'inp2': label_group}, label_group, matches\n\ndef arcface_inference_format(posting_id, image, label_group, matches):\n    return image,posting_id\n\ndef arcface_eval_format(posting_id, image, label_group, matches):\n    return image,label_group\n\n# Data augmentation function\ndef data_augment(posting_id, image, label_group, matches):\n\n    ### CUTOUT\n    if tf.random.uniform([])>0.5 and config.CUTOUT:\n      N_CUTOUT = 6\n      for cutouts in range(N_CUTOUT):\n        if tf.random.uniform([])>0.5:\n           DIM = config.IMAGE_SIZE\n           CUTOUT_LENGTH = DIM//8\n           x1 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           x2 = tf.cast( tf.random.uniform([],0,DIM-CUTOUT_LENGTH),tf.int32)\n           filter_ = tf.concat([tf.zeros((x1,CUTOUT_LENGTH)),tf.ones((CUTOUT_LENGTH,CUTOUT_LENGTH)),tf.zeros((DIM-x1-CUTOUT_LENGTH,CUTOUT_LENGTH))],axis=0)\n           filter_ = tf.concat([tf.zeros((DIM,x2)),filter_,tf.zeros((DIM,DIM-x2-CUTOUT_LENGTH))],axis=1)\n           cutout = tf.reshape(1-filter_,(DIM,DIM,1))\n           image = cutout*image\n\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_hue(image, 0.01)\n    image = tf.image.random_saturation(image, 0.70, 1.30)\n    image = tf.image.random_contrast(image, 0.80, 1.20)\n    image = tf.image.random_brightness(image, 0.10)\n    return posting_id, image, label_group, matches\n```\n\n\n**Changes Made**\n\n```\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels = 3)\n    image = tf.image.resize(image, [config.IMAGE_SIZE , config.IMAGE_SIZE])\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n    \ndef read_labeled_tfrecord_train(example):\n    \n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"species\": tf.io.FixedLenFeature([], tf.int64),\n        'individual_id': tf.io.FixedLenFeature([], tf.int64),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    label_species = tf.cast(example['species'], tf.int32)\n    label_individual_id = tf.cast(example['individual_id'], tf.int32)\n    matches = 1\n    return image_id, image, label_individual_id, matches\n\ndef read_labeled_tfrecord_test(example):\n    LABELED_TFREC_FORMAT = {\n        \"image_id\": tf.io.FixedLenFeature([], tf.string),\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image_id = example['image_id']\n    image = decode_image(example['image'])\n    return image_id, image, None, None\n    \n# This function loads TF Records and parse them into tensors\ndef load_dataset(filenames, ordered = False, is_train=True):\n    \n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n        \n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads = AUTO)\n    dataset = dataset.with_options(ignore_order)\n    if is_train:\n        dataset = dataset.map(read_labeled_tfrecord_train, num_parallel_calls = AUTO) \n    else:\n        dataset = dataset.map(read_labeled_tfrecord_test, num_parallel_calls = AUTO) \n    return dataset\n\n# This function is to get our training tensors\ndef get_training_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = False)\n    dataset = dataset.map(data_augment, num_parallel_calls = AUTO)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.repeat()\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_val_dataset(filenames):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_format, num_parallel_calls = AUTO)\n    dataset = dataset.map(lambda posting_id, image, label_group, matches: (image, label_group))\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_eval_dataset(filenames, get_targets = True):\n    dataset = load_dataset(filenames, ordered = True)\n    dataset = dataset.map(arcface_eval_format, num_parallel_calls = AUTO)\n    if not get_targets:\n        dataset = dataset.map(lambda image, target: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\n# This function is to get our training tensors\ndef get_test_dataset(filenames, get_names = True):\n    dataset = load_dataset(filenames, ordered = True, is_train =False)\n    dataset = dataset.map(arcface_inference_format, num_parallel_calls = AUTO)\n    if not get_names:\n        dataset = dataset.map(lambda image, posting_id: image)\n    dataset = dataset.batch(config.BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n```",
    "1705691": "I appologize if this is a basic question, but I'm very confused with the use of TFRecord. I understand it is a good way to store samples of data, but my confusion is in the use of this data and the records.\n\nSay I was using a triplet loss and wanted to ensure every batch had valid triplets with like 4 images per individual and 4 individuals per batch for a total of 16 images. How would I use the TFRec dataset in such a way that I can feed these images in and ensure valid batches?",
    "1704024": "cheers! I just want to create by myself and found you had already done. many appreciated and very helpful!",
    "1703571": "",
    "1705722": "Thanks for sharing!",
    "1703511": "thanks for sharing!"
  }
}