{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport tensorflow as tf\nimport re\nimport math\nimport os\nfrom tqdm import tqdm\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.preprocessing import LabelEncoder\nimport joblib\nimport json\nfrom datetime import datetime","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-22T17:34:49.209934Z","iopub.execute_input":"2022-02-22T17:34:49.21036Z","iopub.status.idle":"2022-02-22T17:34:56.100444Z","shell.execute_reply.started":"2022-02-22T17:34:49.210255Z","shell.execute_reply":"2022-02-22T17:34:56.099458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\n### Create Kaggle Dataset if not exists \nDATASET_NAME = f'happywhale-tfrecords-detic-box-768'\n\n!rm -rf /tmp/{DATASET_NAME}\n\nos.makedirs(f'/tmp/{DATASET_NAME}', exist_ok=True)\n\nwith open('../input/mkb-kaggle-api/kaggle.json') as f:\n    kaggle_creds = json.load(f)\n    \nos.environ['KAGGLE_USERNAME'] = kaggle_creds['username']\nos.environ['KAGGLE_KEY'] = kaggle_creds['key']\n\n!kaggle datasets init -p /tmp/{DATASET_NAME}\n\nwith open(f'/tmp/{DATASET_NAME}/dataset-metadata.json') as f:\n    dataset_meta = json.load(f)\n\ndataset_meta['id'] = f'ragnar123/{DATASET_NAME}'\ndataset_meta['title'] = DATASET_NAME\nwith open(f'/tmp/{DATASET_NAME}/dataset-metadata.json', \"w\") as outfile:\n    json.dump(dataset_meta, outfile)\nprint(dataset_meta)\n\n!cp /tmp/{DATASET_NAME}/dataset-metadata.json /tmp/{DATASET_NAME}/meta.json\n!ls /tmp/{DATASET_NAME}\n!kaggle datasets create -u -p /tmp/{DATASET_NAME} ","metadata":{"execution":{"iopub.status.busy":"2022-02-22T17:34:56.102138Z","iopub.execute_input":"2022-02-22T17:34:56.102394Z","iopub.status.idle":"2022-02-22T17:34:59.652224Z","shell.execute_reply.started":"2022-02-22T17:34:56.102362Z","shell.execute_reply":"2022-02-22T17:34:59.651147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Configurations\n# Amount of TF records we want to create for the train set\nFOLDS = 30\n# Amount of TF records we want to create for the test set\nTEST_FOLDS = 28\n# Random seed for stratification\nSEED = 42\n# Image size \nIMAGE_SIZE = (768, 768)\n\ndef _bytes_feature(value):\n    \"\"\"Returns a bytes_list from a string / byte.\"\"\"\n    if isinstance(value, type(tf.constant(0))):\n        value = value.numpy()\n    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))\n\ndef _float_feature(value):\n    \"\"\"Returns a float_list from a float / double.\"\"\"\n    return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))\n\ndef _int64_feature(value):\n    \"\"\"Returns an int64_list from a bool / enum / int / uint.\"\"\"\n    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))\n\ndef read_bbox(bbox):\n    return np.array([int(i) for i in bbox.split()])\n\ndef serialize_example(image_id, image, species, individual_id, train = True):\n    if train:\n        feature = {\n            'image_id': _bytes_feature(image_id),\n            'image': _bytes_feature(image),\n            'species': _int64_feature(species),\n            'individual_id': _int64_feature(individual_id),\n        }\n    else:\n        feature = {\n            'image_id': _bytes_feature(image_id),\n            'image': _bytes_feature(image),\n        }\n    example_proto = tf.train.Example(features = tf.train.Features(feature = feature))\n    return example_proto.SerializeToString()\n\n\n# Read train set\ntrain = pd.read_csv('../input/happy-whale-and-dolphin/train.csv')\ntrain.species.replace({\"globis\": \"short_finned_pilot_whale\",\n                       \"pilot_whale\": \"short_finned_pilot_whale\",\n                       \"kiler_whale\": \"killer_whale\",\n                       \"bottlenose_dolpin\": \"bottlenose_dolphin\"}, inplace = True)\n# Use encoders to label encode species and indivual_ids\nspecies_encoder = LabelEncoder()\ntrain['species_encode'] = species_encoder.fit_transform(train['species'])\nindividual_id_encoder = LabelEncoder()\ntrain['individual_id_encode'] = individual_id_encoder.fit_transform(train['individual_id'])\n# Start stratifiedkfold strategy\nkfold = StratifiedKFold(n_splits = FOLDS, shuffle = True, random_state = SEED)\n# Add folds to csv file\nfor fold, (trn_ind, val_ind) in enumerate(kfold.split(train, train['species'])):\n    train.loc[val_ind, 'fold'] = fold\ntrain['fold'] = train['fold'].astype(int)\nnumber_of_species = train['species_encode'].nunique()\nnumber_of_individual_id = train['individual_id_encode'].nunique()\nprint(f'We have {number_of_species} unique species and {number_of_individual_id} unique individuals')\n\n# Add detic (object detection) bounding boxes\ndetic_train_df = pd.read_csv('../input/whale2-cropped-dataset/train2.csv')\ndetic_test_df = pd.read_csv('../input/whale2-cropped-dataset/test2.csv')\ndetic_train_df.loc[detic_train_df.box.isna(), 'box'] = ''\ndetic_test_df.loc[detic_test_df.box.isna(), 'box'] = ''\ntrain = train.merge(detic_train_df[['image', 'box']], how = 'left', on = 'image')\n# Read test file\ntest = pd.read_csv('../input/happy-whale-and-dolphin/sample_submission.csv')\ntest = test.merge(detic_test_df[['image', 'box']], how = 'left', on = 'image')\n# Any null value ('') will be -1\ntrain.loc[train.box == '', 'box'] = '-1 -1 -1 -1'\ntest.loc[test.box == '', 'box'] = '-1 -1 -1 -1'\n# Save new csv file with encoded classes for mapping\ntrain.to_csv(f'/tmp/{DATASET_NAME}/train_encoded.csv', index = False)\n\ndef create_train_tfrec(fold):\n    train_ = train[train['fold'] == fold]\n    with tf.io.TFRecordWriter(f'/tmp/{DATASET_NAME}/train-{fold}-{train_.shape[0]}.tfrec') as writer:\n        for k in range(train_.shape[0]):\n            row = train_.iloc[k]\n            image_id = row['image']\n            box = list(read_bbox(row['box']))\n            image = cv2.imread('../input/happy-whale-and-dolphin/train_images/' + row['image'])\n            if box is not None and box[0] != -1:\n                left, bottom, right, top = box[0], box[1], box[2], box[3]\n                image = image[bottom:top, left:right]\n            image = cv2.resize(image, IMAGE_SIZE)\n            image = cv2.imencode('.jpg', image, (cv2.IMWRITE_JPEG_QUALITY, 100))[1].tobytes()\n            species = row['species_encode']\n            individual_id = row['individual_id_encode']\n            example = serialize_example(str.encode(image_id), image, species, individual_id, train = True)\n            writer.write(example)\n                \ndef create_test_tfrec(fold):\n    i = fold * 1000\n    test_ = test.iloc[i:i+1000]\n    with tf.io.TFRecordWriter(f'/tmp/{DATASET_NAME}/test-{fold}-{test_.shape[0]}.tfrec') as writer:\n        for k in range(len(test_)):\n            row = test_.iloc[k]\n            image_id = row['image']\n            box = list(read_bbox(row['box']))\n            image = cv2.imread('../input/happy-whale-and-dolphin/test_images/' + row['image'])\n            if box is not None and box[0] != -1:\n                left, bottom, right, top = box[0], box[1], box[2], box[3]\n                image = image[bottom:top, left:right]\n            image = cv2.resize(image, IMAGE_SIZE)\n            image = cv2.imencode('.jpg', image, (cv2.IMWRITE_JPEG_QUALITY, 100))[1].tobytes()\n            example = serialize_example(str.encode(image_id), image, None, None, train = False)\n            writer.write(example)\n                \n                \n_ = joblib.Parallel(n_jobs=8)(joblib.delayed(create_train_tfrec)(fold) for fold in tqdm(range(FOLDS))\n)\n\n_ = joblib.Parallel(n_jobs=8)(joblib.delayed(create_test_tfrec)(fold) for fold in tqdm(range(TEST_FOLDS))\n)\nversion_name = datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n!kaggle datasets version -m {version_name} -p /tmp/{DATASET_NAME} -r zip -q","metadata":{"execution":{"iopub.status.busy":"2022-02-22T17:40:53.102483Z","iopub.execute_input":"2022-02-22T17:40:53.104488Z"},"trusted":true},"execution_count":null,"outputs":[]}]}