|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906 |
- {
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Hamming loss"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import pandas as pd\n",
- "from io import StringIO\n",
- "from sklearn.metrics import hamming_loss"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "def hammingLoss(y_true, y_pred):\n",
- " \"\"\"\n",
- " Computes the hamming loss. Used for multiclass and multilabel classification.\n",
- " \"\"\"\n",
- " from sklearn import preprocessing\n",
- " from sklearn.metrics import hamming_loss\n",
- " import numpy as np\n",
- " from itertools import chain\n",
- "\n",
- " def to_2d_array(df):\n",
- " MULTI_CLASS_CONDITION=True\n",
- " _dict = {}\n",
- " for [index,value] in df.as_matrix():\n",
- " if index in _dict.keys():\n",
- " _dict[index].append(value)\n",
- " MULTI_CLASS_CONDITION = False\n",
- " else:\n",
- " _dict[index]=[value]\n",
- " return list(_dict.keys()), list(_dict.values()), MULTI_CLASS_CONDITION\n",
- " \n",
- " (y_true_keys, y_true_mat, b_multiclass) = to_2d_array(y_true)\n",
- " (y_pred_keys, y_pred_mat, b_multiclass) = to_2d_array(y_pred)\n",
- " \n",
- " assert y_true_keys==y_pred_keys\n",
- " \n",
- " if b_multiclass:\n",
- "# print('this is a multiclass case')\n",
- " y_true_label_encoded = np.array(y_true_mat).ravel()\n",
- " y_pred_label_encoded = np.array(y_pred_mat).ravel()\n",
- " else: # MULTI_LABEL_CONDITION\n",
- "# print('this is a multilabel case')\n",
- " y_true_classes=(set(list(chain.from_iterable(y_true_mat))))\n",
- " y_pred_classes=(set(list(chain.from_iterable(y_pred_mat))))\n",
- " all_classes = list(y_true_classes.union(y_pred_classes))\n",
- " lb = preprocessing.MultiLabelBinarizer(classes=all_classes)\n",
- " y_true_label_encoded = lb.fit_transform(y_true_mat)\n",
- " y_pred_label_encoded = lb.transform(y_pred_mat)\n",
- " return hamming_loss(y_true_label_encoded, y_pred_label_encoded)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.26666666666666666"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 1: MultiLabel, typical\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,happy-pleased\n",
- "3,relaxing-calm\n",
- "7,amazed-suprised\n",
- "7,happy-pleased\n",
- "13,quiet-still\n",
- "13,sad-lonely\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,happy-pleased\n",
- "3,sad-lonely\n",
- "7,amazed-suprised\n",
- "7,happy-pleased\n",
- "13,quiet-still\n",
- "13,happy-pleased\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.0"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 2: MultiLabel, Zero loss\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,happy-pleased\n",
- "3,relaxing-calm\n",
- "7,amazed-suprised\n",
- "7,happy-pleased\n",
- "13,quiet-still\n",
- "13,sad-lonely\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,happy-pleased\n",
- "3,relaxing-calm\n",
- "7,amazed-suprised\n",
- "7,happy-pleased\n",
- "13,quiet-still\n",
- "13,sad-lonely\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "1.0"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 3: MultiLabel, Complete loss\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,happy-pleased\n",
- "3,relaxing-calm\n",
- "7,amazed-suprised\n",
- "7,happy-pleased\n",
- "13,quiet-still\n",
- "13,sad-lonely\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,class_label\n",
- "3,ecstatic\n",
- "3,sad-lonely\n",
- "3,quiet-still\n",
- "3,amazed-suprised\n",
- "7,ecstatic\n",
- "7,sad-lonely\n",
- "7,relaxing-calm\n",
- "7,quiet-still\n",
- "13,ecstatic\n",
- "13,happy-pleased\n",
- "13,relaxing-calm\n",
- "13,amazed-suprised\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.2"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 4: Multiclass, Typical\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,versicolor\n",
- "2,versicolor\n",
- "16,virginica\n",
- "17,setosa\n",
- "22,versicolor\n",
- "26,versicolor\n",
- "30,versicolor\n",
- "31,virginica\n",
- "33,versicolor\n",
- "37,virginica\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,setosa\n",
- "2,versicolor\n",
- "16,virginica\n",
- "17,setosa\n",
- "22,versicolor\n",
- "26,virginica\n",
- "30,versicolor\n",
- "31,virginica\n",
- "33,versicolor\n",
- "37,virginica\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.0"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 5: Multiclass, Zero loss\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,versicolor\n",
- "2,versicolor\n",
- "16,virginica\n",
- "17,setosa\n",
- "22,versicolor\n",
- "26,versicolor\n",
- "30,versicolor\n",
- "31,virginica\n",
- "33,versicolor\n",
- "37,virginica\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,versicolor\n",
- "2,versicolor\n",
- "16,virginica\n",
- "17,setosa\n",
- "22,versicolor\n",
- "26,versicolor\n",
- "30,versicolor\n",
- "31,virginica\n",
- "33,versicolor\n",
- "37,virginica\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:13: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- " del sys.path[0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "1.0"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Testcase 6: Multiclass, Complete loss\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,versicolor\n",
- "2,versicolor\n",
- "16,versicolor\n",
- "17,virginica\n",
- "22,versicolor\n",
- "26,versicolor\n",
- "30,versicolor\n",
- "31,virginica\n",
- "33,versicolor\n",
- "37,virginica\n",
- "\"\"\"))\n",
- "\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,species\n",
- "1,setosa\n",
- "2,setosa\n",
- "16,setosa\n",
- "17,setosa\n",
- "22,setosa\n",
- "26,setosa\n",
- "30,setosa\n",
- "31,setosa\n",
- "33,setosa\n",
- "37,setosa\n",
- "\"\"\"))\n",
- "\n",
- "hammingLoss(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# RMSE"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [],
- "source": [
- "def rootMeanSquaredError(y_true, y_pred):\n",
- " \"\"\"\n",
- " Computes the root mean squared error, for both univariate and multivariate case\n",
- " \"\"\"\n",
- " import numpy as np\n",
- " from sklearn.metrics import mean_squared_error\n",
- " from math import sqrt\n",
- " \n",
- " rmse = None\n",
- " \n",
- " # perform some checks\n",
- " assert 'd3mIndex' in y_true.columns\n",
- " assert 'd3mIndex' in y_pred.columns\n",
- " assert y_true.shape == y_pred.shape\n",
- " \n",
- " # preprocessing\n",
- " y_true.set_index('d3mIndex', inplace=True)\n",
- " y_pred.set_index('d3mIndex', inplace=True)\n",
- " \n",
- " # determine the dimension\n",
- " y_true_dim=y_true.shape[1]\n",
- " \n",
- " # univariate case\n",
- " if y_true_dim == 1: \n",
- " y_true_array = y_true.as_matrix().ravel()\n",
- " y_pred_array = y_pred.as_matrix().ravel()\n",
- " mse = mean_squared_error(y_true, y_pred)\n",
- " rmse = sqrt(mse)\n",
- " \n",
- " # multivariate case\n",
- " elif y_true_dim > 1:\n",
- " y_true_array = y_true.as_matrix()\n",
- " y_pred_array = y_pred.as_matrix()\n",
- " mse = mean_squared_error(y_true_array, y_pred_array, multioutput='uniform_average')\n",
- " rmse = sqrt(mse)\n",
- " \n",
- " return rmse"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:25: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:26: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.8381527307120105"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# test case 1\n",
- "# y_true_uni=[3, -1., 2, 7]\n",
- "# y_pred_uni=[2.1, 0.0, 2, 8]\n",
- "# expected rmse = 0.8381527307120105\n",
- "\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,value\n",
- "1,3\n",
- "2,-1.0\n",
- "16,2\n",
- "17,7\n",
- "\"\"\"))\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,value\n",
- "1,2.1\n",
- "2,0.0\n",
- "16,2\n",
- "17,8\n",
- "\"\"\"))\n",
- "rootMeanSquaredError(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:32: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n",
- "/home/svattam/miniconda3/envs/automl/lib/python3.6/site-packages/ipykernel_launcher.py:33: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "0.8416254115301732"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# test case 2\n",
- "# y_true_multi=[[0.5, 1],[-1, 1],[7, -6]]\n",
- "# y_pred_multi=[[0, 2],[-1, 2],[8, -5]]\n",
- "# expected rmse = 0.8416254115301732\n",
- "\n",
- "y_true = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,value1, value2\n",
- "1,0.5,1\n",
- "2,-1,1\n",
- "16,7,-6\n",
- "\"\"\"))\n",
- "y_pred = pd.read_csv(StringIO(\"\"\"\n",
- "d3mIndex,value1,value2\n",
- "1,0,2\n",
- "2,-1,2\n",
- "16,8,-5\n",
- "\"\"\"))\n",
- "rootMeanSquaredError(y_true, y_pred)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Object detection average precision"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "TEST CASE 1 --- AP: 0.6666666666666666\n",
- "TEST CASE 2 --- AP: 0.125\n",
- "TEST CASE 3 --- AP: 0.4444444444444444\n",
- "TEST CASE 4 --- AP: 0.4444444444444444\n"
- ]
- }
- ],
- "source": [
- "def group_gt_boxes_by_image_name(gt_boxes):\n",
- " gt_dict: typing.Dict = {}\n",
- "\n",
- " for box in gt_boxes:\n",
- " image_name = box[0]\n",
- " bounding_polygon = box[1:]\n",
- " bbox = convert_bouding_polygon_to_box_coords(bounding_polygon)\n",
- "\n",
- " if image_name not in gt_dict.keys():\n",
- " gt_dict[image_name] = []\n",
- "\n",
- " gt_dict[image_name].append({'bbox': bbox})\n",
- "\n",
- " return gt_dict\n",
- "\n",
- "\n",
- "def convert_bouding_polygon_to_box_coords(bounding_polygon):\n",
- " # box_coords = [x_min, y_min, x_max, y_max]\n",
- " box_coords = [bounding_polygon[0], bounding_polygon[1],\n",
- " bounding_polygon[4], bounding_polygon[5]]\n",
- " return box_coords\n",
- "\n",
- "\n",
- "def voc_ap(rec, prec):\n",
- " import numpy\n",
- "\n",
- " # First append sentinel values at the end.\n",
- " mrec = numpy.concatenate(([0.], rec, [1.]))\n",
- " mpre = numpy.concatenate(([0.], prec, [0.]))\n",
- "\n",
- " # Compute the precision envelope.\n",
- " for i in range(mpre.size - 1, 0, -1):\n",
- " mpre[i - 1] = numpy.maximum(mpre[i - 1], mpre[i])\n",
- "\n",
- " # To calculate area under PR curve, look for points\n",
- " # where X axis (recall) changes value.\n",
- " i = numpy.where(mrec[1:] != mrec[:-1])[0]\n",
- "\n",
- " # And sum (\\Delta recall) * prec.\n",
- " ap = numpy.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])\n",
- "\n",
- " return float(ap)\n",
- "\n",
- "\n",
- "def object_detection_average_precision(y_true, y_pred):\n",
- " \"\"\"\n",
- " This function takes a list of ground truth bounding polygons (rectangles in this case)\n",
- " and a list of detected bounding polygons (also rectangles) for a given class and\n",
- " computes the average precision of the detections with respect to the ground truth polygons.\n",
- " Parameters:\n",
- " -----------\n",
- " y_true: list\n",
- " List of ground truth polygons. Each polygon is represented as a list of\n",
- " vertices, starting in the upper-left corner going counter-clockwise.\n",
- " Since in this case, the polygons are rectangles, they will have the\n",
- " following format:\n",
- " [image_name, x_min, y_min, x_min, y_max, x_max, y_max, x_max, y_min].\n",
- " y_pred: list\n",
- " List of bounding box polygons with their corresponding confidence scores. Each\n",
- " polygon is represented as a list of vertices, starting in the upper-left corner\n",
- " going counter-clockwise. Since in this case, the polygons are rectangles, they\n",
- " will have the following format:\n",
- " [image_name, x_min, y_min, x_min, y_max, x_max, y_max, x_max, y_min, confidence_score].\n",
- " Returns:\n",
- " --------\n",
- " ap: float\n",
- " Average precision between detected polygons (rectangles) and the ground truth polylgons (rectangles).\n",
- " (it is also the area under the precision-recall curve).\n",
- " Example 1:\n",
- " >> predictions_list_1 = [['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 5, 10, 5, 20, 20, 20, 20, 10, 0.9],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6]]\n",
- " >> ground_truth_list_1 = [['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]]\n",
- " >> ap_1 = object_detection_average_precision(ground_truth_list_1, predictions_list_1)\n",
- " >> print(ap_1)\n",
- " 0.667\n",
- " Example 2:\n",
- " >> predictions_list_2 = [['img_00285.png', 330, 463, 330, 505, 387, 505, 387, 463, 0.0739],\n",
- " ['img_00285.png', 420, 433, 420, 498, 451, 498, 451, 433, 0.0910],\n",
- " ['img_00285.png', 328, 465, 328, 540, 403, 540, 403, 465, 0.1008],\n",
- " ['img_00285.png', 480, 477, 480, 522, 508, 522, 508, 477, 0.1012],\n",
- " ['img_00285.png', 357, 460, 357, 537, 417, 537, 417, 460, 0.1058],\n",
- " ['img_00285.png', 356, 456, 356, 521, 391, 521, 391, 456, 0.0843],\n",
- " ['img_00225.png', 345, 460, 345, 547, 415, 547, 415, 460, 0.0539],\n",
- " ['img_00225.png', 381, 362, 381, 513, 455, 513, 455, 362, 0.0542],\n",
- " ['img_00225.png', 382, 366, 382, 422, 416, 422, 416, 366, 0.0559],\n",
- " ['img_00225.png', 730, 463, 730, 583, 763, 583, 763, 463, 0.0588]]\n",
- " >> ground_truth_list_2 = [['img_00285.png', 480, 457, 480, 529, 515, 529, 515, 457],\n",
- " ['img_00285.png', 480, 457, 480, 529, 515, 529, 515, 457],\n",
- " ['img_00225.png', 522, 540, 522, 660, 576, 660, 576, 540],\n",
- " ['img_00225.png', 739, 460, 739, 545, 768, 545, 768, 460]]\n",
- " >> ap_2 = object_detection_average_precision(ground_truth_list_2, predictions_list_2)\n",
- " >> print(ap_2)\n",
- " 0.125\n",
- " Example 3:\n",
- " >> predictions_list_3 = [['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6],\n",
- " ['img_00002.png', 5, 8, 5, 16, 15, 16, 15, 8, 0.9],\n",
- " ['img_00002.png', 11, 12, 11, 18, 21, 18, 21, 12, 0.9]]\n",
- " >> ground_truth_list_3 = [['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]]\n",
- " >> ap_3 = object_detection_average_precision(ground_truth_list_3, predictions_list_3)\n",
- " >> print(ap_3)\n",
- " 0.444\n",
- " Example 4:\n",
- " (Same as example 3 except the last two box predictions in img_00002.png are switched)\n",
- " >> predictions_list_4 = [['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6],\n",
- " ['img_00002.png', 11, 12, 11, 18, 21, 18, 21, 12, 0.9],\n",
- " ['img_00002.png', 5, 8, 5, 16, 15, 16, 15, 8, 0.9]]\n",
- " >> ground_truth_list_4 = [['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]]\n",
- " >> ap_4 = object_detection_average_precision(ground_truth_list_4, predictions_list_4)\n",
- " >> print(ap_4)\n",
- " 0.444\n",
- " \"\"\"\n",
- "\n",
- " \"\"\"\n",
- " This function is different from others because ``y_true`` and ``y_pred`` are not vectors but arrays.\n",
- " \"\"\"\n",
- " import numpy\n",
- " ovthresh = 0.5\n",
- "\n",
- " # y_true = typing.cast(Truth, unvectorize(y_true))\n",
- " # y_pred = typing.cast(Predictions, unvectorize(y_pred))\n",
- "\n",
- " # Load ground truth.\n",
- " gt_dict = group_gt_boxes_by_image_name(y_true)\n",
- "\n",
- " # Extract gt objects for this class.\n",
- " recs = {}\n",
- " npos = 0\n",
- "\n",
- " imagenames = sorted(gt_dict.keys())\n",
- " for imagename in imagenames:\n",
- " Rlist = [obj for obj in gt_dict[imagename]]\n",
- " bbox = numpy.array([x['bbox'] for x in Rlist])\n",
- " det = [False] * len(Rlist)\n",
- " npos = npos + len(Rlist)\n",
- " recs[imagename] = {'bbox': bbox, 'det': det}\n",
- "\n",
- " # Load detections.\n",
- " det_length = len(y_pred[0])\n",
- "\n",
- " # Check that all boxes are the same size.\n",
- " for det in y_pred:\n",
- " assert len(det) == det_length, 'Not all boxes have the same dimensions.'\n",
- "\n",
- " image_ids = [x[0] for x in y_pred]\n",
- " BP = numpy.array([[float(z) for z in x[1:-1]] for x in y_pred])\n",
- " BB = numpy.array([convert_bouding_polygon_to_box_coords(x) for x in BP])\n",
- "\n",
- " confidence = numpy.array([float(x[-1]) for x in y_pred])\n",
- " boxes_w_confidences_list = numpy.hstack((BB, -1 * confidence[:, None]))\n",
- " boxes_w_confidences = numpy.empty((boxes_w_confidences_list.shape[0],),\n",
- " dtype=[('x_min', float), ('y_min', float),\n",
- " ('x_max', float), ('y_max', float),\n",
- " ('confidence', float)])\n",
- " boxes_w_confidences[:] = [tuple(i) for i in boxes_w_confidences_list]\n",
- "\n",
- " # Sort by confidence.\n",
- " #sorted_ind = numpy.argsort(-confidence)\n",
- " sorted_ind = numpy.argsort(\n",
- " boxes_w_confidences, kind='mergesort',\n",
- " order=('confidence', 'x_min', 'y_min'))\n",
- " BB = BB[sorted_ind, :]\n",
- " image_ids = [image_ids[x] for x in sorted_ind]\n",
- "\n",
- " # Go down y_pred and mark TPs and FPs.\n",
- " nd = len(image_ids)\n",
- " tp = numpy.zeros(nd)\n",
- " fp = numpy.zeros(nd)\n",
- " for d in range(nd):\n",
- " R = recs[image_ids[d]]\n",
- " bb = BB[d, :].astype(float)\n",
- " ovmax = -numpy.inf\n",
- " BBGT = R['bbox'].astype(float)\n",
- "\n",
- " if BBGT.size > 0:\n",
- " # Compute overlaps.\n",
- " # Intersection.\n",
- " ixmin = numpy.maximum(BBGT[:, 0], bb[0])\n",
- " iymin = numpy.maximum(BBGT[:, 1], bb[1])\n",
- " ixmax = numpy.minimum(BBGT[:, 2], bb[2])\n",
- " iymax = numpy.minimum(BBGT[:, 3], bb[3])\n",
- " iw = numpy.maximum(ixmax - ixmin + 1., 0.)\n",
- " ih = numpy.maximum(iymax - iymin + 1., 0.)\n",
- " inters = iw * ih\n",
- "\n",
- " # Union.\n",
- " uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) +\n",
- " (BBGT[:, 2] - BBGT[:, 0] + 1.) *\n",
- " (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters)\n",
- "\n",
- " overlaps = inters / uni\n",
- " ovmax = numpy.max(overlaps)\n",
- " jmax = numpy.argmax(overlaps)\n",
- "\n",
- " if ovmax > ovthresh:\n",
- " if not R['det'][jmax]:\n",
- " tp[d] = 1.\n",
- " R['det'][jmax] = 1\n",
- " else:\n",
- " fp[d] = 1.\n",
- " else:\n",
- " fp[d] = 1.\n",
- "\n",
- " # Compute precision recall.\n",
- " fp = numpy.cumsum(fp)\n",
- " tp = numpy.cumsum(tp)\n",
- " rec = tp / float(npos)\n",
- " # Avoid divide by zero in case the first detection matches a difficult ground truth.\n",
- " prec = tp / numpy.maximum(tp + fp, numpy.finfo(numpy.float64).eps)\n",
- " ap = voc_ap(rec, prec)\n",
- "\n",
- " return ap\n",
- "\n",
- "\n",
- "if __name__ == \"__main__\":\n",
- " predictions_list_1 = [\n",
- " ['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 5, 10, 5, 20, 20, 20, 20, 10, 0.9],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6]\n",
- " ]\n",
- " ground_truth_list_1 = [\n",
- " ['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]\n",
- " ]\n",
- " ap_1 = object_detection_average_precision(\n",
- " ground_truth_list_1, predictions_list_1)\n",
- " print('TEST CASE 1 --- AP: ', ap_1)\n",
- "\n",
- " predictions_list_2 = [\n",
- " ['img_00285.png', 330, 463, 330, 505, 387, 505, 387, 463, 0.0739],\n",
- " ['img_00285.png', 420, 433, 420, 498, 451, 498, 451, 433, 0.0910],\n",
- " ['img_00285.png', 328, 465, 328, 540, 403, 540, 403, 465, 0.1008],\n",
- " ['img_00285.png', 480, 477, 480, 522, 508, 522, 508, 477, 0.1012],\n",
- " ['img_00285.png', 357, 460, 357, 537, 417, 537, 417, 460, 0.1058],\n",
- " ['img_00285.png', 356, 456, 356, 521, 391, 521, 391, 456, 0.0843],\n",
- " ['img_00225.png', 345, 460, 345, 547, 415, 547, 415, 460, 0.0539],\n",
- " ['img_00225.png', 381, 362, 381, 513, 455, 513, 455, 362, 0.0542],\n",
- " ['img_00225.png', 382, 366, 382, 422, 416, 422, 416, 366, 0.0559],\n",
- " ['img_00225.png', 730, 463, 730, 583, 763, 583, 763, 463, 0.0588],\n",
- " ]\n",
- " ground_truth_list_2 = [\n",
- " ['img_00285.png', 480, 457, 480, 529, 515, 529, 515, 457],\n",
- " ['img_00285.png', 480, 457, 480, 529, 515, 529, 515, 457],\n",
- " ['img_00225.png', 522, 540, 522, 660, 576, 660, 576, 540],\n",
- " ['img_00225.png', 739, 460, 739, 545, 768, 545, 768, 460],\n",
- " ]\n",
- " ap_2 = object_detection_average_precision(\n",
- " ground_truth_list_2, predictions_list_2)\n",
- " print('TEST CASE 2 --- AP: ', ap_2)\n",
- "\n",
- " predictions_list_3 = [\n",
- " ['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6],\n",
- " ['img_00002.png', 5, 8, 5, 16, 15, 16, 15, 8, 0.9],\n",
- " ['img_00002.png', 11, 12, 11, 18, 21, 18, 21, 12, 0.9]\n",
- " ]\n",
- " ground_truth_list_3 = [\n",
- " ['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]\n",
- " ]\n",
- " ap_3 = object_detection_average_precision(\n",
- " ground_truth_list_3, predictions_list_3)\n",
- " print('TEST CASE 3 --- AP: ', ap_3)\n",
- "\n",
- " predictions_list_4 = [\n",
- " ['img_00001.png', 110, 110, 110, 210, 210, 210, 210, 110, 0.6],\n",
- " ['img_00002.png', 120, 130, 120, 200, 200, 200, 200, 130, 0.6],\n",
- " ['img_00002.png', 11, 12, 11, 18, 21, 18, 21, 12, 0.9],\n",
- " ['img_00002.png', 5, 8, 5, 16, 15, 16, 15, 8, 0.9]\n",
- " ]\n",
- " ground_truth_list_4 = [\n",
- " ['img_00001.png', 100, 100, 100, 200, 200, 200, 200, 100],\n",
- " ['img_00002.png', 10, 10, 10, 20, 20, 20, 20, 10],\n",
- " ['img_00002.png', 70, 80, 70, 150, 140, 150, 140, 80]\n",
- " ]\n",
- " ap_4 = object_detection_average_precision(\n",
- " ground_truth_list_4, predictions_list_4)\n",
- " print('TEST CASE 4 --- AP: ', ap_4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.6.5"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
- }
|