{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":15768,"databundleVersionId":700263,"sourceType":"competition"}],"dockerImageVersionId":29271,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"This is certainly an interesting and challenging competition.\n![gif](https://raw.githubusercontent.com/lyft/nuscenes-devkit/master/notebooks/media/001.gif)\nLets take a look at the 85GB unique dataset!\n\n\n\n**Disclaimer: I do not know anything about 3D object detection nor about Autonomous Vehicles. \nThe notebook is provided \"as is\", without warranty of any kind... :)**","metadata":{}},{"cell_type":"code","source":"%matplotlib inline\nimport os\nimport pandas as pd\nimport datetime as dt\nimport numpy as np\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\nimport datetime as dt\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.offline as py\npy.init_notebook_mode(connected=True)\nimport plotly.graph_objs as go\nimport plotly.figure_factory as ff\nimport warnings","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-05T01:45:27.389692Z","iopub.execute_input":"2024-06-05T01:45:27.390049Z","iopub.status.idle":"2024-06-05T01:45:31.224890Z","shell.execute_reply.started":"2024-06-05T01:45:27.389985Z","shell.execute_reply":"2024-06-05T01:45:31.223653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.rcParams['figure.figsize'] = [16, 10]\nplt.rcParams['font.size'] = 14\nwarnings.filterwarnings('ignore')\npd.options.display.max_columns = 99\nsns.set_palette(sns.color_palette('tab20', 20))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-06-05T01:45:45.453692Z","iopub.execute_input":"2024-06-05T01:45:45.454386Z","iopub.status.idle":"2024-06-05T01:45:45.466886Z","shell.execute_reply.started":"2024-06-05T01:45:45.454313Z","shell.execute_reply":"2024-06-05T01:45:45.465487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"start = dt.datetime.now()","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2024-06-05T01:45:57.069113Z","iopub.execute_input":"2024-06-05T01:45:57.069512Z","iopub.status.idle":"2024-06-05T01:45:57.074887Z","shell.execute_reply.started":"2024-06-05T01:45:57.069448Z","shell.execute_reply":"2024-06-05T01:45:57.073643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base = '/kaggle/input/3d-object-detection-for-autonomous-vehicles/'\ndirs = os.listdir(base)\nprint(dirs)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:46:09.307311Z","iopub.execute_input":"2024-06-05T01:46:09.307662Z","iopub.status.idle":"2024-06-05T01:46:09.315080Z","shell.execute_reply.started":"2024-06-05T01:46:09.307612Z","shell.execute_reply":"2024-06-05T01:46:09.314236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Unique ground truth and submission format\nWe are required to optimize a custom performance metric, the mean average precision[](http://) at different intersection over union (IoU) thresholds.","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(base + 'train.csv')\nsample_submission = pd.read_csv(base + 'sample_submission.csv')\nprint(f'train: {train.shape}, sample submission: {sample_submission.shape}')\ntrain.head(2)\nsample_submission.head(2)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:47:15.408723Z","iopub.execute_input":"2024-06-05T01:47:15.409087Z","iopub.status.idle":"2024-06-05T01:47:17.145803Z","shell.execute_reply.started":"2024-06-05T01:47:15.409025Z","shell.execute_reply":"2024-06-05T01:47:17.144734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The annotations in train.csv have the following components:\n* **center_x**, **center_y** and **center_z** are the world coordinates of the center of the 3D bounding volume.\n* **width**, **length** and **height** are the dimensions of the volume.\n* **yaw** is the angle of the volume around the z axis (where y is forward/back, x is left/right, and z is up/down - making 'yaw' the direction the front of the vehicle / bounding box is pointing at while on the ground).\n* **class_name** is the type of object contained by the bounding volume.\n\n\n**We have 638K annotated objects in 22K train samples.**","metadata":{}},{"cell_type":"code","source":"# Let's check the parsing of prediction strings. Each object should have 8 params\nmax([len(ps.split(' ')) % 8 for ps in train.PredictionString.values])","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:49:32.783545Z","iopub.execute_input":"2024-06-05T01:49:32.783890Z","iopub.status.idle":"2024-06-05T01:49:33.062295Z","shell.execute_reply.started":"2024-06-05T01:49:32.783843Z","shell.execute_reply":"2024-06-05T01:49:33.061382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"object_columns = ['sample_id', 'object_id', 'center_x', 'center_y', 'center_z',\n                  'width', 'length', 'height', 'yaw', 'class_name']\nobjects = []\nfor sample_id, ps in tqdm(train.values[:]):\n    object_params = ps.split()\n    n_objects = len(object_params)\n    for i in range(n_objects // 8):\n        x, y, z, w, l, h, yaw, c = tuple(object_params[i * 8: (i + 1) * 8])\n        objects.append([sample_id, i, x, y, z, w, l, h, yaw, c])\ntrain_objects = pd.DataFrame(\n    objects,\n    columns = object_columns\n)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:50:29.616444Z","iopub.execute_input":"2024-06-05T01:50:29.616771Z","iopub.status.idle":"2024-06-05T01:50:33.360729Z","shell.execute_reply.started":"2024-06-05T01:50:29.616724Z","shell.execute_reply":"2024-06-05T01:50:33.359842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in object_columns[2:-1]:\n    train_objects[col] = train_objects[col].astype('float')\ntrain_objects['confidence'] = 1.0","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:51:05.696555Z","iopub.execute_input":"2024-06-05T01:51:05.696883Z","iopub.status.idle":"2024-06-05T01:51:07.587591Z","shell.execute_reply.started":"2024-06-05T01:51:05.696836Z","shell.execute_reply":"2024-06-05T01:51:07.586638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_objects.groupby('sample_id').count()[['object_id']].hist()\nplt.title('Number of objects per sample')\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:51:28.163288Z","iopub.execute_input":"2024-06-05T01:51:28.163642Z","iopub.status.idle":"2024-06-05T01:51:28.885723Z","shell.execute_reply.started":"2024-06-05T01:51:28.163590Z","shell.execute_reply":"2024-06-05T01:51:28.884546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_objects.shape\ntrain_objects.head()\ntrain_objects.describe()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:52:36.867109Z","iopub.execute_input":"2024-06-05T01:52:36.867517Z","iopub.status.idle":"2024-06-05T01:52:37.134645Z","shell.execute_reply.started":"2024-06-05T01:52:36.867460Z","shell.execute_reply":"2024-06-05T01:52:37.133542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n### Object annotations","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(ncols=3)\nsns.distplot(train_objects.center_x, ax = ax[0])\nsns.distplot(train_objects.center_y, ax = ax[1])\nsns.distplot(train_objects.center_z, ax = ax[2])\nplt.suptitle('X, y, z coord distribution')\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:53:33.543735Z","iopub.execute_input":"2024-06-05T01:53:33.544050Z","iopub.status.idle":"2024-06-05T01:53:35.408108Z","shell.execute_reply.started":"2024-06-05T01:53:33.544003Z","shell.execute_reply":"2024-06-05T01:53:35.407107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(ncols=3)\nsns.distplot(train_objects.width, ax = ax[0])\nsns.distplot(train_objects.length, ax = ax[1])\nsns.distplot(train_objects.height, ax = ax[2])\nplt.suptitle('Width, length, height distribution')\nplt.show();","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:55:20.427077Z","iopub.execute_input":"2024-06-05T01:55:20.427460Z","iopub.status.idle":"2024-06-05T01:55:22.123412Z","shell.execute_reply.started":"2024-06-05T01:55:20.427406Z","shell.execute_reply":"2024-06-05T01:55:22.122507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Classes\n\nVast majority of the annotated objects is just car. We have other vehicles and pedestrians to detect.","metadata":{}},{"cell_type":"code","source":"class_cnt = train_objects.groupby('class_name').count()[['object_id']].sort_values(by='object_id', ascending=False).reset_index()\nclass_cnt['p'] = class_cnt.object_id / class_cnt.object_id.sum() \nclass_cnt","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:56:08.625768Z","iopub.execute_input":"2024-06-05T01:56:08.626106Z","iopub.status.idle":"2024-06-05T01:56:08.861021Z","shell.execute_reply.started":"2024-06-05T01:56:08.626053Z","shell.execute_reply":"2024-06-05T01:56:08.860065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_objects.groupby('class_name').mean()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:56:29.237147Z","iopub.execute_input":"2024-06-05T01:56:29.237543Z","iopub.status.idle":"2024-06-05T01:56:29.407421Z","shell.execute_reply.started":"2024-06-05T01:56:29.237488Z","shell.execute_reply":"2024-06-05T01:56:29.406447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Sample submission","metadata":{}},{"cell_type":"code","source":"x, y, z, w, l, h, yaw = train_objects[[\n    'center_x', 'center_y', 'center_z', 'width', 'length', 'height', 'yaw']].mean()\nmean_prediction_string = ' '.join(map(str, [0.9, x, y, z, 10*w, 10*l, h, yaw, 'car']))\n","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:57:18.195216Z","iopub.execute_input":"2024-06-05T01:57:18.195609Z","iopub.status.idle":"2024-06-05T01:57:18.251740Z","shell.execute_reply.started":"2024-06-05T01:57:18.195548Z","shell.execute_reply":"2024-06-05T01:57:18.250624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission['PredictionString'] = mean_prediction_string \nsample_submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:57:30.140691Z","iopub.execute_input":"2024-06-05T01:57:30.141040Z","iopub.status.idle":"2024-06-05T01:57:32.395433Z","shell.execute_reply.started":"2024-06-05T01:57:30.140984Z","shell.execute_reply":"2024-06-05T01:57:32.394319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission.shape\nsample_submission.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:57:41.116092Z","iopub.execute_input":"2024-06-05T01:57:41.116493Z","iopub.status.idle":"2024-06-05T01:57:41.144948Z","shell.execute_reply.started":"2024-06-05T01:57:41.116424Z","shell.execute_reply":"2024-06-05T01:57:41.144047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train data","metadata":{}},{"cell_type":"code","source":"for f in os.listdir(base + 'train_data'):\n    print(f)\n    try:\n        df = pd.read_json(base + 'train_data/' + f)\n        df.shape\n        df.head()\n        df.nunique()\n    except Exception as e:\n        print(e)","metadata":{"execution":{"iopub.status.busy":"2024-06-05T01:58:36.818922Z","iopub.execute_input":"2024-06-05T01:58:36.819342Z","iopub.status.idle":"2024-06-05T01:59:10.538460Z","shell.execute_reply.started":"2024-06-05T01:58:36.819259Z","shell.execute_reply":"2024-06-05T01:59:10.537191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# References\n[1] https://github.com/lyft/nuscenes-devkit","metadata":{}},{"cell_type":"code","source":"end = dt.datetime.now()\nprint('Latest run {}.\\nTotal time {}s'.format(end, (end - start).seconds))","metadata":{"execution":{"iopub.status.busy":"2024-06-05T02:02:13.176268Z","iopub.execute_input":"2024-06-05T02:02:13.176645Z","iopub.status.idle":"2024-06-05T02:02:13.182226Z","shell.execute_reply.started":"2024-06-05T02:02:13.176593Z","shell.execute_reply":"2024-06-05T02:02:13.181143Z"},"trusted":true},"execution_count":null,"outputs":[]}]}