diff --git a/.gitignore b/.gitignore index f417c17..abb3de6 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,4 @@ out-img/ converted_models/ *.pth *.onnx +.devcontainer diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..8d6614d --- /dev/null +++ b/README2.md @@ -0,0 +1,20 @@ +# Spoter Embeddings + +## Creating dataset +First, make a folder where all you're videos are located. When this is done, all keypoints can be extracted from the videos using the following command. This will extract the keypoints and store them in \. +``` +python3 preprocessing.py extract --videos-folder --output-landmark +``` + +When this is done, the dataset can be created using the following command: +``` +python3 preprocessing.py create --landmarks-dataset --videos-folder --dataset-folder (--create-new-split --test-size ) +``` +The above command generates a train (and val) csv file which includes all the extracted keypoints. These can then be used to train or generates embeddings. + +## Creating Embeddings +The embeddings can be created using the following command: +``` +python3 export_embeddings.py --checkpoint --dataset --output +``` +The command above generates the embeddings for a given dataset and saves them as a csv file. \ No newline at end of file diff --git a/checkpoints/checkpoint_embed_3006.pth b/checkpoints/checkpoint_embed_3006.pth new file mode 100644 index 0000000..7123eca Binary files /dev/null and b/checkpoints/checkpoint_embed_3006.pth differ diff --git a/checkpoints/checkpoint_embed_3835.pth b/checkpoints/checkpoint_embed_3835.pth new file mode 100644 index 0000000..d3195e2 Binary files /dev/null and b/checkpoints/checkpoint_embed_3835.pth differ diff --git a/embeddings/basic-signs/embeddings-online-dict.csv b/embeddings/basic-signs/embeddings-online-dict.csv new file mode 100644 index 0000000..2b86d35 --- /dev/null +++ b/embeddings/basic-signs/embeddings-online-dict.csv @@ -0,0 +1,91 @@ +embeddings,label_name,labels,embeddings2 +"[[ 0.01295076 -0.1074132 0.5111911 0.08452003 -0.7638924 0.6458221 + -1.3892679 -1.1791427 -0.30736607 -0.41543546 -0.6358013 0.31411174 + 0.878936 1.7265923 -0.09298562 0.12005516 0.26995468 -1.5934305 + -0.12619524 0.9111336 0.91827893 0.5948979 0.90334046 -0.84089845 + -0.29575598 -0.3024254 -0.03074584 1.4402957 -0.22309914 0.54750854 + -0.68767273 -0.0665718 ]]",BEDANKEN,0,"[0.012950755655765533, -0.10741320252418518, 0.5111911296844482, 0.08452003449201584, -0.763892412185669, 0.6458221077919006, -1.389267921447754, -1.179142713546753, -0.3073660731315613, -0.41543546319007874, -0.6358013153076172, 0.31411173939704895, 0.8789359927177429, 1.7265923023223877, -0.0929856151342392, 0.12005516141653061, 0.2699546813964844, -1.593430519104004, -0.12619523704051971, 0.9111335873603821, 0.9182789325714111, 0.5948979258537292, 0.9033404588699341, -0.8408984541893005, -0.2957559823989868, -0.30242541432380676, -0.030745841562747955, 1.440295696258545, -0.22309914231300354, 0.5475085377693176, -0.6876727342605591, -0.06657180190086365]" +"[[ 1.0287632 -0.94657993 0.7852507 -0.37169546 0.3614158 0.5360078 + -0.9989285 -0.24402924 -0.47437504 -0.17307773 0.9196662 0.5362411 + -0.50366765 0.7600024 0.6701926 -0.5288625 -0.38939306 -1.0722619 + -1.33836 1.331829 -0.6958481 0.57767504 0.87002045 -0.59203666 + -0.57576096 0.70008135 0.8224436 -0.32370126 0.5276206 -0.62150276 + -0.9639951 -0.40879178]]",GOED,1,"[1.0287631750106812, -0.9465799331665039, 0.785250723361969, -0.37169545888900757, 0.3614158034324646, 0.536007821559906, -0.9989284873008728, -0.244029238820076, -0.47437503933906555, -0.17307773232460022, 0.9196661710739136, 0.5362411141395569, -0.5036676526069641, 0.7600023746490479, 0.6701925992965698, -0.528862476348877, -0.38939306139945984, -1.072261929512024, -1.3383599519729614, 1.3318289518356323, -0.6958481073379517, 0.5776750445365906, 0.8700204491615295, -0.5920366644859314, -0.5757609605789185, 0.7000813484191895, 0.8224436044692993, -0.32370126247406006, 0.5276206135749817, -0.6215027570724487, -0.963995099067688, -0.40879178047180176]" +"[[-0.5988377 -1.6454532 0.5696761 0.27801913 -0.39687645 1.5192578 + -0.57908726 -1.9851501 1.1918951 -1.3280408 0.27390718 0.71642965 + -1.0471189 0.9825219 -0.6625729 -0.28641602 2.0109527 -0.97667754 + -2.3978348 2.666861 0.15066166 -1.6922158 0.9681514 -1.1413386 + 0.08027886 -0.6215762 -0.09759905 0.6157277 -0.01341684 0.9806912 + -0.09793527 -1.9003383 ]]",GOEDEMIDDAG,2,"[-0.598837673664093, -1.6454532146453857, 0.5696761012077332, 0.27801913022994995, -0.3968764543533325, 1.5192577838897705, -0.5790872573852539, -1.9851500988006592, 1.1918951272964478, -1.3280408382415771, 0.2739071846008301, 0.7164296507835388, -1.047118902206421, 0.9825218915939331, -0.6625729203224182, -0.28641602396965027, 2.0109527111053467, -0.9766775369644165, -2.3978347778320312, 2.666861057281494, 0.1506616622209549, -1.6922158002853394, 0.9681513905525208, -1.141338586807251, 0.08027885854244232, -0.621576189994812, -0.09759905189275742, 0.6157277226448059, -0.013416841626167297, 0.9806911945343018, -0.0979352742433548, -1.9003382921218872]" +"[[-0.11578767 0.28371835 0.8604608 -0.31061298 -0.78153455 -0.24914108 + -2.443886 -0.3267159 0.29237527 -0.7879326 -0.12082034 0.32809633 + -1.0938975 0.7125962 0.49117383 -0.3119098 0.15369919 0.39569452 + -1.18983 1.2498406 -0.38752007 -0.54896545 -0.620718 0.02654967 + -0.10994279 -0.39713857 -0.18035033 -1.554728 0.12178666 -0.5698373 + 1.1097438 -1.2350351 ]]",GOEDEMORGEN,3,"[-0.11578767001628876, 0.2837183475494385, 0.8604608178138733, -0.3106129765510559, -0.7815345525741577, -0.24914108216762543, -2.4438860416412354, -0.326715886592865, 0.29237526655197144, -0.7879325747489929, -0.12082034349441528, 0.32809633016586304, -1.0938974618911743, 0.7125961780548096, 0.4911738336086273, -0.3119097948074341, 0.15369918942451477, 0.3956945240497589, -1.18982994556427, 1.2498406171798706, -0.38752007484436035, -0.5489654541015625, -0.6207180023193359, 0.02654966711997986, -0.10994279384613037, -0.3971385657787323, -0.18035033345222473, -1.5547280311584473, 0.12178666144609451, -0.5698372721672058, 1.1097438335418701, -1.2350350618362427]" +"[[-0.9557147 0.03368077 1.0923759 -0.41077584 -1.6992741 -0.59566665 + -1.1562454 0.8824008 -0.25122 0.625515 1.6720039 0.5639413 + -0.35894975 -0.05896414 0.84854823 0.4072139 -1.1763096 -1.5435666 + -1.5066593 0.66299886 -1.3121625 1.4410669 -0.6341419 -0.4873513 + 0.8113033 -0.01502099 0.32262453 2.5855515 -0.7294207 0.7582124 + -0.1386989 -0.17011487]]",GOEDENACHT,4,"[-0.9557147026062012, 0.03368076682090759, 1.0923758745193481, -0.4107758402824402, -1.6992740631103516, -0.5956666469573975, -1.1562453508377075, 0.8824008107185364, -0.2512199878692627, 0.6255149841308594, 1.6720038652420044, 0.5639412999153137, -0.35894975066185, -0.058964136987924576, 0.8485482335090637, 0.40721389651298523, -1.176309585571289, -1.5435665845870972, -1.5066592693328857, 0.6629988551139832, -1.3121625185012817, 1.441066861152649, -0.6341419219970703, -0.48735129833221436, 0.8113033175468445, -0.015020990744233131, 0.322624534368515, 2.5855515003204346, -0.7294207215309143, 0.7582123875617981, -0.13869890570640564, -0.17011487483978271]" +"[[ 0.13687058 -1.099074 1.1867181 -1.2216619 -0.965039 -0.6957289 + -1.6400954 0.7317837 0.5887569 0.18756844 1.4867041 0.63357025 + -1.5853169 0.4157976 0.76919526 0.08512082 -1.0937556 -0.07339763 + -2.8580015 1.6835626 -1.4538742 1.2302468 -0.49323368 -0.81243044 + -0.11378415 -0.09592562 0.31165385 -0.32617894 0.02981896 -0.01485211 + 1.1880591 -0.40726334]]",GOEDENAVOND,5,"[0.1368705779314041, -1.0990740060806274, 1.1867181062698364, -1.221661925315857, -0.9650390148162842, -0.6957288980484009, -1.6400953531265259, 0.7317836880683899, 0.5887569189071655, 0.18756844103336334, 1.4867041110992432, 0.6335702538490295, -1.5853168964385986, 0.4157975912094116, 0.7691952586174011, 0.08512081950902939, -1.0937556028366089, -0.07339762896299362, -2.858001470565796, 1.6835626363754272, -1.4538742303848267, 1.2302467823028564, -0.49323368072509766, -0.8124304413795471, -0.11378414928913116, -0.09592562168836594, 0.31165385246276855, -0.3261789381504059, 0.029818959534168243, -0.014852114021778107, 1.1880590915679932, -0.4072633385658264]" +"[[ 1.3673804 1.7083405 0.58775777 0.26056585 -0.29101595 -0.69954723 + 0.45681733 1.6908163 0.02684825 0.7537957 2.2054908 0.28831166 + -1.5712252 -1.6869793 0.8009781 -0.51264 -1.3544708 -0.72502786 + -0.31009498 -0.23777717 -1.7524906 1.6333568 1.5263942 0.22317217 + -0.40576094 2.2136266 1.4030526 -1.0599502 0.8686069 -1.1141618 + -0.01899157 -1.2256656 ]]",JA,6,"[1.3673803806304932, 1.7083405256271362, 0.5877577662467957, 0.260565847158432, -0.29101595282554626, -0.6995472311973572, 0.4568173289299011, 1.6908162832260132, 0.02684824913740158, 0.7537956833839417, 2.205490827560425, 0.2883116602897644, -1.5712251663208008, -1.6869792938232422, 0.8009781241416931, -0.5126399993896484, -1.3544708490371704, -0.725027859210968, -0.3100949823856354, -0.23777717351913452, -1.7524906396865845, 1.6333568096160889, 1.526394248008728, 0.2231721729040146, -0.4057609438896179, 2.2136266231536865, 1.403052568435669, -1.0599502325057983, 0.8686069250106812, -1.1141618490219116, -0.01899157091975212, -1.22566556930542]" +"[[ 1.8208723 -0.59625745 0.15060106 -0.23053254 1.0344827 1.7016335 + 0.1968202 -0.48188782 0.3004466 -0.53336793 0.89704275 0.26869062 + -1.0112952 0.0343281 0.32149622 -0.8189871 0.33571526 -0.57059044 + -0.7577773 1.4743904 -0.01735806 -0.4116615 2.3637483 -0.6602343 + -0.6101709 1.8139238 1.041902 -0.9006022 0.6082014 -0.23616463 + -0.62204087 -0.524899 ]]",LINKS,7,"[1.8208723068237305, -0.5962574481964111, 0.15060105919837952, -0.23053254187107086, 1.034482717514038, 1.7016334533691406, 0.1968201994895935, -0.4818878173828125, 0.30044659972190857, -0.533367931842804, 0.8970427513122559, 0.2686906158924103, -1.011295199394226, 0.034328099340200424, 0.32149621844291687, -0.8189870715141296, 0.33571526408195496, -0.5705904364585876, -0.7577772736549377, 1.4743903875350952, -0.01735806092619896, -0.4116615056991577, 2.36374831199646, -0.660234272480011, -0.6101709008216858, 1.8139238357543945, 1.04190194606781, -0.9006022214889526, 0.6082013845443726, -0.2361646294593811, -0.622040867805481, -0.5248990058898926]" +"[[ 1.3968729 2.340378 0.567814 0.5684975 -0.8795973 -1.0090083 + -0.01301649 1.9747832 -0.3257468 0.76960254 1.402801 0.39424965 + 0.06948688 -0.51904166 1.0961802 -0.34335235 -1.8730735 -1.0801809 + 0.2751789 -0.96998405 -1.9822828 2.1046805 1.3094746 0.5770473 + -0.19693638 1.8973799 0.99536693 0.2668684 0.28499565 -0.9838486 + -0.19578832 -0.46982569]]",NEE,8,"[1.396872878074646, 2.3403780460357666, 0.5678139925003052, 0.5684974789619446, -0.8795973062515259, -1.0090082883834839, -0.013016488403081894, 1.974783182144165, -0.3257468044757843, 0.7696025371551514, 1.4028010368347168, 0.39424964785575867, 0.06948687881231308, -0.5190416574478149, 1.0961802005767822, -0.343352347612381, -1.8730734586715698, -1.0801808834075928, 0.2751789093017578, -0.9699840545654297, -1.9822827577590942, 2.1046805381774902, 1.3094745874404907, 0.5770472884178162, -0.19693638384342194, 1.8973798751831055, 0.9953669309616089, 0.2668684124946594, 0.2849956452846527, -0.9838485717773438, -0.19578832387924194, -0.4698256850242615]" +"[[ 1.8143647 -0.9315294 0.28706568 -1.0938002 -0.2451038 0.42331484 + -0.31653756 0.00268575 0.89822304 1.0639151 1.7406261 1.1707302 + -1.6639041 0.30558044 0.22984704 -1.0260515 -0.08818819 -0.14696571 + -1.5269523 0.55015475 -0.12936743 0.93951946 1.3917109 -0.62517196 + -1.3869016 1.4833041 1.4647726 -1.0285482 -0.3704591 1.4672718 + 0.40315557 0.04754414]]",RECHTS,9,"[1.8143646717071533, -0.9315294027328491, 0.28706568479537964, -1.0938001871109009, -0.24510380625724792, 0.4233148396015167, -0.3165375590324402, 0.002685748040676117, 0.8982230424880981, 1.0639151334762573, 1.7406260967254639, 1.1707302331924438, -1.663904070854187, 0.3055804371833801, 0.2298470437526703, -1.0260515213012695, -0.08818819373846054, -0.14696571230888367, -1.5269522666931152, 0.5501547455787659, -0.1293674260377884, 0.939519464969635, 1.391710877418518, -0.625171959400177, -1.386901617050171, 1.4833041429519653, 1.4647725820541382, -1.028548240661621, -0.37045910954475403, 1.4672718048095703, 0.4031555652618408, 0.04754413664340973]" +"[[ 1.681777 -0.79441184 0.07110912 -0.01304399 1.110081 2.1115103 + -0.27283993 -1.5035654 0.55927217 -0.9903696 0.05718866 0.19891238 + -0.7289791 0.71738267 -0.41428873 -0.58389515 1.1087953 -0.6616588 + -0.6330258 1.5830203 0.60013187 -1.0640136 2.3917787 -0.70012283 + -0.7359694 0.9847692 0.94458187 -0.5915589 0.3662199 0.39359796 + -0.6499281 -0.30565363]]",SALUUT,10,"[1.681777000427246, -0.794411838054657, 0.07110912352800369, -0.013043994084000587, 1.1100809574127197, 2.1115102767944336, -0.2728399336338043, -1.5035654306411743, 0.5592721700668335, -0.9903696179389954, 0.05718865618109703, 0.1989123821258545, -0.7289791107177734, 0.7173826694488525, -0.414288729429245, -0.5838951468467712, 1.1087952852249146, -0.6616588234901428, -0.6330258250236511, 1.5830203294754028, 0.6001318693161011, -1.0640136003494263, 2.3917787075042725, -0.7001228332519531, -0.7359694242477417, 0.9847692251205444, 0.9445818662643433, -0.5915588736534119, 0.3662199079990387, 0.39359796047210693, -0.649928092956543, -0.3056536316871643]" +"[[ 0.56773967 -0.6260798 0.23771092 -0.10016712 0.86817515 0.92371875 + -0.16313902 -0.3785063 -0.41955388 -0.586288 -0.33712262 -0.07999519 + -0.98128295 0.18787864 -0.36432508 -0.06605241 0.00710656 -0.36359936 + -0.00642961 1.257384 0.64647824 -1.1618687 1.3707273 -0.46546304 + -0.14522405 0.29306158 0.41898865 -0.12311607 0.24604419 -0.48434448 + -0.79076517 0.753163 ]]",SLECHT,11,"[0.5677396655082703, -0.626079797744751, 0.23771092295646667, -0.10016711801290512, 0.8681751489639282, 0.9237187504768372, -0.16313901543617249, -0.37850630283355713, -0.41955387592315674, -0.5862879753112793, -0.3371226191520691, -0.07999519258737564, -0.9812829494476318, 0.18787863850593567, -0.36432507634162903, -0.06605241447687149, 0.007106557488441467, -0.36359935998916626, -0.006429608445614576, 1.257383942604065, 0.6464782357215881, -1.161868691444397, 1.370727300643921, -0.4654630422592163, -0.14522404968738556, 0.29306158423423767, 0.4189886450767517, -0.12311606854200363, 0.24604418873786926, -0.484344482421875, -0.7907651662826538, 0.7531629800796509]" +"[[ 0.9251696 -2.8536968 0.6521715 -1.8256427 0.44136596 0.33299872 + -1.4674346 -0.7897836 0.47153538 0.1437631 0.7396151 1.0851275 + -1.2100328 1.626544 0.69652647 0.0048107 0.13927785 -0.63199776 + -3.0121155 2.1738136 -0.7935879 0.2744053 0.281097 -1.0899199 + -0.7062637 -0.04824958 0.3436054 -0.69366074 0.22799876 0.8932708 + 0.51823634 -0.08065546]]",SMAKELIJK,12,"[0.9251695871353149, -2.853696823120117, 0.6521714925765991, -1.825642704963684, 0.44136595726013184, 0.33299872279167175, -1.4674346446990967, -0.7897835969924927, 0.4715353846549988, 0.14376309514045715, 0.7396150827407837, 1.0851274728775024, -1.2100328207015991, 1.6265439987182617, 0.6965264678001404, 0.004810698330402374, 0.139277845621109, -0.6319977641105652, -3.012115478515625, 2.173813581466675, -0.7935879230499268, 0.274405300617218, 0.2810969948768616, -1.089919924736023, -0.7062637209892273, -0.04824957996606827, 0.3436053991317749, -0.6936607360839844, 0.2279987633228302, 0.8932707905769348, 0.5182363390922546, -0.08065545558929443]" +"[[-1.460053 2.9393604 0.5533726 1.3786266 -1.5367306 -1.2867874 + -1.2442408 0.62938243 -0.7092637 -1.0278705 -1.3296479 -0.8105969 + 0.69997054 0.16618343 0.5113248 0.15563956 -0.4815752 -0.10130378 + 1.4232539 -1.2767068 -0.3229611 0.45140803 -1.3901687 1.0403453 + 1.454544 -1.308266 -1.145199 0.661388 -0.20519465 -1.0480955 + -0.04290716 -0.36275834]]",SORRY,13,"[-1.4600529670715332, 2.9393603801727295, 0.5533726215362549, 1.3786265850067139, -1.5367306470870972, -1.2867873907089233, -1.2442407608032227, 0.6293824315071106, -0.7092636823654175, -1.027870535850525, -1.3296478986740112, -0.8105968832969666, 0.699970543384552, 0.16618342697620392, 0.5113248229026794, 0.15563955903053284, -0.4815751910209656, -0.10130377858877182, 1.4232538938522339, -1.2767068147659302, -0.32296109199523926, 0.4514080286026001, -1.3901686668395996, 1.040345311164856, 1.454543948173523, -1.308266043663025, -1.145198941230774, 0.6613879799842834, -0.2051946520805359, -1.048095464706421, -0.04290715977549553, -0.3627583384513855]" +"[[ 1.0733138 -0.66348886 0.36737278 0.01765811 0.5730918 1.7617474 + -0.45580968 -1.0973133 0.4730748 -0.4665998 0.48594972 0.548745 + -0.91712314 0.4846773 0.3774526 -0.5996147 0.28750947 -1.0166394 + -0.6239797 1.7935088 -0.03666669 -0.51941574 2.045076 -0.9045104 + -0.6312211 0.9698636 1.0522215 -0.14772844 0.7406032 0.2901447 + -0.48710442 -0.4619298 ]]",TOT-ZIENS,14,"[1.07331383228302, -0.6634888648986816, 0.3673727810382843, 0.017658105120062828, 0.5730918049812317, 1.7617473602294922, -0.45580968260765076, -1.0973132848739624, 0.4730747938156128, -0.46659979224205017, 0.48594972491264343, 0.5487449765205383, -0.9171231389045715, 0.4846773147583008, 0.3774526119232178, -0.599614679813385, 0.2875094711780548, -1.0166393518447876, -0.6239796876907349, 1.793508768081665, -0.036666687577962875, -0.5194157361984253, 2.0450758934020996, -0.9045103788375854, -0.6312211155891418, 0.9698635935783386, 1.0522215366363525, -0.14772844314575195, 0.7406032085418701, 0.2901447117328644, -0.4871044158935547, -0.4619297981262207]" diff --git a/export_embeddings.py b/export_embeddings.py new file mode 100644 index 0000000..7a5cd6f --- /dev/null +++ b/export_embeddings.py @@ -0,0 +1,97 @@ +import multiprocessing +import os +import torch +import argparse +from datasets.dataset_loader import LocalDatasetLoader +from datasets.embedding_dataset import SLREmbeddingDataset +from torch.utils.data import DataLoader +from datasets import SLREmbeddingDataset, collate_fn_padd +from models.spoter_embedding_model import SPOTER_EMBEDDINGS +import numpy as np +import random +import pandas as pd + +seed = 43 +random.seed(seed) +np.random.seed(seed) +os.environ["PYTHONHASHSEED"] = str(seed) +torch.manual_seed(seed) +torch.cuda.manual_seed(seed) +torch.cuda.manual_seed_all(seed) +torch.backends.cudnn.deterministic = True +torch.use_deterministic_algorithms(True) +generator = torch.Generator() +generator.manual_seed(seed) + +def seed_worker(worker_id): + worker_seed = torch.initial_seed() % 2**32 + np.random.seed(worker_seed) + random.seed(worker_seed) + +generator = torch.Generator() +generator.manual_seed(seed) +import os +os.environ["CUBLAS_WORKSPACE_CONFIG"] = ":4096:8" + +def parse_args(): + parser = argparse.ArgumentParser(description='Export embeddings') + parser.add_argument('--checkpoint', type=str, default=None, help='Path to checkpoint') + parser.add_argument('--output', type=str, default=None, help='Path to output') + parser.add_argument('--dataset', type=str, default=None, help='Path to data') + parser.add_argument('--format', type=str, default='csv', help='Format of the output file (csv, json)') + args = parser.parse_args() + return args + +args = parse_args() + +device = torch.device("cpu") +if torch.cuda.is_available(): + device = torch.device("cuda") + +# load the model +checkpoint = torch.load(args.checkpoint, map_location=device) + +model = SPOTER_EMBEDDINGS( + features=checkpoint["config_args"].vector_length, + hidden_dim=checkpoint["config_args"].hidden_dim, + norm_emb=checkpoint["config_args"].normalize_embeddings, +).to(device) + +model.load_state_dict(checkpoint["state_dict"]) + +dataset_loader = LocalDatasetLoader() +dataset = SLREmbeddingDataset(args.dataset, triplet=False, augmentations=False) + +data_loader = DataLoader( + dataset, + batch_size=1, + shuffle=False, + collate_fn=collate_fn_padd, + pin_memory=torch.cuda.is_available(), + #num_workers=0, # Uncomment this line (and comment out next line) if you want to disable multithreading + num_workers=multiprocessing.cpu_count(), + worker_init_fn=seed_worker, + generator=generator, + ) + +embeddings = [] +k = 0 +with torch.no_grad(): + for i, (inputs, labels, masks) in enumerate(data_loader): + k += 1 + inputs = inputs.to(device) + masks = masks.to(device) + outputs = model(inputs, masks) + + for n in range(outputs.shape[0]): + embeddings.append(outputs[n].cpu().numpy()) + +df = pd.read_csv(args.dataset) +df["embeddings"] = embeddings +df = df[['embeddings', 'label_name', 'labels']] +df['embeddings2'] = df['embeddings'].apply(lambda x: x.tolist()[0]) + +if args.format == 'json': + df.to_json(args.output, orient='records') +elif args.format == 'csv': + df.to_csv(args.output, index=False) \ No newline at end of file diff --git a/export_model.py b/export_model.py new file mode 100644 index 0000000..044f0f3 --- /dev/null +++ b/export_model.py @@ -0,0 +1,71 @@ +import numpy as np +import onnx +import torch +import torchvision + +from models.spoter_embedding_model import SPOTER_EMBEDDINGS + +# set parameters of the model +model_name = 'embedding_model' +output=32 + +# load PyTorch model from .pth file + +device = torch.device("cpu") +# if torch.cuda.is_available(): +# device = torch.device("cuda") + +CHECKPOINT_PATH = "checkpoints/checkpoint_embed_1105.pth" +checkpoint = torch.load(CHECKPOINT_PATH, map_location=device) + +model = SPOTER_EMBEDDINGS( + features=checkpoint["config_args"].vector_length, + hidden_dim=checkpoint["config_args"].hidden_dim, + norm_emb=checkpoint["config_args"].normalize_embeddings, +).to(device) +model.load_state_dict(checkpoint["state_dict"]) +# set model to evaluation mode +model.eval() + +model_export = "onnx" +if model_export == "coreml": + dummy_input = torch.randn(1, 10, 54, 2) + # set device for dummy input + dummy_input = dummy_input.to(device) + traced_model = torch.jit.trace(model, dummy_input) + + out = traced_model(dummy_input) + import coremltools as ct + + # Convert to Core ML + coreml_model = ct.convert( + traced_model, + inputs=[ct.TensorType(name="input", shape=dummy_input.shape)], + ) + + # Save Core ML model + coreml_model.save("out-models/" + model_name + ".mlmodel") +else: + # create dummy input tensor + dummy_input = torch.randn(1, 10, 54, 2) + # set device for dummy input + dummy_input = dummy_input.to(device) + + # export model to ONNX format + output_file = 'models/' + model_name + '.onnx' + torch.onnx.export(model, dummy_input, output_file, input_names=['input'], output_names=['output']) + + torch.onnx.export(model, # model being run + dummy_input, # model input (or a tuple for multiple inputs) + 'out-models/' + model_name + '.onnx', # where to save the model (can be a file or file-like object) + export_params=True, # store the trained parameter weights inside the model file + opset_version=9, # the ONNX version to export the model to + do_constant_folding=True, # whether to execute constant folding for optimization + input_names = ['X'], # the model's input names + output_names = ['Y'] # the model's output names + ) + + + # load exported ONNX model for verification + onnx_model = onnx.load(output_file) + onnx.checker.check_model(onnx_model) \ No newline at end of file diff --git a/hyperparam_opt.py b/hyperparam_opt.py new file mode 100644 index 0000000..a7caabe --- /dev/null +++ b/hyperparam_opt.py @@ -0,0 +1,73 @@ +from clearml.automation import UniformParameterRange, UniformIntegerParameterRange, DiscreteParameterRange +from clearml.automation import HyperParameterOptimizer +from clearml.automation.optuna import OptimizerOptuna +from optuna.pruners import HyperbandPruner, MedianPruner +from clearml import Task + +task = Task.init( + project_name='SpoterEmbedding', + task_name='Automatic Hyper-Parameter Optimization', + task_type=Task.TaskTypes.optimizer, + reuse_last_task_id=False +) + + +optimizer = HyperParameterOptimizer( + # specifying the task to be optimized, task must be in system already so it can be cloned + base_task_id="4504e0b3ec6745249d3d4c94d3d40652", + # setting the hyperparameters to optimize + hyper_parameters=[ + # epochs: + DiscreteParameterRange('Args/epochs', [200]), + # learning rate + UniformParameterRange('Args/lr', 0.000001, 0.01), + # optimizer + DiscreteParameterRange('Args/optimizer', ['ADAM', 'SGD']), + # vector length + UniformIntegerParameterRange('Args/vector_length', 10, 100), + ], + # setting the objective metric we want to maximize/minimize + objective_metric_title='train_loss', + objective_metric_series='loss', + objective_metric_sign='min', + + # setting optimizer + optimizer_class=OptimizerOptuna, + + # configuring optimization parameters + execution_queue='default', + optimization_time_limit=360, + compute_time_limit=480, + total_max_jobs=20, + min_iteration_per_job=0, + max_iteration_per_job=150000, + pool_period_min=0.1, + + save_top_k_tasks_only=3, + optuna_pruner=MedianPruner(), + + ) + +def job_complete_callback( + job_id, # type: str + objective_value, # type: float + objective_iteration, # type: int + job_parameters, # type: dict + top_performance_job_id # type: str +): + print('Job completed!', job_id, objective_value, objective_iteration, job_parameters) + if job_id == top_performance_job_id: + print('WOOT WOOT we broke the record! Objective reached {}'.format(objective_value)) + +task.execute_remotely(queue_name='hypertuning', exit_process=True) + +optimizer.set_report_period(0.3) + +optimizer.start(job_complete_callback=job_complete_callback) + +optimizer.wait() + +top_exp = optimizer.get_top_experiments(top_k=3) +print([t.id for t in top_exp]) + +optimizer.stop() \ No newline at end of file diff --git a/normalization/blazepose_mapping.py b/normalization/blazepose_mapping.py index 666aba7..ad24b55 100644 --- a/normalization/blazepose_mapping.py +++ b/normalization/blazepose_mapping.py @@ -61,20 +61,25 @@ def map_blazepose_keypoint(column): return f"{mapped}_{hand}{suffix}" -def map_blazepose_df(df): +def map_blazepose_df(df, rename=True): + to_drop = [] + if rename: + renamings = {} + for column in df.columns: + mapped_column = map_blazepose_keypoint(column) + if mapped_column: + renamings[column] = mapped_column + else: + to_drop.append(column) + df = df.rename(columns=renamings) + for index, row in df.iterrows(): + sequence_size = len(row["leftEar_Y"]) lsx = row["leftShoulder_X"] rsx = row["rightShoulder_X"] lsy = row["leftShoulder_Y"] rsy = row["rightShoulder_Y"] - # convert all to list - lsx = lsx[1:-1].split(",") - rsx = rsx[1:-1].split(",") - lsy = lsy[1:-1].split(",") - rsy = rsy[1:-1].split(",") - sequence_size = len(lsx) - neck_x = [] neck_y = [] # Treat each element of the sequence (analyzed frame) individually @@ -84,4 +89,5 @@ def map_blazepose_df(df): df.loc[index, "neck_X"] = str(neck_x) df.loc[index, "neck_Y"] = str(neck_y) - return df + df.drop(columns=to_drop, inplace=True) + return df \ No newline at end of file diff --git a/normalization/main.py b/normalization/main.py index 9f4231f..2ed4891 100644 --- a/normalization/main.py +++ b/normalization/main.py @@ -5,30 +5,30 @@ import pandas as pd from normalization.hand_normalization import normalize_hands_full from normalization.body_normalization import normalize_body_full -DATASET_PATH = './data/wlasl' +DATASET_PATH = './data/processed' # Load the dataset -df = pd.read_csv(os.path.join(DATASET_PATH, "WLASL100_train.csv"), encoding="utf-8") +df = pd.read_csv(os.path.join(DATASET_PATH, "spoter_train.csv"), encoding="utf-8") print(df.head()) print(df.columns) # Retrieve metadata -video_size_heights = df["video_height"].to_list() -video_size_widths = df["video_width"].to_list() +# video_size_heights = df["video_height"].to_list() +# video_size_widths = df["video_width"].to_list() # Delete redundant (non-related) properties -del df["video_height"] -del df["video_width"] +# del df["video_height"] +# del df["video_width"] # Temporarily remove other relevant metadata labels = df["labels"].to_list() -video_fps = df["fps"].to_list() +signs = df["sign"].to_list() + del df["labels"] -del df["fps"] -del df["split"] -del df["video_id"] -del df["label_name"] -del df["length"] +del df["sign"] +del df["path"] +del df["participant_id"] +del df["sequence_id"] # Convert the strings into lists @@ -41,7 +41,7 @@ for column in df.columns: # Perform the normalizations df = normalize_hands_full(df) -df, invalid_row_indexes = normalize_body_full(df) +# df, invalid_row_indexes = normalize_body_full(df) # Clear lists of items from deleted rows # labels = [t for i, t in enumerate(labels) if i not in invalid_row_indexes] @@ -49,6 +49,6 @@ df, invalid_row_indexes = normalize_body_full(df) # Return the metadata back to the dataset df["labels"] = labels -df["fps"] = video_fps +df["sign"] = signs -df.to_csv(os.path.join(DATASET_PATH, "wlasl_train_norm.csv"), encoding="utf-8", index=False) +df.to_csv(os.path.join(DATASET_PATH, "spoter_train_norm.csv"), encoding="utf-8", index=False) diff --git a/notebooks/embeddings_evaluation.ipynb b/notebooks/embeddings_evaluation.ipynb index f04a1c0..d012c83 100644 --- a/notebooks/embeddings_evaluation.ipynb +++ b/notebooks/embeddings_evaluation.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "id": "c20f7fd5", "metadata": {}, "outputs": [], @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "ada032d0", "metadata": {}, "outputs": [], @@ -22,13 +22,12 @@ "import os\n", "import os.path as op\n", "import pandas as pd\n", - "import json\n", - "import base64" + "import json" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "id": "05682e73", "metadata": {}, "outputs": [], @@ -38,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "id": "fede7684", "metadata": {}, "outputs": [], @@ -48,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "id": "ce531994", "metadata": {}, "outputs": [], @@ -64,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "id": "f4a2d672", "metadata": {}, "outputs": [], @@ -87,17 +86,17 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "id": "1d9db764", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 7, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -119,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "id": "71224139", "metadata": {}, "outputs": [], @@ -155,7 +154,7 @@ "# checkpoint = torch.load(model.get_weights())\n", "\n", "## Set your path to checkoint here\n", - "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_6.pth\"\n", + "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_1105.pth\"\n", "checkpoint = torch.load(CHECKPOINT_PATH, map_location=device)\n", "\n", "model = SPOTER_EMBEDDINGS(\n", @@ -169,27 +168,28 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 24, "id": "ba6b58f0", "metadata": {}, "outputs": [], "source": [ - "SL_DATASET = 'wlasl' # or 'lsa'\n", - "if SL_DATASET == 'wlasl':\n", + "SL_DATASET = 'basic-signs' # or 'wlasl'\n", + "\n", + "if SL_DATASET == 'fingerspelling':\n", + " dataset_name = \"fingerspelling\"\n", + " split_dataset_path = \"fingerspelling_{}.csv\"\n", + "elif SL_DATASET == 'wlasl':\n", " dataset_name = \"wlasl\"\n", - " num_classes = 100\n", - " split_dataset_path = \"WLASL100_train.csv\"\n", - "else:\n", - " dataset_name = \"lsa64_mapped_mediapipe_only_landmarks_25fps\"\n", - " num_classes = 64\n", - " split_dataset_path = \"LSA64_{}.csv\"\n", - " \n", + " split_dataset_path = \"WLASL100_{}.csv\"\n", + "elif SL_DATASET == 'basic-signs':\n", + " dataset_name = \"basic-signs\"\n", + " split_dataset_path = \"basic-signs_{}.csv\"\n", " " ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 25, "id": "5643a72c", "metadata": {}, "outputs": [], @@ -228,7 +228,7 @@ "outputs": [], "source": [ "dataloaders = {}\n", - "splits = ['train', 'val']\n", + "splits = ['train', 'val']\n", "dfs = {}\n", "for split in splits:\n", " split_set_path = op.join(dataset_folder, split_dataset_path.format(split))\n", @@ -269,6 +269,8 @@ " for i, (inputs, labels, masks) in enumerate(dataloader):\n", " k += 1\n", " inputs = inputs.to(device)\n", + " \n", + "\n", " masks = masks.to(device)\n", " outputs = model(inputs, masks)\n", " for n in range(outputs.shape[0]):\n", @@ -285,7 +287,7 @@ { "data": { "text/plain": [ - "(810, 810)" + "(164, 164)" ] }, "execution_count": 19, @@ -299,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "ab83c6e2", "metadata": { "lines_to_next_cell": 2 @@ -311,6 +313,70 @@ " df['embeddings'] = embeddings_split[split]" ] }, + { + "cell_type": "code", + "execution_count": 26, + "id": "0b9fb9c2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 [1.7327625, -3.015248, -1.4775522, -0.7505071,...\n", + "1 [2.0936582, -0.596195, -0.7918601, -0.15896143...\n", + "2 [-1.4007742, -0.9608915, 1.3294879, -0.5185398...\n", + "3 [1.3280737, -3.299126, -1.0110444, -1.2528414,...\n", + "4 [-0.071124956, -0.79259753, 0.7182858, 0.38130...\n", + " ... \n", + "159 [-1.5968355, 1.9617733, 0.28859574, 1.256657, ...\n", + "160 [0.44801116, -1.8377966, 1.1004394, -1.195648,...\n", + "161 [2.0584257, 1.6986116, 0.5129896, 0.27279535, ...\n", + "162 [1.6695516, -2.967027, -1.5715427, -0.77170163...\n", + "163 [1.4977738, -2.6278958, -1.6123883, -0.8420623...\n", + "Name: embeddings, Length: 164, dtype: object\n", + "0 TOT-ZIENS\n", + "1 GOED\n", + "2 GOEDENACHT\n", + "3 NEE\n", + "4 SLECHT\n", + " ... \n", + "159 SORRY\n", + "160 GOEDEMORGEN\n", + "161 LINKS\n", + "162 TOT-ZIENS\n", + "163 GOED\n", + "Name: label_name, Length: 164, dtype: object\n", + "0 0\n", + "1 1\n", + "2 2\n", + "3 3\n", + "4 4\n", + " ..\n", + "159 7\n", + "160 5\n", + "161 13\n", + "162 0\n", + "163 1\n", + "Name: labels, Length: 164, dtype: int64\n" + ] + } + ], + "source": [ + "print(dfs['train'][\"embeddings\"])\n", + "print(dfs['train'][\"label_name\"])\n", + "print(dfs['train'][\"labels\"])\n", + "\n", + "# only keep these columns\n", + "dfs['train'] = dfs['train'][['embeddings', 'label_name', 'labels']]\n", + "\n", + "# convert embeddings to string\n", + "dfs['train']['embeddings2'] = dfs['train']['embeddings'].apply(lambda x: x.tolist())\n", + "\n", + "# save the dfs['train']\n", + "dfs['train'].to_csv(f'../data/{dataset_name}/embeddings.csv', index=False)" + ] + }, { "cell_type": "markdown", "id": "2951638d", @@ -322,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "id": "7399b8ae", "metadata": {}, "outputs": [ @@ -331,16 +397,16 @@ "output_type": "stream", "text": [ "Using centroids only\n", - "Top-1 accuracy: 5.19 %\n", - "Top-5 embeddings class match: 17.65 % (Picks any class in the 5 closest embeddings)\n", + "Top-1 accuracy: 80.00 %\n", + "Top-5 embeddings class match: 93.33 % (Picks any class in the 5 closest embeddings)\n", "\n", "################################\n", "\n", "Using all embeddings\n", - "Top-1 accuracy: 5.31 %\n", - "5-nn accuracy: 5.56 % (Picks the class that appears most often in the 5 closest embeddings)\n", - "Top-5 embeddings class match: 15.43 % (Picks any class in the 5 closest embeddings)\n", - "Top-5 unique class match: 15.56 % (Picks the 5 closest distinct classes)\n", + "Top-1 accuracy: 80.00 %\n", + "5-nn accuracy: 80.00 % (Picks the class that appears most often in the 5 closest embeddings)\n", + "Top-5 embeddings class match: 86.67 % (Picks any class in the 5 closest embeddings)\n", + "Top-5 unique class match: 93.33 % (Picks the 5 closest distinct classes)\n", "\n", "################################\n", "\n" @@ -375,13 +441,13 @@ " sorted_labels = labels[argsort]\n", " if sorted_labels[0] == true_label:\n", " top1 += 1\n", - " if use_centroids:\n", - " good_samples.append(df_val.loc[i, 'video_id'])\n", - " else:\n", - " good_samples.append((df_val.loc[i, 'video_id'],\n", - " df_train.loc[argsort[0], 'video_id'],\n", - " i,\n", - " argsort[0]))\n", + " # if use_centroids:\n", + " # good_samples.append(df_val.loc[i, 'video_id'])\n", + " # else:\n", + " # good_samples.append((df_val.loc[i, 'video_id'],\n", + " # df_train.loc[argsort[0], 'video_id'],\n", + " # i,\n", + " # argsort[0]))\n", "\n", "\n", " if true_label == Counter(sorted_labels[:5]).most_common()[0][0]:\n", diff --git a/notebooks/visualize_embeddings.ipynb b/notebooks/visualize_embeddings.ipynb index 4268c5a..b0d979c 100644 --- a/notebooks/visualize_embeddings.ipynb +++ b/notebooks/visualize_embeddings.ipynb @@ -91,7 +91,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 7, @@ -129,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 41, "id": "ead15a36", "metadata": {}, "outputs": [ @@ -139,7 +139,7 @@ "" ] }, - "execution_count": 9, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -151,7 +151,7 @@ "# checkpoint = torch.load(model.get_weights())\n", "\n", "\n", - "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_18.pth\"\n", + "CHECKPOINT_PATH = \"../out-checkpoints/augment_rotate_75_x8/checkpoint_embed_197.pth\"\n", "checkpoint = torch.load(CHECKPOINT_PATH, map_location=device)\n", "\n", "\n", @@ -166,26 +166,28 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 42, "id": "20f8036d", "metadata": {}, "outputs": [], "source": [ - "SL_DATASET = 'wlasl' # or 'lsa'\n", - "if SL_DATASET == 'wlasl':\n", - " dataset_name = \"processed\"\n", - " num_classes = 15\n", - " split_dataset_path = \"spoter_test.csv\"\n", - "else:\n", - " dataset_name = \"lsa64_mapped_mediapipe_only_landmarks_25fps\"\n", - " num_classes = 64\n", - " split_dataset_path = \"LSA64_{}.csv\"\n", + "SL_DATASET = 'basic-signs' # or 'wlasl'\n", + "\n", + "if SL_DATASET == 'fingerspelling':\n", + " dataset_name = \"fingerspelling\"\n", + " split_dataset_path = \"fingerspelling_{}.csv\"\n", + "elif SL_DATASET == 'wlasl':\n", + " dataset_name = \"wlasl\"\n", + " split_dataset_path = \"WLASL100_{}.csv\"\n", + "elif SL_DATASET == 'basic-signs':\n", + " dataset_name = \"basic-signs\"\n", + " split_dataset_path = \"{}.csv\"\n", " " ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 43, "id": "758716b6", "metadata": {}, "outputs": [], @@ -205,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 44, "id": "f1527959", "metadata": {}, "outputs": [ @@ -255,7 +257,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 45, "id": "3c3af5bf", "metadata": { "lines_to_next_cell": 0 @@ -264,10 +266,10 @@ { "data": { "text/plain": [ - "1220" + "143" ] }, - "execution_count": 24, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -286,13 +288,13 @@ " # df['video_fn'] = df['video_id'].apply(lambda video_id: os.path.join(BASE_DATA_FOLDER, f'lsa/videos/{video_id}.mp4'))\n", " dfs[split] = df\n", "\n", - "df = pd.concat([dfs['train'].sample(20), dfs['val']]).reset_index(drop=True)\n", + "df = pd.concat([dfs['train']]).reset_index(drop=True)\n", "len(df)" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 46, "id": "dccbe1b9", "metadata": {}, "outputs": [], @@ -315,7 +317,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 47, "id": "904298f0", "metadata": {}, "outputs": [], @@ -329,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 48, "id": "42832f7c", "metadata": { "scrolled": false @@ -340,7 +342,7 @@ "text/html": [ "
\n", " \n", - " Loading BokehJS ...\n", + " Loading BokehJS ...\n", "
\n" ] }, @@ -349,7 +351,7 @@ }, { "data": { - "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1144\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1144\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1506\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1506\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", "application/vnd.bokehjs_load.v0+json": "" }, "metadata": {}, @@ -373,7 +375,12 @@ " \n", " \n", "\"\"\"\n", - "cmap = LinearColorMapper(palette=\"Turbo256\", low=0, high=len(set_labels))\n", + "\n", + "# get labels\n", + "labels = df['label_name'].values\n", + "# get unique labels\n", + "unique_labels = np.unique(labels)\n", + "cmap = LinearColorMapper(palette=\"Turbo256\", low=0, high=len(unique_labels))\n", "\n", "output_notebook()\n", "# or \n", @@ -387,32 +394,33 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 49, "id": "ead4daf7", "metadata": { "scrolled": false }, "outputs": [ { - "ename": "KeyError", - "evalue": "'label_name'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/indexes/base.py:3802\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3801\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 3802\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_engine\u001b[39m.\u001b[39;49mget_loc(casted_key)\n\u001b[1;32m 3803\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n", - "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/_libs/index.pyx:138\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", - "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/_libs/index.pyx:165\u001b[0m, in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n", - "File \u001b[0;32mpandas/_libs/hashtable_class_helper.pxi:5745\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", - "File \u001b[0;32mpandas/_libs/hashtable_class_helper.pxi:5753\u001b[0m, in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n", - "\u001b[0;31mKeyError\u001b[0m: 'label_name'", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[29], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m column_data \u001b[39m=\u001b[39m \u001b[39mdict\u001b[39m(\n\u001b[1;32m 2\u001b[0m x\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mtsne_x\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 3\u001b[0m y\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mtsne_y\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 4\u001b[0m label\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39msign\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[0;32m----> 5\u001b[0m label_desc\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39;49m\u001b[39mlabel_name\u001b[39;49m\u001b[39m'\u001b[39;49m],\n\u001b[1;32m 6\u001b[0m split\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39msplit\u001b[39m\u001b[39m'\u001b[39m],\n\u001b[1;32m 7\u001b[0m video_id\u001b[39m=\u001b[39mdf[\u001b[39m'\u001b[39m\u001b[39mvideo_id\u001b[39m\u001b[39m'\u001b[39m]\n\u001b[1;32m 8\u001b[0m )\n\u001b[1;32m 10\u001b[0m \u001b[39mif\u001b[39;00m use_img_div:\n\u001b[1;32m 11\u001b[0m emb_videos \u001b[39m=\u001b[39m load_videos(df[\u001b[39m'\u001b[39m\u001b[39mvideo_fn\u001b[39m\u001b[39m'\u001b[39m])\n", - "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/frame.py:3807\u001b[0m, in \u001b[0;36mDataFrame.__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 3805\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcolumns\u001b[39m.\u001b[39mnlevels \u001b[39m>\u001b[39m \u001b[39m1\u001b[39m:\n\u001b[1;32m 3806\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_getitem_multilevel(key)\n\u001b[0;32m-> 3807\u001b[0m indexer \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mcolumns\u001b[39m.\u001b[39;49mget_loc(key)\n\u001b[1;32m 3808\u001b[0m \u001b[39mif\u001b[39;00m is_integer(indexer):\n\u001b[1;32m 3809\u001b[0m indexer \u001b[39m=\u001b[39m [indexer]\n", - "File \u001b[0;32m/usr/local/lib/python3.8/dist-packages/pandas/core/indexes/base.py:3804\u001b[0m, in \u001b[0;36mIndex.get_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 3802\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_engine\u001b[39m.\u001b[39mget_loc(casted_key)\n\u001b[1;32m 3803\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n\u001b[0;32m-> 3804\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mKeyError\u001b[39;00m(key) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n\u001b[1;32m 3805\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mTypeError\u001b[39;00m:\n\u001b[1;32m 3806\u001b[0m \u001b[39m# If we have a listlike key, _check_indexing_error will raise\u001b[39;00m\n\u001b[1;32m 3807\u001b[0m \u001b[39m# InvalidIndexError. Otherwise we fall through and re-raise\u001b[39;00m\n\u001b[1;32m 3808\u001b[0m \u001b[39m# the TypeError.\u001b[39;00m\n\u001b[1;32m 3809\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_check_indexing_error(key)\n", - "\u001b[0;31mKeyError\u001b[0m: 'label_name'" - ] + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n const docs_json = {\"49e50715-c814-427d-91f3-7faabca8d9a1\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1518\"}],\"center\":[{\"id\":\"1521\"},{\"id\":\"1525\"},{\"id\":\"1559\"}],\"height\":800,\"left\":[{\"id\":\"1522\"}],\"renderers\":[{\"id\":\"1547\"}],\"title\":{\"id\":\"1508\"},\"toolbar\":{\"id\":\"1534\"},\"width\":1000,\"x_range\":{\"id\":\"1510\"},\"x_scale\":{\"id\":\"1514\"},\"y_range\":{\"id\":\"1512\"},\"y_scale\":{\"id\":\"1516\"}},\"id\":\"1507\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1529\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1551\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1552\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1555\",\"type\":\"AllLabels\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1554\"},\"group\":null,\"major_label_policy\":{\"id\":\"1555\"},\"ticker\":{\"id\":\"1519\"}},\"id\":\"1518\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1554\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1532\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1523\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1526\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1510\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1527\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1519\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1556\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"high\":15,\"low\":0,\"palette\":[\"#30123b\",\"#311542\",\"#32184a\",\"#341b51\",\"#351e58\",\"#36215f\",\"#372365\",\"#38266c\",\"#392972\",\"#3a2c79\",\"#3b2f7f\",\"#3c3285\",\"#3c358b\",\"#3d3791\",\"#3e3a96\",\"#3f3d9c\",\"#4040a1\",\"#4043a6\",\"#4145ab\",\"#4148b0\",\"#424bb5\",\"#434eba\",\"#4350be\",\"#4353c2\",\"#4456c7\",\"#4458cb\",\"#455bce\",\"#455ed2\",\"#4560d6\",\"#4563d9\",\"#4666dd\",\"#4668e0\",\"#466be3\",\"#466de6\",\"#4670e8\",\"#4673eb\",\"#4675ed\",\"#4678f0\",\"#467af2\",\"#467df4\",\"#467ff6\",\"#4682f8\",\"#4584f9\",\"#4587fb\",\"#4589fc\",\"#448cfd\",\"#438efd\",\"#4291fe\",\"#4193fe\",\"#4096fe\",\"#3f98fe\",\"#3e9bfe\",\"#3c9dfd\",\"#3ba0fc\",\"#39a2fc\",\"#38a5fb\",\"#36a8f9\",\"#34aaf8\",\"#33acf6\",\"#31aff5\",\"#2fb1f3\",\"#2db4f1\",\"#2bb6ef\",\"#2ab9ed\",\"#28bbeb\",\"#26bde9\",\"#25c0e6\",\"#23c2e4\",\"#21c4e1\",\"#20c6df\",\"#1ec9dc\",\"#1dcbda\",\"#1ccdd7\",\"#1bcfd4\",\"#1ad1d2\",\"#19d3cf\",\"#18d5cc\",\"#18d7ca\",\"#17d9c7\",\"#17dac4\",\"#17dcc2\",\"#17debf\",\"#18e0bd\",\"#18e1ba\",\"#19e3b8\",\"#1ae4b6\",\"#1be5b4\",\"#1de7b1\",\"#1ee8af\",\"#20e9ac\",\"#22eba9\",\"#24eca6\",\"#27eda3\",\"#29eea0\",\"#2cef9d\",\"#2ff09a\",\"#32f197\",\"#35f394\",\"#38f491\",\"#3bf48d\",\"#3ff58a\",\"#42f687\",\"#46f783\",\"#4af880\",\"#4df97c\",\"#51f979\",\"#55fa76\",\"#59fb72\",\"#5dfb6f\",\"#61fc6c\",\"#65fc68\",\"#69fd65\",\"#6dfd62\",\"#71fd5f\",\"#74fe5c\",\"#78fe59\",\"#7cfe56\",\"#80fe53\",\"#84fe50\",\"#87fe4d\",\"#8bfe4b\",\"#8efe48\",\"#92fe46\",\"#95fe44\",\"#98fe42\",\"#9bfd40\",\"#9efd3e\",\"#a1fc3d\",\"#a4fc3b\",\"#a6fb3a\",\"#a9fb39\",\"#acfa37\",\"#aef937\",\"#b1f836\",\"#b3f835\",\"#b6f735\",\"#b9f534\",\"#bbf434\",\"#bef334\",\"#c0f233\",\"#c3f133\",\"#c5ef33\",\"#c8ee33\",\"#caed33\",\"#cdeb34\",\"#cfea34\",\"#d1e834\",\"#d4e735\",\"#d6e535\",\"#d8e335\",\"#dae236\",\"#dde036\",\"#dfde36\",\"#e1dc37\",\"#e3da37\",\"#e5d838\",\"#e7d738\",\"#e8d538\",\"#ead339\",\"#ecd139\",\"#edcf39\",\"#efcd39\",\"#f0cb3a\",\"#f2c83a\",\"#f3c63a\",\"#f4c43a\",\"#f6c23a\",\"#f7c039\",\"#f8be39\",\"#f9bc39\",\"#f9ba38\",\"#fab737\",\"#fbb537\",\"#fbb336\",\"#fcb035\",\"#fcae34\",\"#fdab33\",\"#fda932\",\"#fda631\",\"#fda330\",\"#fea12f\",\"#fe9e2e\",\"#fe9b2d\",\"#fe982c\",\"#fd952b\",\"#fd9229\",\"#fd8f28\",\"#fd8c27\",\"#fc8926\",\"#fc8624\",\"#fb8323\",\"#fb8022\",\"#fa7d20\",\"#fa7a1f\",\"#f9771e\",\"#f8741c\",\"#f7711b\",\"#f76e1a\",\"#f66b18\",\"#f56817\",\"#f46516\",\"#f36315\",\"#f26014\",\"#f15d13\",\"#ef5a11\",\"#ee5810\",\"#ed550f\",\"#ec520e\",\"#ea500d\",\"#e94d0d\",\"#e84b0c\",\"#e6490b\",\"#e5460a\",\"#e3440a\",\"#e24209\",\"#e04008\",\"#de3e08\",\"#dd3c07\",\"#db3a07\",\"#d93806\",\"#d73606\",\"#d63405\",\"#d43205\",\"#d23005\",\"#d02f04\",\"#ce2d04\",\"#cb2b03\",\"#c92903\",\"#c72803\",\"#c52602\",\"#c32402\",\"#c02302\",\"#be2102\",\"#bb1f01\",\"#b91e01\",\"#b61c01\",\"#b41b01\",\"#b11901\",\"#ae1801\",\"#ac1601\",\"#a91501\",\"#a61401\",\"#a31201\",\"#a01101\",\"#9d1001\",\"#9a0e01\",\"#970d01\",\"#940c01\",\"#910b01\",\"#8e0a01\",\"#8b0901\",\"#870801\",\"#840701\",\"#810602\",\"#7d0502\",\"#7a0402\"]},\"id\":\"1505\",\"type\":\"LinearColorMapper\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1542\"},\"glyph\":{\"id\":\"1544\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1546\"},\"nonselection_glyph\":{\"id\":\"1545\"},\"view\":{\"id\":\"1548\"}},\"id\":\"1547\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"hatch_alpha\":{\"value\":0.2},\"hatch_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1546\",\"type\":\"Scatter\"},{\"attributes\":{\"source\":{\"id\":\"1542\"}},\"id\":\"1548\",\"type\":\"CDSView\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"Check label by hovering mouse over the dots\"},\"id\":\"1508\",\"type\":\"Title\"},{\"attributes\":{\"data\":{\"label\":[3,0,9,1,2,12,8,4,11,4,5,6,1,8,4,1,8,6,2,0,0,0,11,10,4,6,8,4,2,13,6,7,4,6,13,6,11,0,12,9,9,2,7,13,3,4,14,2,2,5,2,14,7,9,14,1,10,4,3,4,10,0,14,7,6,9,3,12,1,9,9,11,1,1,8,7,11,3,1,9,14,5,6,8,12,11,11,5,9,1,0,8,5,14,10,10,11,8,5,12,0,3,1,10,5,11,5,12,9,9,3,6,8,2,14,10,5,9,3,6,0,13,7,7,10,0,10,7,11,13,2,12,13,9,13,7,2,8,4,10,14,2,13],\"label_desc\":[\"NEE\",\"TOT-ZIENS\",\"RECHTS\",\"GOED\",\"GOEDENACHT\",\"BEDANKEN\",\"SMAKELIJK\",\"SLECHT\",\"SALUUT\",\"SLECHT\",\"GOEDEMORGEN\",\"JA\",\"GOED\",\"SMAKELIJK\",\"SLECHT\",\"GOED\",\"SMAKELIJK\",\"JA\",\"GOEDENACHT\",\"TOT-ZIENS\",\"TOT-ZIENS\",\"TOT-ZIENS\",\"SALUUT\",\"GOEDENAVOND\",\"SLECHT\",\"JA\",\"SMAKELIJK\",\"SLECHT\",\"GOEDENACHT\",\"LINKS\",\"JA\",\"SORRY\",\"SLECHT\",\"JA\",\"LINKS\",\"JA\",\"SALUUT\",\"TOT-ZIENS\",\"BEDANKEN\",\"RECHTS\",\"RECHTS\",\"GOEDENACHT\",\"SORRY\",\"LINKS\",\"NEE\",\"SLECHT\",\"GOEDEMIDDAG\",\"GOEDENACHT\",\"GOEDENACHT\",\"GOEDEMORGEN\",\"GOEDENACHT\",\"GOEDEMIDDAG\",\"SORRY\",\"RECHTS\",\"GOEDEMIDDAG\",\"GOED\",\"GOEDENAVOND\",\"SLECHT\",\"NEE\",\"SLECHT\",\"GOEDENAVOND\",\"TOT-ZIENS\",\"GOEDEMIDDAG\",\"SORRY\",\"JA\",\"RECHTS\",\"NEE\",\"BEDANKEN\",\"GOED\",\"RECHTS\",\"RECHTS\",\"SALUUT\",\"GOED\",\"GOED\",\"SMAKELIJK\",\"SORRY\",\"SALUUT\",\"NEE\",\"GOED\",\"RECHTS\",\"GOEDEMIDDAG\",\"GOEDEMORGEN\",\"JA\",\"SMAKELIJK\",\"BEDANKEN\",\"SALUUT\",\"SALUUT\",\"GOEDEMORGEN\",\"RECHTS\",\"GOED\",\"TOT-ZIENS\",\"SMAKELIJK\",\"GOEDEMORGEN\",\"GOEDEMIDDAG\",\"GOEDENAVOND\",\"GOEDENAVOND\",\"SALUUT\",\"SMAKELIJK\",\"GOEDEMORGEN\",\"BEDANKEN\",\"TOT-ZIENS\",\"NEE\",\"GOED\",\"GOEDENAVOND\",\"GOEDEMORGEN\",\"SALUUT\",\"GOEDEMORGEN\",\"BEDANKEN\",\"RECHTS\",\"RECHTS\",\"NEE\",\"JA\",\"SMAKELIJK\",\"GOEDENACHT\",\"GOEDEMIDDAG\",\"GOEDENAVOND\",\"GOEDEMORGEN\",\"RECHTS\",\"NEE\",\"JA\",\"TOT-ZIENS\",\"LINKS\",\"SORRY\",\"SORRY\",\"GOEDENAVOND\",\"TOT-ZIENS\",\"GOEDENAVOND\",\"SORRY\",\"SALUUT\",\"LINKS\",\"GOEDENACHT\",\"BEDANKEN\",\"LINKS\",\"RECHTS\",\"LINKS\",\"SORRY\",\"GOEDENACHT\",\"SMAKELIJK\",\"SLECHT\",\"GOEDENAVOND\",\"GOEDEMIDDAG\",\"GOEDENACHT\",\"LINKS\"],\"labels\":[3,0,9,1,2,12,8,4,11,4,5,6,1,8,4,1,8,6,2,0,0,0,11,10,4,6,8,4,2,13,6,7,4,6,13,6,11,0,12,9,9,2,7,13,3,4,14,2,2,5,2,14,7,9,14,1,10,4,3,4,10,0,14,7,6,9,3,12,1,9,9,11,1,1,8,7,11,3,1,9,14,5,6,8,12,11,11,5,9,1,0,8,5,14,10,10,11,8,5,12,0,3,1,10,5,11,5,12,9,9,3,6,8,2,14,10,5,9,3,6,0,13,7,7,10,0,10,7,11,13,2,12,13,9,13,7,2,8,4,10,14,2,13],\"split\":[\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\",\"train\"],\"x\":{\"__ndarray__\":\"ARi7wMqEXkDRJx/Bu6GvQNdTvr+4Pyu+y7TdPu/JAcG7Lw7BtZ/mwMGKlcA2FoM/tMCXQACITjhk3efA6K2gQBJRZz882QdA8YqJv5gnnUAMb4lA58mQQFZZJcGhd0Y/fNz1wN7Wvb+n5Vw/wjcQwVyr4r+4MU++QQxswOAWBUEwRBbBxD80QP2k7r1nampAqpPbwFC2gkB6w3o9Iu8EwLf1A8GNWgHAdBYLQT5/SL19Scy/MXWvwKHt8sCnZb2/CfYGwB9oGcAAcGu/NW7IwMUKCkEHNtnAOWIfwOtNtUCP5no/d5b5wANVysAa1vPADqK3v5EEaUCSqJbA7o4RQd/2Pr+0SRHBtwyxwNHijr/eWZpALA11wLfGGMFN6/3AFrWcQN7+vkBqtUjASRgSQQOSJ8H9eaBAmVyeQHQq5MCNhkHARcYjweTFakB652XAYe9xwDOK/8B7Qv7Ac5YFQFmYAsEg5MFAe4RtQPyZuMCEIyfA/KugwJjtHD/htLU+AoMhwcJ3+D8Mq+zA33mEwGhynED117vAZDtQQI3/BT+xvpnA2Z3/wO3coMAOfby/KXYHwcjJ6sC05o9A8aBDQIElpj/ZwhzAPDjPwNyB9b/6cDLAVTeAwJ2A8cBPfum+V/eEQEcPAD+oyyJB0ykQQaCfoMDJz39AoxEtwDovC0EgXtfAAVWHPa+v+r9BQgjAGU12vMQ8CsEIN8E+W0YGQfaj2b+UVTFA4S37wFa7U7+lIr7AkUvAv75/qL4=\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[143]},\"y\":{\"__ndarray__\":\"PXMbwDmNZEBa2QFASR2Tv0LmOL8awdQ/DpRuQPEFiMBeHSRAEEyHwJnpnz+WH47Arl8bvlanJUDzXYjAvQaMv3zVPkARozfADUmMwOENS0Cg+C9ApddUQEVaEEDL/fq9MkGewCuMo8BUBeY/mUlYwHOBxcAfgbHAiFn0vwJYfj83/FfA3UEbwB91rsALH3q/k5weQDYepUBdD0I/8fakQFHASkC4wQDAG3ICvyxpv8DV3EvAQeKcwIAAlUCtWY/AyOW6wEqbvj+OT2nAh2eGQPV2R74JPrc/P4GLQDd4BsAguoG/RPypwCqCocBd04/ACbljP82/kUArvkRAhD79PUCVoMC+goY/8A/4v0ie9j+S8Ly/wKRwQGgJlj9SdDVAvVANwN8y+7/0DKlAWWlPv8uW1T+v8lbAftUXwLd/ur3NwnlAHe5OQGs2lL8ToDpAShobQJUxhD/7uOA/66MLwCjwPD+PheC/eIMxQIPlU0DqgIu/DL5lQIKO8D6UvQhA0zCwP4f0T0DmeJtA7s2NQCFoSkCStYHAzALkPS9/1T0ZtZxA92wDQPOCm0AwxxJAQsZuPr6zUT+wdbc/D7fdv6lgUEBF7gzA/5mFQJyxSr4/CJw/0AZfQMQRH8BYG9LAvfaDQMMEx8Acb1U/hK0avzBICEApmhlAuWyXPqzxgz/A9jNAqCPWwG9HrMANYak+K0mowCFyyj9R5czAZfjvPUVycr9WR3rAuIc1wI8BUD+xnts/9WZ7wJhOxcA=\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[143]}},\"selected\":{\"id\":\"1557\"},\"selection_policy\":{\"id\":\"1556\"}},\"id\":\"1542\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1514\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"items\":[{\"id\":\"1560\"}]},\"id\":\"1559\",\"type\":\"Legend\"},{\"attributes\":{},\"id\":\"1531\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"1512\",\"type\":\"DataRange1d\"},{\"attributes\":{\"axis\":{\"id\":\"1522\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1525\",\"type\":\"Grid\"},{\"attributes\":{\"label\":{\"field\":\"label_desc\"},\"renderers\":[{\"id\":\"1547\"}]},\"id\":\"1560\",\"type\":\"LegendItem\"},{\"attributes\":{\"callback\":null,\"tooltips\":\"\\n
\\n \\n
\\n @label_desc - @split\\n [#@video_id]\\n
\\n
\\n \\n\"},\"id\":\"1533\",\"type\":\"HoverTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"hatch_alpha\":{\"value\":0.1},\"hatch_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1545\",\"type\":\"Scatter\"},{\"attributes\":{\"axis\":{\"id\":\"1518\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1521\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1557\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1530\",\"type\":\"ResetTool\"},{\"attributes\":{\"overlay\":{\"id\":\"1532\"}},\"id\":\"1528\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"hatch_alpha\":{\"value\":0.5},\"hatch_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"field\":\"labels\",\"transform\":{\"id\":\"1505\"}},\"size\":{\"value\":10},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1544\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1516\",\"type\":\"LinearScale\"},{\"attributes\":{\"tools\":[{\"id\":\"1526\"},{\"id\":\"1527\"},{\"id\":\"1528\"},{\"id\":\"1529\"},{\"id\":\"1530\"},{\"id\":\"1531\"},{\"id\":\"1533\"}]},\"id\":\"1534\",\"type\":\"Toolbar\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1551\"},\"group\":null,\"major_label_policy\":{\"id\":\"1552\"},\"ticker\":{\"id\":\"1523\"}},\"id\":\"1522\",\"type\":\"LinearAxis\"}],\"root_ids\":[\"1507\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.3\"}};\n const render_items = [{\"docid\":\"49e50715-c814-427d-91f3-7faabca8d9a1\",\"root_ids\":[\"1507\"],\"roots\":{\"1507\":\"c95f81fb-7cf0-4c10-b8a3-a9e77c772aef\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "1507" + } + }, + "output_type": "display_data" } ], "source": [ @@ -420,34 +428,522 @@ " x=df['tsne_x'],\n", " y=df['tsne_y'],\n", " label=df['labels'],\n", - " label_desc=df['sign'],\n", + " label_desc=df['label_name'],\n", " split=df['split'],\n", - " video_id=df['video_id']\n", + " # video_id=df['video_id']\n", ")\n", "\n", + "# get unique labels\n", + "set_labels = list(set(column_data['label']))\n", + "\n", + "# map labels to 0 to num_classes\n", + "label_to_id = {label: i for i, label in enumerate(set_labels)}\n", + "column_data['labels'] = [label_to_id[label] for label in column_data['label']]\n", + "\n", + "\n", "if use_img_div:\n", " emb_videos = load_videos(df['video_fn'])\n", " column_data[\"videos\"] = emb_videos\n", "source = ColumnDataSource(data=column_data)\n", "\n", - "p.scatter('x', 'y',\n", - " size=10,\n", - " source=source,\n", - " fill_color={\"field\": 'label', \"transform\": cmap},\n", - " line_color={\"field\": 'label', \"transform\": cmap}, \n", - " #legend_label={\"field\": 'split', \"transform\": lambda x: df['split']},\n", - "# marker={\"field\": 'split'}\n", - " )\n", + "# scatter plot with for each label another color\n", + "p.scatter(x='x',\n", + " y='y',\n", + " source=source,\n", + " color={'field': 'labels', 'transform': cmap},\n", + " legend_field='label_desc',\n", + " size=10,\n", + " alpha=0.5)\n", + "\n", "\n", "show(p)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 134, "id": "1d761766", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
nose_Xnose_YleftEye_XleftEye_YrightEye_XrightEye_YleftEar_XleftEar_YrightEar_XrightEar_Y...splitvideo_idlabelslabel_namevideo_widthvideo_heightfpslengthtsne_xtsne_y
0[0.498452,0.498553,0.498740,0.499141,0.499253,...[0.320706,0.326079,0.329347,0.330840,0.331348,...[0.534112,0.534081,0.534074,0.534061,0.533951,...[0.283401,0.285650,0.287332,0.288115,0.288350,...[0.461303,0.461805,0.462395,0.462959,0.463122,...[0.276863,0.278502,0.279791,0.280531,0.280942,...[0.558462,0.557758,0.557173,0.556385,0.555548,...[0.304631,0.305481,0.306485,0.306842,0.306911,...[0.432248,0.432255,0.432270,0.432289,0.432280,...[0.300599,0.302358,0.303453,0.304156,0.304925,......trainB!train!2_20230301114043553439_H4EER0B640.0480.030.0000003.933333-5.14574510.443328
1[0.499603,0.499782,0.499713,0.499718,0.499716,...[0.377759,0.372090,0.369328,0.368845,0.368575,...[0.545239,0.545351,0.545337,0.545315,0.545176,...[0.303044,0.300618,0.299811,0.299697,0.299686,...[0.450075,0.450722,0.451349,0.452002,0.452172,...[0.302042,0.301742,0.301553,0.301575,0.301589,...[0.571113,0.571111,0.571020,0.570947,0.570956,...[0.315368,0.314974,0.315351,0.315415,0.315432,...[0.411997,0.412929,0.413561,0.414035,0.414218,...[0.322391,0.322607,0.322609,0.322896,0.323251,......trainD!train!4_20230228231932508739_203WJ1D640.0480.015.0000004.000000-1.611456-13.267664
2[0.506591,0.507312,0.507955,0.508396,0.508882,...[0.397696,0.397776,0.397885,0.397972,0.398277,...[0.554327,0.554781,0.555182,0.555651,0.556110,...[0.343845,0.343422,0.343181,0.342978,0.342935,...[0.464670,0.464618,0.464613,0.464606,0.464599,...[0.342834,0.343746,0.344376,0.344640,0.345239,...[0.589977,0.589761,0.589638,0.589578,0.589559,...[0.373605,0.372651,0.372061,0.371614,0.371254,...[0.439167,0.439298,0.439412,0.439468,0.439555,...[0.369968,0.371493,0.372602,0.372962,0.373442,......trainX!train!24_20230313193727472324_QZ48Y2X640.0480.016.6666673.840000-8.379868-9.681334
3[0.563219,0.564298,0.564446,0.564395,0.564335,...[0.453190,0.454664,0.455088,0.455298,0.455444,...[0.615217,0.615701,0.615785,0.615487,0.615222,...[0.390181,0.393572,0.394811,0.395661,0.396261,...[0.525598,0.528705,0.529607,0.529693,0.529688,...[0.376735,0.379062,0.379977,0.381287,0.382156,...[0.654602,0.652928,0.651517,0.649746,0.648452,...[0.414657,0.417255,0.418721,0.419629,0.420523,...[0.487122,0.489352,0.490052,0.490523,0.490764,...[0.389374,0.393725,0.396954,0.398778,0.399780,......trainO!train!15_20230316130349891667_94GK73O640.0480.030.0000003.933333-3.46801119.879887
4[0.534347,0.534350,0.534348,0.534351,0.534257,...[0.366040,0.369482,0.371950,0.373151,0.375056,...[0.573697,0.573855,0.573859,0.573850,0.573835,...[0.312855,0.314814,0.315821,0.316412,0.317599,...[0.499859,0.499486,0.499479,0.499499,0.499556,...[0.319383,0.320213,0.321349,0.322067,0.322843,...[0.614189,0.611145,0.609677,0.608775,0.608422,...[0.339505,0.339731,0.339752,0.339752,0.339768,...[0.469407,0.469407,0.469571,0.469696,0.469925,...[0.340159,0.340279,0.340594,0.340797,0.340932,......trainW!train!23_20230307162255985290_ZET4J5W640.0480.030.0000003.933333-13.8196629.518650
..................................................................
555[0.606690,0.606405,0.606321,0.606093,0.606335,...[0.533929,0.534472,0.534947,0.534889,0.537878,...[0.653085,0.652606,0.652609,0.652661,0.653283,...[0.484087,0.483741,0.483700,0.483398,0.483384,...[0.565955,0.565624,0.565546,0.565457,0.566247,...[0.485883,0.485947,0.486004,0.485994,0.486090,...[0.695397,0.695193,0.695191,0.695250,0.695459,...[0.516024,0.516022,0.516945,0.516905,0.516701,...[0.538066,0.539230,0.539818,0.540210,0.541056,...[0.520784,0.520945,0.521081,0.520950,0.520934,......trainF!train!6_20230306192746737772_PBKJJ24F640.0480.014.9850153.9372670.8503919.577452
556[0.573205,0.574528,0.574271,0.573180,0.572867,...[0.425358,0.427494,0.430532,0.431733,0.435090,...[0.639872,0.640339,0.640325,0.639660,0.639780,...[0.375095,0.375091,0.375052,0.374993,0.375106,...[0.520413,0.520586,0.519840,0.519523,0.519537,...[0.352025,0.352860,0.353801,0.354090,0.355025,...[0.679821,0.679411,0.678846,0.678844,0.678880,...[0.415243,0.415450,0.415431,0.415466,0.415461,...[0.473096,0.472687,0.471395,0.470902,0.470860,...[0.389405,0.390338,0.391198,0.391376,0.391626,......trainX!train!24_20230318150756432389_T1XTN2X640.0480.01000.0000002.5420006.209669-17.046406
557[0.438977,0.438982,0.438984,0.439069,0.439295,...[0.379214,0.380074,0.381261,0.382829,0.384443,...[0.486520,0.487420,0.488052,0.488677,0.489241,...[0.325285,0.328029,0.330372,0.332641,0.334531,...[0.406919,0.407048,0.407155,0.407375,0.407649,...[0.323748,0.324836,0.326162,0.327786,0.329353,...[0.526903,0.526998,0.527116,0.527220,0.527326,...[0.355733,0.356432,0.357204,0.357981,0.358690,...[0.381000,0.381048,0.381127,0.381257,0.381449,...[0.345693,0.345312,0.345154,0.345138,0.345149,......trainZ!train!26_20230313164104308046_EDP6L14Z640.0480.030.0000003.6000007.305971-23.761284
558[0.562234,0.562230,0.562221,0.562282,0.562289,...[0.604714,0.604817,0.605458,0.605774,0.605789,...[0.621810,0.620646,0.619884,0.619644,0.619426,...[0.547658,0.549717,0.552919,0.554406,0.554940,...[0.526415,0.526580,0.526635,0.526828,0.526959,...[0.542624,0.542402,0.542402,0.542387,0.542231,...[0.662978,0.662662,0.662170,0.661898,0.661687,...[0.577477,0.579208,0.581354,0.582389,0.582804,...[0.492118,0.492225,0.492262,0.492301,0.492397,...[0.553820,0.556338,0.558264,0.559222,0.559432,......trainY!train!25_20230313125334541132_UB0038Y640.0480.01000.0000003.9020009.30426610.654608
559[0.537090,0.537468,0.538434,0.537603,0.536945,...[0.298635,0.298634,0.298710,0.298587,0.298353,...[0.567478,0.567737,0.568967,0.568920,0.568670,...[0.272478,0.272135,0.271965,0.271218,0.270843,...[0.507183,0.507388,0.507843,0.507606,0.507431,...[0.266559,0.266555,0.266612,0.266608,0.266449,...[0.597032,0.597237,0.597694,0.598045,0.598189,...[0.297459,0.297435,0.297352,0.296939,0.296923,...[0.477034,0.477224,0.477629,0.477716,0.477724,...[0.294895,0.294492,0.294483,0.294487,0.294418,......trainW!train!23_20230307164435248346_FGQVL5W640.0480.01000.0000003.198000-14.6106008.728515
\n", + "

560 rows × 118 columns

\n", + "
" + ], + "text/plain": [ + " nose_X \\\n", + "0 [0.498452,0.498553,0.498740,0.499141,0.499253,... \n", + "1 [0.499603,0.499782,0.499713,0.499718,0.499716,... \n", + "2 [0.506591,0.507312,0.507955,0.508396,0.508882,... \n", + "3 [0.563219,0.564298,0.564446,0.564395,0.564335,... \n", + "4 [0.534347,0.534350,0.534348,0.534351,0.534257,... \n", + ".. ... \n", + "555 [0.606690,0.606405,0.606321,0.606093,0.606335,... \n", + "556 [0.573205,0.574528,0.574271,0.573180,0.572867,... \n", + "557 [0.438977,0.438982,0.438984,0.439069,0.439295,... \n", + "558 [0.562234,0.562230,0.562221,0.562282,0.562289,... \n", + "559 [0.537090,0.537468,0.538434,0.537603,0.536945,... \n", + "\n", + " nose_Y \\\n", + "0 [0.320706,0.326079,0.329347,0.330840,0.331348,... \n", + "1 [0.377759,0.372090,0.369328,0.368845,0.368575,... \n", + "2 [0.397696,0.397776,0.397885,0.397972,0.398277,... \n", + "3 [0.453190,0.454664,0.455088,0.455298,0.455444,... \n", + "4 [0.366040,0.369482,0.371950,0.373151,0.375056,... \n", + ".. ... \n", + "555 [0.533929,0.534472,0.534947,0.534889,0.537878,... \n", + "556 [0.425358,0.427494,0.430532,0.431733,0.435090,... \n", + "557 [0.379214,0.380074,0.381261,0.382829,0.384443,... \n", + "558 [0.604714,0.604817,0.605458,0.605774,0.605789,... \n", + "559 [0.298635,0.298634,0.298710,0.298587,0.298353,... \n", + "\n", + " leftEye_X \\\n", + "0 [0.534112,0.534081,0.534074,0.534061,0.533951,... \n", + "1 [0.545239,0.545351,0.545337,0.545315,0.545176,... \n", + "2 [0.554327,0.554781,0.555182,0.555651,0.556110,... \n", + "3 [0.615217,0.615701,0.615785,0.615487,0.615222,... \n", + "4 [0.573697,0.573855,0.573859,0.573850,0.573835,... \n", + ".. ... \n", + "555 [0.653085,0.652606,0.652609,0.652661,0.653283,... \n", + "556 [0.639872,0.640339,0.640325,0.639660,0.639780,... \n", + "557 [0.486520,0.487420,0.488052,0.488677,0.489241,... \n", + "558 [0.621810,0.620646,0.619884,0.619644,0.619426,... \n", + "559 [0.567478,0.567737,0.568967,0.568920,0.568670,... \n", + "\n", + " leftEye_Y \\\n", + "0 [0.283401,0.285650,0.287332,0.288115,0.288350,... \n", + "1 [0.303044,0.300618,0.299811,0.299697,0.299686,... \n", + "2 [0.343845,0.343422,0.343181,0.342978,0.342935,... \n", + "3 [0.390181,0.393572,0.394811,0.395661,0.396261,... \n", + "4 [0.312855,0.314814,0.315821,0.316412,0.317599,... \n", + ".. ... \n", + "555 [0.484087,0.483741,0.483700,0.483398,0.483384,... \n", + "556 [0.375095,0.375091,0.375052,0.374993,0.375106,... \n", + "557 [0.325285,0.328029,0.330372,0.332641,0.334531,... \n", + "558 [0.547658,0.549717,0.552919,0.554406,0.554940,... \n", + "559 [0.272478,0.272135,0.271965,0.271218,0.270843,... \n", + "\n", + " rightEye_X \\\n", + "0 [0.461303,0.461805,0.462395,0.462959,0.463122,... \n", + "1 [0.450075,0.450722,0.451349,0.452002,0.452172,... \n", + "2 [0.464670,0.464618,0.464613,0.464606,0.464599,... \n", + "3 [0.525598,0.528705,0.529607,0.529693,0.529688,... \n", + "4 [0.499859,0.499486,0.499479,0.499499,0.499556,... \n", + ".. ... \n", + "555 [0.565955,0.565624,0.565546,0.565457,0.566247,... \n", + "556 [0.520413,0.520586,0.519840,0.519523,0.519537,... \n", + "557 [0.406919,0.407048,0.407155,0.407375,0.407649,... \n", + "558 [0.526415,0.526580,0.526635,0.526828,0.526959,... \n", + "559 [0.507183,0.507388,0.507843,0.507606,0.507431,... \n", + "\n", + " rightEye_Y \\\n", + "0 [0.276863,0.278502,0.279791,0.280531,0.280942,... \n", + "1 [0.302042,0.301742,0.301553,0.301575,0.301589,... \n", + "2 [0.342834,0.343746,0.344376,0.344640,0.345239,... \n", + "3 [0.376735,0.379062,0.379977,0.381287,0.382156,... \n", + "4 [0.319383,0.320213,0.321349,0.322067,0.322843,... \n", + ".. ... \n", + "555 [0.485883,0.485947,0.486004,0.485994,0.486090,... \n", + "556 [0.352025,0.352860,0.353801,0.354090,0.355025,... \n", + "557 [0.323748,0.324836,0.326162,0.327786,0.329353,... \n", + "558 [0.542624,0.542402,0.542402,0.542387,0.542231,... \n", + "559 [0.266559,0.266555,0.266612,0.266608,0.266449,... \n", + "\n", + " leftEar_X \\\n", + "0 [0.558462,0.557758,0.557173,0.556385,0.555548,... \n", + "1 [0.571113,0.571111,0.571020,0.570947,0.570956,... \n", + "2 [0.589977,0.589761,0.589638,0.589578,0.589559,... \n", + "3 [0.654602,0.652928,0.651517,0.649746,0.648452,... \n", + "4 [0.614189,0.611145,0.609677,0.608775,0.608422,... \n", + ".. ... \n", + "555 [0.695397,0.695193,0.695191,0.695250,0.695459,... \n", + "556 [0.679821,0.679411,0.678846,0.678844,0.678880,... \n", + "557 [0.526903,0.526998,0.527116,0.527220,0.527326,... \n", + "558 [0.662978,0.662662,0.662170,0.661898,0.661687,... \n", + "559 [0.597032,0.597237,0.597694,0.598045,0.598189,... \n", + "\n", + " leftEar_Y \\\n", + "0 [0.304631,0.305481,0.306485,0.306842,0.306911,... \n", + "1 [0.315368,0.314974,0.315351,0.315415,0.315432,... \n", + "2 [0.373605,0.372651,0.372061,0.371614,0.371254,... \n", + "3 [0.414657,0.417255,0.418721,0.419629,0.420523,... \n", + "4 [0.339505,0.339731,0.339752,0.339752,0.339768,... \n", + ".. ... \n", + "555 [0.516024,0.516022,0.516945,0.516905,0.516701,... \n", + "556 [0.415243,0.415450,0.415431,0.415466,0.415461,... \n", + "557 [0.355733,0.356432,0.357204,0.357981,0.358690,... \n", + "558 [0.577477,0.579208,0.581354,0.582389,0.582804,... \n", + "559 [0.297459,0.297435,0.297352,0.296939,0.296923,... \n", + "\n", + " rightEar_X \\\n", + "0 [0.432248,0.432255,0.432270,0.432289,0.432280,... \n", + "1 [0.411997,0.412929,0.413561,0.414035,0.414218,... \n", + "2 [0.439167,0.439298,0.439412,0.439468,0.439555,... \n", + "3 [0.487122,0.489352,0.490052,0.490523,0.490764,... \n", + "4 [0.469407,0.469407,0.469571,0.469696,0.469925,... \n", + ".. ... \n", + "555 [0.538066,0.539230,0.539818,0.540210,0.541056,... \n", + "556 [0.473096,0.472687,0.471395,0.470902,0.470860,... \n", + "557 [0.381000,0.381048,0.381127,0.381257,0.381449,... \n", + "558 [0.492118,0.492225,0.492262,0.492301,0.492397,... \n", + "559 [0.477034,0.477224,0.477629,0.477716,0.477724,... \n", + "\n", + " rightEar_Y ... split \\\n", + "0 [0.300599,0.302358,0.303453,0.304156,0.304925,... ... train \n", + "1 [0.322391,0.322607,0.322609,0.322896,0.323251,... ... train \n", + "2 [0.369968,0.371493,0.372602,0.372962,0.373442,... ... train \n", + "3 [0.389374,0.393725,0.396954,0.398778,0.399780,... ... train \n", + "4 [0.340159,0.340279,0.340594,0.340797,0.340932,... ... train \n", + ".. ... ... ... \n", + "555 [0.520784,0.520945,0.521081,0.520950,0.520934,... ... train \n", + "556 [0.389405,0.390338,0.391198,0.391376,0.391626,... ... train \n", + "557 [0.345693,0.345312,0.345154,0.345138,0.345149,... ... train \n", + "558 [0.553820,0.556338,0.558264,0.559222,0.559432,... ... train \n", + "559 [0.294895,0.294492,0.294483,0.294487,0.294418,... ... train \n", + "\n", + " video_id labels label_name video_width \\\n", + "0 B!train!2_20230301114043553439_H4EER 0 B 640.0 \n", + "1 D!train!4_20230228231932508739_203WJ 1 D 640.0 \n", + "2 X!train!24_20230313193727472324_QZ48Y 2 X 640.0 \n", + "3 O!train!15_20230316130349891667_94GK7 3 O 640.0 \n", + "4 W!train!23_20230307162255985290_ZET4J 5 W 640.0 \n", + ".. ... ... ... ... \n", + "555 F!train!6_20230306192746737772_PBKJJ 24 F 640.0 \n", + "556 X!train!24_20230318150756432389_T1XTN 2 X 640.0 \n", + "557 Z!train!26_20230313164104308046_EDP6L 14 Z 640.0 \n", + "558 Y!train!25_20230313125334541132_UB003 8 Y 640.0 \n", + "559 W!train!23_20230307164435248346_FGQVL 5 W 640.0 \n", + "\n", + " video_height fps length tsne_x tsne_y \n", + "0 480.0 30.000000 3.933333 -5.145745 10.443328 \n", + "1 480.0 15.000000 4.000000 -1.611456 -13.267664 \n", + "2 480.0 16.666667 3.840000 -8.379868 -9.681334 \n", + "3 480.0 30.000000 3.933333 -3.468011 19.879887 \n", + "4 480.0 30.000000 3.933333 -13.819662 9.518650 \n", + ".. ... ... ... ... ... \n", + "555 480.0 14.985015 3.937267 0.850391 9.577452 \n", + "556 480.0 1000.000000 2.542000 6.209669 -17.046406 \n", + "557 480.0 30.000000 3.600000 7.305971 -23.761284 \n", + "558 480.0 1000.000000 3.902000 9.304266 10.654608 \n", + "559 480.0 1000.000000 3.198000 -14.610600 8.728515 \n", + "\n", + "[560 rows x 118 columns]" + ] + }, + "execution_count": 134, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df" ] diff --git a/predictions/k_nearest.py b/predictions/k_nearest.py new file mode 100644 index 0000000..2bf95d9 --- /dev/null +++ b/predictions/k_nearest.py @@ -0,0 +1,93 @@ +import numpy as np +from collections import Counter + +# TODO scaling van distance tov intra distances? +# TODO efficientere manier om k=1 te doen + + +def minkowski_distance_p(x, y, p=2): + x = np.asarray(x) + y = np.asarray(y) + + # Find the smallest common datatype with float64 (return type of this + # function) - addresses #10262. + # Don't just cast to float64 for complex input case. + common_datatype = np.promote_types(np.promote_types(x.dtype, y.dtype), + 'float64') + + # Make sure x and y are NumPy arrays of correct datatype. + x = x.astype(common_datatype) + y = y.astype(common_datatype) + + if p == np.inf: + return np.amax(np.abs(y - x), axis=-1) + elif p == 1: + return np.sum(np.abs(y - x), axis=-1) + else: + return np.sum(np.abs(y - x) ** p, axis=-1) + + +def minkowski_distance(x, y, p=2): + x = np.asarray(x) + y = np.asarray(y) + if p == np.inf or p == 1: + return minkowski_distance_p(x, y, p) + else: + return minkowski_distance_p(x, y, p) ** (1. / p) + + +class KNearestNeighbours: + def __init__(self, k=5): + self.k = k + self.embeddings = None + self.embeddings_list = None + + def set_embeddings(self, embeddings): + self.embeddings = embeddings + df = embeddings.drop(columns=['labels', 'label_name', 'embeddings']) + # convert embedding from string to list of floats + df["embeddings"] = df["embeddings2"].apply(lambda x: [float(i) for i in x[1:-1].split(", ")]) + # drop embeddings2 + df = df.drop(columns=['embeddings2']) + # to list + self.embeddings_list = df["embeddings"].tolist() + + def distance_matrix(self, keypoints, p=2, threshold=1000000): + x = np.array(keypoints) + m, k = x.shape + y = np.asarray(self.embeddings_list) + n, kk = y.shape + + if k != kk: + raise ValueError(f"x contains {k}-dimensional vectors but y contains " + f"{kk}-dimensional vectors") + + if m * n * k <= threshold: + # print("Using minkowski_distance") + return minkowski_distance(x[:, np.newaxis, :], y[np.newaxis, :, :], p) + else: + result = np.empty((m, n), dtype=float) # FIXME: figure out the best dtype + if m < n: + for i in range(m): + result[i, :] = minkowski_distance(x[i], y, p) + else: + for j in range(n): + result[:, j] = minkowski_distance(x, y[j], p) + return result + + def predict(self, key_points_embeddings): + # calculate distance matrix + dist_matrix = self.distance_matrix(key_points_embeddings, p=2, threshold=1000000) + + # get the 5 closest matches and select the class that is most common and use the average distance as the score + # get the 5 closest matches + indeces = np.argsort(dist_matrix)[0][:self.k] + # get the labels + labels = self.embeddings["label_name"].iloc[indeces].tolist() + c = Counter(labels).most_common()[0][0] + + # filter indeces to only include the most common label + indeces = [i for i in indeces if self.embeddings["label_name"].iloc[i] == c] + # get the average distance + score = np.mean(dist_matrix[0][indeces]) + return c, score diff --git a/predictions/plotting.py b/predictions/plotting.py new file mode 100644 index 0000000..ea08a72 --- /dev/null +++ b/predictions/plotting.py @@ -0,0 +1,86 @@ +import json + +from matplotlib import pyplot as plt + + +def load_results(): + with open("predictions/test_results/knn.json", 'r') as f: + results = json.load(f) + return results + +def plot_all(): + results = load_results() + print(f"average elapsed time to detect a sign: {get_general_elapsed_time(results)}") + plot_general_accuracy(results) + for label in results.keys(): + plot_accuracy_per_label(results, label) + + +def general_accuracy(results): + label_accuracy = get_label_accuracy(results) + accuracy = [] + amount = [] + response = [] + for label in label_accuracy.keys(): + for index, value in enumerate(label_accuracy[label]): + if index >= len(accuracy): + accuracy.append(0) + amount.append(0) + accuracy[index] += label_accuracy[label][index] + amount[index] += 1 + for a, b in zip(accuracy, amount): + if b < 5: + break + response.append(a / b) + return response +def plot_general_accuracy(results): + accuracy = general_accuracy(results) + plt.plot(accuracy) + plt.title = "General accuracy" + plt.ylabel('accuracy') + plt.xlabel('buffer') + plt.show() + + +def plot_accuracy_per_label(results, label): + accuracy = get_label_accuracy(results) + plt.plot(accuracy[label], label=label) + plt.titel = f"Accuracy per label {label}" + plt.ylabel('accuracy') + plt.xlabel('prediction') + plt.legend() + plt.show() + +def get_label_accuracy(results): + accuracy = {} + amount = {} + response = {} + for label, predictions in results.items(): + if label not in accuracy: + accuracy[label] = [] + amount[label] = [] + for prediction in predictions: + for index, value in enumerate(prediction["predictions"]): + if index >= len(accuracy[label]): + accuracy[label].append(0) + amount[label].append(0) + accuracy[label][index] += 1 if value["correct"] else 0 + amount[label][index] += 1 + for label in accuracy: + response[label] = [] + for index, value in enumerate(accuracy[label]): + if amount[label][index] < 2: + break + response[label].append(accuracy[label][index] / amount[label][index]) + return response + +def get_general_elapsed_time(results): + label_time = get_label_elapsed_time(results) + return sum([label_time[label] for label in results]) / len(results) + +def get_label_elapsed_time(results): + return {label: sum([result["elapsed_time"] for result in results[label]]) / len(results[label]) for label in results} + + +if __name__ == '__main__': + plot_all() diff --git a/predictions/predictor.py b/predictions/predictor.py new file mode 100644 index 0000000..f8584f0 --- /dev/null +++ b/predictions/predictor.py @@ -0,0 +1,267 @@ +import cv2 +import mediapipe as mp +import numpy as np +import pandas as pd +import torch + +from predictions.k_nearest import KNearestNeighbours + +device = torch.device("cpu") +if torch.cuda.is_available(): + device = torch.device("cuda") +from models import SPOTER_EMBEDDINGS + +BODY_IDENTIFIERS = [ + 0, + 33, + 5, + 2, + 8, + 7, + 12, + 11, + 14, + 13, + 16, + 15, +] + +HAND_IDENTIFIERS = [ + 0, + 8, + 7, + 6, + 5, + 12, + 11, + 10, + 9, + 16, + 15, + 14, + 13, + 20, + 19, + 18, + 17, + 4, + 3, + 2, + 1, +] + +CHECKPOINT_PATH = "checkpoints/checkpoint_embed_1105.pth" + + +class Predictor: + def __init__(self, embeddings_path, predictor_type): + + # Initialize MediaPipe Hands model + self.holistic = mp.solutions.holistic.Holistic( + min_detection_confidence=0.5, + min_tracking_confidence=0.5, + model_complexity=2 + ) + + self.mp_holistic = mp.solutions.holistic + self.mp_drawing = mp.solutions.drawing_utils + # buffer = [] + self.left_shoulder_index = 11 + self.right_shoulder_index = 12 + self.neck_index = 33 + self.nose_index = 0 + self.left_eye_index = 2 + + # load training embedding csv + self.embeddings = pd.read_csv(embeddings_path) + + checkpoint = torch.load(CHECKPOINT_PATH, map_location=device) + + self.model = SPOTER_EMBEDDINGS( + features=checkpoint["config_args"].vector_length, + hidden_dim=checkpoint["config_args"].hidden_dim, + norm_emb=checkpoint["config_args"].normalize_embeddings, + ).to(device) + + self.model.load_state_dict(checkpoint["state_dict"]) + + if predictor_type is None: + self.predictor = KNearestNeighbours(1) + else: + self.predictor = predictor_type + self.predictor.set_embeddings(self.embeddings) + + def extract_keypoints(self, image_orig): + image = cv2.cvtColor(image_orig, cv2.COLOR_BGR2RGB) + results = self.holistic.process(image) + + def extract_keypoints(lmks): + if lmks: + a = np.array([[float(lmk.x), float(lmk.y)] for lmk in lmks.landmark]) + return a + return None + + def calculate_neck(keypoints): + if keypoints is not None: + left_shoulder = keypoints[11] + right_shoulder = keypoints[12] + + neck = [(float(left_shoulder[0]) + float(right_shoulder[0])) / 2, + (float(left_shoulder[1]) + float(right_shoulder[1])) / 2] + # add neck to keypoints + keypoints = np.append(keypoints, [neck], axis=0) + return keypoints + return None + + pose = extract_keypoints(results.pose_landmarks) + pose = calculate_neck(pose) + if pose is None: + return None + pose_norm = self.normalize_pose(pose) + # filter out keypoints that are not in BODY_IDENTIFIERS and make sure they are in the correct order + pose_norm = pose_norm[BODY_IDENTIFIERS] + + left_hand = extract_keypoints(results.left_hand_landmarks) + right_hand = extract_keypoints(results.right_hand_landmarks) + + if left_hand is None and right_hand is None: + return None + + # normalize hands + if left_hand is not None: + left_hand = self.normalize_hand(left_hand) + else: + left_hand = np.zeros((21, 2)) + if right_hand is not None: + right_hand = self.normalize_hand(right_hand) + else: + right_hand = np.zeros((21, 2)) + + left_hand = left_hand[HAND_IDENTIFIERS] + + right_hand = right_hand[HAND_IDENTIFIERS] + + # combine pose and hands + pose_norm = np.append(pose_norm, left_hand, axis=0) + pose_norm = np.append(pose_norm, right_hand, axis=0) + + # move interval + pose_norm -= 0.5 + + return pose_norm + + # if we have the keypoints, normalize single body, keypoints is numpy array of (identifiers, 2) + def normalize_pose(self, keypoints): + left_shoulder = keypoints[self.left_shoulder_index] + right_shoulder = keypoints[self.right_shoulder_index] + + neck = keypoints[self.neck_index] + nose = keypoints[self.nose_index] + + # Prevent from even starting the analysis if some necessary elements are not present + if (left_shoulder[0] == 0 or right_shoulder[0] == 0 + or (left_shoulder[0] == right_shoulder[0] and left_shoulder[1] == right_shoulder[1])) and ( + neck[0] == 0 or nose[0] == 0 or (neck[0] == nose[0] and neck[1] == nose[1])): + return keypoints + + if left_shoulder[0] != 0 and right_shoulder[0] != 0 and ( + left_shoulder[0] != right_shoulder[0] or left_shoulder[1] != right_shoulder[1]): + shoulder_distance = ((((left_shoulder[0] - right_shoulder[0]) ** 2) + ( + (left_shoulder[1] - right_shoulder[1]) ** 2)) ** 0.5) + head_metric = shoulder_distance + else: + neck_nose_distance = ((((neck[0] - nose[0]) ** 2) + ((neck[1] - nose[1]) ** 2)) ** 0.5) + head_metric = neck_nose_distance + + # Set the starting and ending point of the normalization bounding box + starting_point = [keypoints[self.neck_index][0] - 3 * head_metric, + keypoints[self.left_eye_index][1] + head_metric] + ending_point = [keypoints[self.neck_index][0] + 3 * head_metric, starting_point[1] - 6 * head_metric] + + if starting_point[0] < 0: + starting_point[0] = 0 + if starting_point[1] < 0: + starting_point[1] = 0 + if ending_point[0] < 0: + ending_point[0] = 0 + if ending_point[1] < 0: + ending_point[1] = 0 + + # Normalize the keypoints + for i in range(len(keypoints)): + keypoints[i][0] = (keypoints[i][0] - starting_point[0]) / (ending_point[0] - starting_point[0]) + keypoints[i][1] = (keypoints[i][1] - ending_point[1]) / (starting_point[1] - ending_point[1]) + + return keypoints + + def normalize_hand(self, keypoints): + x_values = [keypoints[i][0] for i in range(len(keypoints)) if keypoints[i][0] != 0] + y_values = [keypoints[i][1] for i in range(len(keypoints)) if keypoints[i][1] != 0] + + if not x_values or not y_values: + return keypoints + + width, height = max(x_values) - min(x_values), max(y_values) - min(y_values) + if width > height: + delta_x = 0.1 * width + delta_y = delta_x + ((width - height) / 2) + else: + delta_y = 0.1 * height + delta_x = delta_y + ((height - width) / 2) + + starting_point = (min(x_values) - delta_x, min(y_values) - delta_y) + ending_point = (max(x_values) + delta_x, max(y_values) + delta_y) + + if ending_point[0] - starting_point[0] == 0 or ending_point[1] - starting_point[1] == 0: + return keypoints + + # normalize keypoints + for i in range(len(keypoints)): + keypoints[i][0] = (keypoints[i][0] - starting_point[0]) / (ending_point[0] - starting_point[0]) + keypoints[i][1] = (keypoints[i][1] - starting_point[1]) / (ending_point[1] - starting_point[1]) + + return keypoints + + + def get_embedding(self, keypoints): + # run model on frame + self.model.eval() + with torch.no_grad(): + keypoints = torch.from_numpy(np.array([keypoints])).float().to(device) + new_embeddings = self.model(keypoints).cpu().numpy().tolist()[0] + return new_embeddings + + def predict(self, embeddings): + return self.predictor.predict(embeddings) + + def make_prediction(self, keypoints): + # run model on frame + self.model.eval() + with torch.no_grad(): + keypoints = torch.from_numpy(np.array([keypoints])).float().to(device) + new_embeddings = self.model(keypoints).cpu().numpy().tolist()[0] + + return self.predictor.predict(new_embeddings) + + def validation(self): + # load validation data + validation_data = np.load('validation_data.npy', allow_pickle=True) + validation_labels = np.load('validation_labels.npy', allow_pickle=True) + + # run model on validation data + self.model.eval() + with torch.no_grad(): + validation_embeddings = self.model(torch.from_numpy(validation_data).float().to(device)).cpu().numpy() + + # predict validation data + predictions = self.predictor.predict(validation_embeddings) + + # calculate accuracy + correct = 0 + for i in range(len(predictions)): + if predictions[i] == validation_labels[i]: + correct += 1 + accuracy = correct / len(predictions) + print('Accuracy: ' + str(accuracy)) + + diff --git a/predictions/svm_model.py b/predictions/svm_model.py new file mode 100644 index 0000000..c458468 --- /dev/null +++ b/predictions/svm_model.py @@ -0,0 +1,34 @@ +from sklearn import svm + +class SVM: + def __init__(self, type="ovo"): + self.label_name_to_label = None + self.clf = None + self.embeddings_list = None + self.labels = None + self.type = type + + def set_embeddings(self, embeddings): + # convert embedding from string to list of floats + embeddings["embeddings"] = embeddings["embeddings2"].apply(lambda x: [float(i) for i in x[1:-1].split(", ")]) + # drop embeddings2 + df = embeddings.drop(columns=['embeddings2']) + # to list + self.embeddings_list = df["embeddings"].tolist() + self.labels = df["labels"].tolist() + self.label_name_to_label = df[["label_name", "labels"]] + self.label_name_to_label.columns = ["label_name", "label"] + self.label_name_to_label = self.label_name_to_label.drop_duplicates() + + self.train() + + def train(self): + self.clf = svm.SVC(decision_function_shape=self.type, probability=True) + self.clf.fit(self.embeddings_list, self.labels) + + def predict(self, key_points_embeddings): + label = self.clf.predict(key_points_embeddings) + score = self.clf.predict_log_proba(key_points_embeddings) + # TODO fix dictionary + label = label.item() + return self.label_name_to_label.loc[self.label_name_to_label["label"] == label]["label_name"].iloc[0], score[0][label] diff --git a/predictions/test_results/knn.json b/predictions/test_results/knn.json new file mode 100644 index 0000000..cf9aed8 --- /dev/null +++ b/predictions/test_results/knn.json @@ -0,0 +1 @@ +{"E": [{"predictions": [{"label": "S", "score": 2.190137280056244, "label_video": "E", "correct": false}, {"label": "S", "score": 2.265894461548086, "label_video": "E", "correct": false}, {"label": "S", "score": 2.3252602702018343, "label_video": "E", "correct": false}, {"label": "S", "score": 2.332154059953553, "label_video": "E", "correct": false}, {"label": "S", "score": 2.3138604941087015, "label_video": "E", "correct": false}, {"label": "S", "score": 2.29974197159059, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2709755486463132, "label_video": "E", "correct": false}, {"label": "S", "score": 2.1818039569585133, "label_video": "E", "correct": false}], "elapsed_time": 1.2231944799423218, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230313163125014477_8TJDN.mp4"}, {"predictions": [{"label": "E", "score": 2.166597357753879, "label_video": "E", "correct": true}, {"label": "E", "score": 2.0005266910270643, "label_video": "E", "correct": true}, {"label": "E", "score": 1.890655110038001, "label_video": "E", "correct": true}, {"label": "E", "score": 1.8288562962562633, "label_video": "E", "correct": true}, {"label": "E", "score": 1.8256607047046791, "label_video": "E", "correct": true}, {"label": "E", "score": 1.8086739273931849, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7818514088016821, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7577802964559444, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7365194632666703, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7210284808378644, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7200616215414366, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7196277117983136, "label_video": "E", "correct": true}, {"label": "E", "score": 1.721667095999382, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7321930562455028, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7607394205457891, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7385430126888015, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7028085444670018, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7295273749607436, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7988718449759884, "label_video": "E", "correct": true}], "elapsed_time": 0.7463110497123316, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230228222625583933_TIKL7.mp4"}, {"predictions": [{"label": "W", "score": 2.8072052883597256, "label_video": "E", "correct": false}, {"label": "E", "score": 2.7569202399231107, "label_video": "E", "correct": true}, {"label": "E", "score": 2.684126512350632, "label_video": "E", "correct": true}, {"label": "E", "score": 2.6469213160561718, "label_video": "E", "correct": true}, {"label": "E", "score": 2.644743464072631, "label_video": "E", "correct": true}, {"label": "E", "score": 2.6782830664552755, "label_video": "E", "correct": true}, {"label": "E", "score": 2.718583155767106, "label_video": "E", "correct": true}, {"label": "E", "score": 2.7472647785384794, "label_video": "E", "correct": true}, {"label": "E", "score": 2.7158228550246624, "label_video": "E", "correct": true}, {"label": "E", "score": 2.6854780779917204, "label_video": "E", "correct": true}], "elapsed_time": 1.4933396100997924, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230301112854628464_X3R8E.mp4"}, {"predictions": [{"label": "S", "score": 2.528388695606183, "label_video": "E", "correct": false}, {"label": "S", "score": 2.584524414029524, "label_video": "E", "correct": false}, {"label": "S", "score": 2.6456725243451644, "label_video": "E", "correct": false}, {"label": "S", "score": 2.624085926323849, "label_video": "E", "correct": false}, {"label": "S", "score": 2.5974478857490206, "label_video": "E", "correct": false}, {"label": "S", "score": 2.5975275134893754, "label_video": "E", "correct": false}], "elapsed_time": 1.7039889097213745, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230228212226677814_SBH8Y.mp4"}, {"predictions": [{"label": "I", "score": 2.6150372387252907, "label_video": "E", "correct": false}, {"label": "I", "score": 2.7650428741969764, "label_video": "E", "correct": false}, {"label": "I", "score": 2.78368774410185, "label_video": "E", "correct": false}, {"label": "I", "score": 2.8005089346007024, "label_video": "E", "correct": false}, {"label": "I", "score": 2.778125324528488, "label_video": "E", "correct": false}, {"label": "I", "score": 2.728640795418373, "label_video": "E", "correct": false}, {"label": "I", "score": 2.7150811351221216, "label_video": "E", "correct": false}, {"label": "I", "score": 2.7044701100785984, "label_video": "E", "correct": false}, {"label": "I", "score": 2.70659929614657, "label_video": "E", "correct": false}, {"label": "I", "score": 2.7026573562851106, "label_video": "E", "correct": false}, {"label": "I", "score": 2.6932856756858876, "label_video": "E", "correct": false}, {"label": "I", "score": 2.6871437139594407, "label_video": "E", "correct": false}, {"label": "I", "score": 2.681449077923473, "label_video": "E", "correct": false}, {"label": "I", "score": 2.6751640438422224, "label_video": "E", "correct": false}, {"label": "I", "score": 2.6628070211540096, "label_video": "E", "correct": false}, {"label": "I", "score": 2.652167939651586, "label_video": "E", "correct": false}, {"label": "I", "score": 2.6502538533968627, "label_video": "E", "correct": false}, {"label": "I", "score": 2.632983081984754, "label_video": "E", "correct": false}, {"label": "I", "score": 2.645524838517422, "label_video": "E", "correct": false}], "elapsed_time": 0.7248871075479608, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230225172811197744_I9HWY.mp4"}, {"predictions": [{"label": "S", "score": 2.108136647111057, "label_video": "E", "correct": false}, {"label": "S", "score": 2.1507763278782535, "label_video": "E", "correct": false}, {"label": "S", "score": 2.1960575697280156, "label_video": "E", "correct": false}, {"label": "S", "score": 2.24306483144525, "label_video": "E", "correct": false}, {"label": "S", "score": 2.258846517763946, "label_video": "E", "correct": false}, {"label": "S", "score": 2.259834471201342, "label_video": "E", "correct": false}, {"label": "S", "score": 2.254240242633714, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2468259012490712, "label_video": "E", "correct": false}, {"label": "S", "score": 2.240154571661751, "label_video": "E", "correct": false}, {"label": "S", "score": 2.234526205928132, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2314242991641953, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2275836624424685, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2247259384371167, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2216763591514654, "label_video": "E", "correct": false}, {"label": "S", "score": 2.218010203779102, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2152956207952, "label_video": "E", "correct": false}, {"label": "S", "score": 2.211719646108808, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2076744399039683, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2035600443680994, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2035880054612482, "label_video": "E", "correct": false}, {"label": "S", "score": 2.209043171419028, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2176616454597307, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2292647855477954, "label_video": "E", "correct": false}, {"label": "S", "score": 2.237358246348353, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2338297005715164, "label_video": "E", "correct": false}, {"label": "S", "score": 2.2389897833142274, "label_video": "E", "correct": false}], "elapsed_time": 0.5641147356766921, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230313160925785353_26854.mp4"}, {"predictions": [{"label": "E", "score": 1.7355053298540994, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7578229997867918, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7937993263075802, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7045767531248075, "label_video": "E", "correct": true}, {"label": "E", "score": 1.5995661414480855, "label_video": "E", "correct": true}, {"label": "E", "score": 1.505937480567229, "label_video": "E", "correct": true}, {"label": "E", "score": 1.4316545670000786, "label_video": "E", "correct": true}, {"label": "E", "score": 1.379622094946395, "label_video": "E", "correct": true}, {"label": "E", "score": 1.3361880277648945, "label_video": "E", "correct": true}, {"label": "E", "score": 1.303315788665923, "label_video": "E", "correct": true}, {"label": "E", "score": 1.278531000746199, "label_video": "E", "correct": true}, {"label": "E", "score": 1.2567457545332381, "label_video": "E", "correct": true}, {"label": "E", "score": 1.239767225887907, "label_video": "E", "correct": true}, {"label": "E", "score": 1.2328864582680286, "label_video": "E", "correct": true}, {"label": "E", "score": 1.2332663783398283, "label_video": "E", "correct": true}, {"label": "E", "score": 1.3432010611672403, "label_video": "E", "correct": true}, {"label": "E", "score": 1.545565681236631, "label_video": "E", "correct": true}, {"label": "E", "score": 1.7922144688263122, "label_video": "E", "correct": true}, {"label": "E", "score": 2.0409035359932766, "label_video": "E", "correct": true}], "elapsed_time": 0.47628065159446314, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230228222723769152_80Z8G.mp4"}, {"predictions": [{"label": "S", "score": 2.2644626404987496, "label_video": "E", "correct": false}, {"label": "S", "score": 2.3267948157962555, "label_video": "E", "correct": false}, {"label": "S", "score": 2.3753592192845185, "label_video": "E", "correct": false}, {"label": "S", "score": 2.4100022434556383, "label_video": "E", "correct": false}, {"label": "S", "score": 2.420097222073198, "label_video": "E", "correct": false}, {"label": "S", "score": 2.42832725988638, "label_video": "E", "correct": false}, {"label": "S", "score": 2.4298514363828065, "label_video": "E", "correct": false}, {"label": "S", "score": 2.4169307110930904, "label_video": "E", "correct": false}, {"label": "S", "score": 2.4042945732500676, "label_video": "E", "correct": false}, {"label": "S", "score": 2.381076398902999, "label_video": "E", "correct": false}, {"label": "S", "score": 2.3554080014062677, "label_video": "E", "correct": false}], "elapsed_time": 1.032421263781461, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/E!test!5_20230301111033511290_KUCFK.mp4"}], "O": [{"predictions": [{"label": "F", "score": 2.3261498085068117, "label_video": "O", "correct": false}, {"label": "F", "score": 2.50896151041909, "label_video": "O", "correct": false}, {"label": "F", "score": 2.565945011247159, "label_video": "O", "correct": false}, {"label": "F", "score": 2.5153920269968792, "label_video": "O", "correct": false}, {"label": "F", "score": 2.486196071342428, "label_video": "O", "correct": false}, {"label": "F", "score": 2.4476926460116886, "label_video": "O", "correct": false}, {"label": "F", "score": 2.4285582581384633, "label_video": "O", "correct": false}, {"label": "F", "score": 2.423863392633778, "label_video": "O", "correct": false}, {"label": "F", "score": 2.4167157360692784, "label_video": "O", "correct": false}, {"label": "F", "score": 2.411892599916059, "label_video": "O", "correct": false}, {"label": "F", "score": 2.3966725881056186, "label_video": "O", "correct": false}, {"label": "F", "score": 2.381665979082131, "label_video": "O", "correct": false}, {"label": "F", "score": 2.3760690332417247, "label_video": "O", "correct": false}, {"label": "F", "score": 2.366975483616101, "label_video": "O", "correct": false}, {"label": "F", "score": 2.357391621611846, "label_video": "O", "correct": false}, {"label": "F", "score": 2.3336606612147737, "label_video": "O", "correct": false}, {"label": "F", "score": 2.3275322742029014, "label_video": "O", "correct": false}, {"label": "F", "score": 2.3827769309971027, "label_video": "O", "correct": false}, {"label": "F", "score": 2.0942451618898055, "label_video": "O", "correct": false}, {"label": "F", "score": 1.8953301801900535, "label_video": "O", "correct": false}], "elapsed_time": 0.49619457721710203, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/O!test!15_20230324145140727510_GV6KU.mp4"}, {"predictions": [{"label": "O", "score": 2.0027144635276293, "label_video": "O", "correct": true}, {"label": "O", "score": 1.916255603702779, "label_video": "O", "correct": true}, {"label": "O", "score": 1.9611054011353952, "label_video": "O", "correct": true}, {"label": "O", "score": 1.980939010816558, "label_video": "O", "correct": true}, {"label": "O", "score": 1.9881187827814706, "label_video": "O", "correct": true}, {"label": "O", "score": 2.0011049261340124, "label_video": "O", "correct": true}, {"label": "O", "score": 2.013036621295981, "label_video": "O", "correct": true}, {"label": "O", "score": 2.0305553948850386, "label_video": "O", "correct": true}, {"label": "O", "score": 2.046294430682596, "label_video": "O", "correct": true}, {"label": "O", "score": 2.056655428497203, "label_video": "O", "correct": true}, {"label": "O", "score": 2.011573537594876, "label_video": "O", "correct": true}, {"label": "O", "score": 1.9726298771492914, "label_video": "O", "correct": true}, {"label": "O", "score": 1.9796402202349164, "label_video": "O", "correct": true}, {"label": "O", "score": 2.001106593126245, "label_video": "O", "correct": true}, {"label": "O", "score": 2.0434188808885043, "label_video": "O", "correct": true}], "elapsed_time": 0.6964441299438476, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/O!test!15_20230313161001708086_84P2Y.mp4"}, {"predictions": [{"label": "O", "score": 2.000605534800153, "label_video": "O", "correct": true}, {"label": "O", "score": 2.1916175642974753, "label_video": "O", "correct": true}, {"label": "O", "score": 2.2582970514743836, "label_video": "O", "correct": true}, {"label": "C", "score": 2.2079147322613704, "label_video": "O", "correct": false}, {"label": "C", "score": 2.198147980050692, "label_video": "O", "correct": false}, {"label": "O", "score": 2.161718749898936, "label_video": "O", "correct": true}, {"label": "O", "score": 1.9194568168850605, "label_video": "O", "correct": true}], "elapsed_time": 1.4628337110791887, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/O!test!15_20230307105210876800_7CHCO.mp4"}, {"predictions": [{"label": "O", "score": 2.0847329722712287, "label_video": "O", "correct": true}, {"label": "O", "score": 2.112314915673618, "label_video": "O", "correct": true}, {"label": "O", "score": 2.1442195556263433, "label_video": "O", "correct": true}, {"label": "O", "score": 2.159599089556211, "label_video": "O", "correct": true}, {"label": "O", "score": 2.1519303173187714, "label_video": "O", "correct": true}, {"label": "O", "score": 2.159751104070638, "label_video": "O", "correct": true}, {"label": "O", "score": 2.165239018629952, "label_video": "O", "correct": true}, {"label": "O", "score": 2.182593115889716, "label_video": "O", "correct": true}, {"label": "O", "score": 2.2069072663012363, "label_video": "O", "correct": true}, {"label": "O", "score": 2.232165396040678, "label_video": "O", "correct": true}, {"label": "O", "score": 2.2215687018209382, "label_video": "O", "correct": true}], "elapsed_time": 1.2745911208066074, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/O!test!15_20230312122247191901_T173O.mp4"}], "A": [{"predictions": [{"label": "N", "score": 2.502842651314949, "label_video": "A", "correct": false}, {"label": "N", "score": 2.5587059942095376, "label_video": "A", "correct": false}, {"label": "N", "score": 2.5303674490018357, "label_video": "A", "correct": false}], "elapsed_time": 1.8489221731821697, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/A!test!161_20230330092955445886_PSMEM.mp4"}], "S": [{"predictions": [{"label": "S", "score": 1.716039674522859, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7734668806015637, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8344348347258221, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8420545290525645, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8341208543762357, "label_video": "S", "correct": true}, {"label": "S", "score": 1.808703075653552, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7849513030188886, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7629903131800642, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7403400060361227, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7192775315617341, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7009284407465006, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6875012447214632, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6750967864497146, "label_video": "S", "correct": true}, {"label": "S", "score": 1.66416751250942, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6559323911119435, "label_video": "S", "correct": true}, {"label": "S", "score": 1.646520556964503, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6352838938606313, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6070300944243696, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5604203550359794, "label_video": "S", "correct": true}], "elapsed_time": 0.5266764916871723, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230312121854024043_55ZUE.mp4"}, {"predictions": [{"label": "S", "score": 1.8352949801140988, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7495565262037258, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7403631094666123, "label_video": "S", "correct": true}, {"label": "S", "score": 1.714273543703028, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6860791819047762, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6774602329249553, "label_video": "S", "correct": true}, {"label": "S", "score": 1.678372293840499, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6834180449801457, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7129980792239785, "label_video": "S", "correct": true}, {"label": "S", "score": 1.747419984408787, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8025909973564112, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8387994273648964, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8655203315658875, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8763084960060077, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8842123322362185, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8799885800340517, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8803398010673784, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8798412615553697, "label_video": "S", "correct": true}, {"label": "S", "score": 1.889591751877364, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8927896381480311, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9032286466469066, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9195851864414342, "label_video": "S", "correct": true}, {"label": "S", "score": 1.940100421692101, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9613025677271603, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9882577902731353, "label_video": "S", "correct": true}, {"label": "S", "score": 2.008796840837135, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0261088887769296, "label_video": "S", "correct": true}, {"label": "S", "score": 2.042825439078845, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0563277317887745, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0703641703864606, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0797639969234103, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0792713538854026, "label_video": "S", "correct": true}, {"label": "S", "score": 2.079998433229924, "label_video": "S", "correct": true}, {"label": "S", "score": 2.070078837661669, "label_video": "S", "correct": true}, {"label": "S", "score": 2.063287773034918, "label_video": "S", "correct": true}, {"label": "S", "score": 2.056972567243449, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0522423606112885, "label_video": "S", "correct": true}, {"label": "S", "score": 2.048212587182319, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0462123862086794, "label_video": "S", "correct": true}, {"label": "S", "score": 2.03434518165927, "label_video": "S", "correct": true}, {"label": "S", "score": 2.023365803522765, "label_video": "S", "correct": true}, {"label": "S", "score": 2.021121663847045, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0181973445575516, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0178934527456462, "label_video": "S", "correct": true}, {"label": "S", "score": 2.016323665965047, "label_video": "S", "correct": true}, {"label": "S", "score": 2.017843860494682, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0205513467273852, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0221325780908472, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0266579130591484, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0291776925766394, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0299701415555504, "label_video": "S", "correct": true}, {"label": "S", "score": 2.030140708412324, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0258305485882304, "label_video": "S", "correct": true}, {"label": "S", "score": 2.017732934454221, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0330900570581143, "label_video": "S", "correct": true}, {"label": "S", "score": 2.0300794699425144, "label_video": "S", "correct": true}, {"label": "S", "score": 2.020308155970905, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9803381048613822, "label_video": "S", "correct": true}, {"label": "S", "score": 1.9147529446112015, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8624678407714073, "label_video": "S", "correct": true}, {"label": "S", "score": 1.8025727074847524, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7477009471533758, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7141500580153222, "label_video": "S", "correct": true}], "elapsed_time": 0.23932316189720518, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230307122512902333_JZA8B.mp4"}, {"predictions": [{"label": "S", "score": 1.6320972943695307, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6146498360590587, "label_video": "S", "correct": true}, {"label": "S", "score": 1.594954148877431, "label_video": "S", "correct": true}, {"label": "S", "score": 1.570550177669325, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5539396871903448, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5469260928468478, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5441603619594242, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5472105915900478, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5506061020914577, "label_video": "S", "correct": true}, {"label": "S", "score": 1.550581824312194, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5528041863895736, "label_video": "S", "correct": true}, {"label": "S", "score": 1.560581163974628, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5748604970070377, "label_video": "S", "correct": true}], "elapsed_time": 0.8533159769498385, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230313160939569443_1TAZF.mp4"}, {"predictions": [{"label": "S", "score": 1.5881789894003167, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5243579321460168, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5239025625693974, "label_video": "S", "correct": true}, {"label": "S", "score": 1.559913737941981, "label_video": "S", "correct": true}, {"label": "S", "score": 1.60550485644557, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6324015713991775, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6405457450580463, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6426854068811163, "label_video": "S", "correct": true}, {"label": "S", "score": 1.642043777972051, "label_video": "S", "correct": true}, {"label": "S", "score": 1.63536203230168, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6277524022875682, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6268764610001687, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6263034203811497, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6268433581740167, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6147279016403444, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6282129829866339, "label_video": "S", "correct": true}], "elapsed_time": 0.6564424335956573, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230312121919868772_2GX0Q.mp4"}, {"predictions": [{"label": "S", "score": 1.617148611084026, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6229421928598216, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6215842430202758, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6232646583521069, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6217427472425987, "label_video": "S", "correct": true}, {"label": "S", "score": 1.624256834254724, "label_video": "S", "correct": true}, {"label": "S", "score": 1.629102442334176, "label_video": "S", "correct": true}, {"label": "S", "score": 1.637925269540377, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6473122839133685, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6673686369044054, "label_video": "S", "correct": true}], "elapsed_time": 1.3923760652542114, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230313162146181100_W8B5U.mp4"}, {"predictions": [{"label": "S", "score": 1.6165151808478626, "label_video": "S", "correct": true}, {"label": "S", "score": 1.609263546492879, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6230744933905281, "label_video": "S", "correct": true}, {"label": "S", "score": 1.626788589786378, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6209607419778074, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6138710675664563, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6038265368427826, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5857243605674871, "label_video": "S", "correct": true}, {"label": "S", "score": 1.5848178450977726, "label_video": "S", "correct": true}], "elapsed_time": 1.4181531270345051, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230313162028538158_6758G.mp4"}, {"predictions": [{"label": "S", "score": 1.6304359187997934, "label_video": "S", "correct": true}, {"label": "S", "score": 1.728725907680822, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7541537881994766, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7472154796688137, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7398300668249411, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7353090631160526, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7225025279891986, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7132907431969162, "label_video": "S", "correct": true}, {"label": "S", "score": 1.7066149148875593, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6981954039009308, "label_video": "S", "correct": true}, {"label": "S", "score": 1.689595299524582, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6726226417085914, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6393601601240146, "label_video": "S", "correct": true}, {"label": "S", "score": 1.6134250273570476, "label_video": "S", "correct": true}], "elapsed_time": 0.7448362282344273, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/S!test!19_20230313163204448992_WQ0DP.mp4"}], "C": [{"predictions": [{"label": "O", "score": 1.977330945481084, "label_video": "C", "correct": false}, {"label": "C", "score": 1.7647170231646903, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6937199100387557, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7090358252609146, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6876185211540313, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6448948540948924, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6313436269574244, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6053864016429469, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5816096982610461, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5603269467646235, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5530324355545109, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5863704160766836, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6856915357660518, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8516909137221305, "label_video": "C", "correct": true}, {"label": "O", "score": 2.0588977050453643, "label_video": "C", "correct": false}], "elapsed_time": 0.6937832037607828, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230228222900196636_WCUZC.mp4"}, {"predictions": [{"label": "C", "score": 1.9967831496207553, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8680615506591207, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8289634773762726, "label_video": "C", "correct": true}, {"label": "C", "score": 1.858912968792222, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8688283210030625, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8857705157611389, "label_video": "C", "correct": true}, {"label": "C", "score": 1.9030906420926912, "label_video": "C", "correct": true}, {"label": "C", "score": 1.9184281358378532, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8610789577180886, "label_video": "C", "correct": true}, {"label": "C", "score": 1.816401197842238, "label_video": "C", "correct": true}, {"label": "C", "score": 1.8358874299450827, "label_video": "C", "correct": true}, {"label": "C", "score": 1.9287322504444573, "label_video": "C", "correct": true}], "elapsed_time": 0.8738957444826762, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230225172602384205_0L5PV.mp4"}, {"predictions": [{"label": "C", "score": 1.4362341492331705, "label_video": "C", "correct": true}, {"label": "C", "score": 1.4280490210345083, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3767576408775033, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3725693828356726, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3689353544885392, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3733962078443454, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3899848510239632, "label_video": "C", "correct": true}, {"label": "C", "score": 1.4299935543543931, "label_video": "C", "correct": true}], "elapsed_time": 1.4033561646938324, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230301112555258258_J20ZW.mp4"}, {"predictions": [{"label": "C", "score": 2.215148772699183, "label_video": "C", "correct": true}, {"label": "C", "score": 1.858901264239698, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7743399695158817, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7750182704908657, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7567733852324119, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7398553074579732, "label_video": "C", "correct": true}, {"label": "C", "score": 1.6984526153154975, "label_video": "C", "correct": true}, {"label": "C", "score": 1.669164921292031, "label_video": "C", "correct": true}, {"label": "C", "score": 1.654604480955965, "label_video": "C", "correct": true}, {"label": "C", "score": 1.653599724219093, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7985355881414107, "label_video": "C", "correct": true}, {"label": "C", "score": 2.07203750049349, "label_video": "C", "correct": true}], "elapsed_time": 1.0376296440760295, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230228222348734036_7AKPT.mp4"}, {"predictions": [{"label": "C", "score": 1.5854485021834863, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3884778550251369, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3579873074504107, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3691522205206652, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3759127367013437, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3775045433320934, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3868690589062456, "label_video": "C", "correct": true}, {"label": "C", "score": 1.4622217705743823, "label_video": "C", "correct": true}, {"label": "C", "score": 1.7382789351681844, "label_video": "C", "correct": true}, {"label": "C", "score": 2.035754548979554, "label_video": "C", "correct": true}], "elapsed_time": 1.3849168062210082, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230228212119836715_BW57D.mp4"}, {"predictions": [{"label": "C", "score": 1.641134872270149, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5789116017781293, "label_video": "C", "correct": true}, {"label": "C", "score": 1.5161773733246438, "label_video": "C", "correct": true}], "elapsed_time": 3.3825887044270835, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230312122058637918_LQEOR.mp4"}, {"predictions": [{"label": "C", "score": 1.3764627590232508, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3098357578494597, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3007456579038037, "label_video": "C", "correct": true}, {"label": "C", "score": 1.3283153853968315, "label_video": "C", "correct": true}, {"label": "C", "score": 1.2892499212037352, "label_video": "C", "correct": true}], "elapsed_time": 2.214378547668457, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/C!test!3_20230301110903171278_FN72D.mp4"}], "I": [{"predictions": [{"label": "I", "score": 1.8139299591283857, "label_video": "I", "correct": true}, {"label": "I", "score": 1.7494897134756047, "label_video": "I", "correct": true}, {"label": "I", "score": 1.7084415476398935, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6797895557502507, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6667353245927652, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6510832812404386, "label_video": "I", "correct": true}, {"label": "I", "score": 1.637115672500266, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6216009829559839, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6068864213084968, "label_video": "I", "correct": true}, {"label": "I", "score": 1.5859572489034741, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6024396046263814, "label_video": "I", "correct": true}], "elapsed_time": 0.9532940604469993, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230323161011067039_E92MK.mp4"}, {"predictions": [{"label": "I", "score": 1.4753965810681975, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4883175302187204, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4985193116492448, "label_video": "I", "correct": true}, {"label": "I", "score": 1.495023363826316, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4856737905940456, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4743905515290725, "label_video": "I", "correct": true}, {"label": "I", "score": 1.46432082369075, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4561173313565594, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4451434747736638, "label_video": "I", "correct": true}], "elapsed_time": 1.155551142162747, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230313161515860029_2TSJE.mp4"}, {"predictions": [{"label": "I", "score": 3.0524482478962516, "label_video": "I", "correct": true}, {"label": "I", "score": 3.0540120544800824, "label_video": "I", "correct": true}, {"label": "I", "score": 3.0390343709832965, "label_video": "I", "correct": true}, {"label": "I", "score": 2.9977399453311735, "label_video": "I", "correct": true}, {"label": "I", "score": 2.9842761391216936, "label_video": "I", "correct": true}, {"label": "I", "score": 2.998656427402033, "label_video": "I", "correct": true}, {"label": "I", "score": 2.9988163697562933, "label_video": "I", "correct": true}, {"label": "I", "score": 3.031036512827623, "label_video": "I", "correct": true}, {"label": "I", "score": 3.0741581918976166, "label_video": "I", "correct": true}, {"label": "I", "score": 3.1288462731499367, "label_video": "I", "correct": true}, {"label": "I", "score": 3.117791180000039, "label_video": "I", "correct": true}, {"label": "I", "score": 3.0265960814819235, "label_video": "I", "correct": true}, {"label": "I", "score": 2.9074425477608017, "label_video": "I", "correct": true}, {"label": "I", "score": 2.7503537790425048, "label_video": "I", "correct": true}], "elapsed_time": 0.783704331942967, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230304203928258183_HU41F.mp4"}, {"predictions": [{"label": "I", "score": 1.7444761983550743, "label_video": "I", "correct": true}, {"label": "I", "score": 1.9488894306950606, "label_video": "I", "correct": true}, {"label": "I", "score": 2.136447015758643, "label_video": "I", "correct": true}, {"label": "I", "score": 2.2794722745636578, "label_video": "I", "correct": true}, {"label": "I", "score": 2.3578393871952907, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4425784372740416, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4989748763764577, "label_video": "I", "correct": true}, {"label": "I", "score": 2.5378527842785115, "label_video": "I", "correct": true}, {"label": "I", "score": 2.5550169166260717, "label_video": "I", "correct": true}, {"label": "I", "score": 2.5589496352867185, "label_video": "I", "correct": true}, {"label": "I", "score": 2.535707763079276, "label_video": "I", "correct": true}, {"label": "I", "score": 2.5038233726236556, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4777688201287393, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4445347357749774, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4223534864278884, "label_video": "I", "correct": true}, {"label": "I", "score": 2.4008279644944714, "label_video": "I", "correct": true}, {"label": "I", "score": 2.399232060301443, "label_video": "I", "correct": true}, {"label": "I", "score": 2.3991338300155802, "label_video": "I", "correct": true}, {"label": "I", "score": 2.3333373266026065, "label_video": "I", "correct": true}, {"label": "I", "score": 2.1898129071020813, "label_video": "I", "correct": true}], "elapsed_time": 0.5960410594940185, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230304204033566379_RJI6D.mp4"}, {"predictions": [{"label": "I", "score": 1.8377144424465985, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8349144680349858, "label_video": "I", "correct": true}, {"label": "I", "score": 2.044303994450949, "label_video": "I", "correct": true}, {"label": "I", "score": 1.9733982281682871, "label_video": "I", "correct": true}, {"label": "I", "score": 1.9712839143992864, "label_video": "I", "correct": true}, {"label": "I", "score": 1.9206008779214871, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8778746723152273, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8503594713181752, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8379213184308505, "label_video": "I", "correct": true}, {"label": "I", "score": 1.828857985513623, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8185261899593088, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8090914099426132, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8040133377543954, "label_video": "I", "correct": true}, {"label": "I", "score": 1.800734741736591, "label_video": "I", "correct": true}, {"label": "I", "score": 1.7973439996579106, "label_video": "I", "correct": true}, {"label": "I", "score": 1.8626603928167715, "label_video": "I", "correct": true}, {"label": "I", "score": 1.919232706542087, "label_video": "I", "correct": true}, {"label": "I", "score": 2.0623921369357103, "label_video": "I", "correct": true}, {"label": "I", "score": 2.2003906592660116, "label_video": "I", "correct": true}, {"label": "Y", "score": 1.9678664645861255, "label_video": "I", "correct": false}, {"label": "Y", "score": 1.8448572719293748, "label_video": "I", "correct": false}, {"label": "Y", "score": 1.8429107861357439, "label_video": "I", "correct": false}, {"label": "Y", "score": 1.915442002209762, "label_video": "I", "correct": false}, {"label": "Y", "score": 2.0349261437462003, "label_video": "I", "correct": false}], "elapsed_time": 0.6068106194337209, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230309104645114365_GJLCF.mp4"}, {"predictions": [{"label": "I", "score": 1.39264520096394, "label_video": "I", "correct": true}, {"label": "I", "score": 1.5232745710887778, "label_video": "I", "correct": true}, {"label": "I", "score": 1.5994129294441106, "label_video": "I", "correct": true}, {"label": "I", "score": 1.637144947301188, "label_video": "I", "correct": true}, {"label": "I", "score": 1.6346930211566735, "label_video": "I", "correct": true}, {"label": "I", "score": 1.5890836494984741, "label_video": "I", "correct": true}, {"label": "I", "score": 1.5097455394695845, "label_video": "I", "correct": true}, {"label": "I", "score": 1.4281141882959631, "label_video": "I", "correct": true}], "elapsed_time": 1.759196013212204, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/I!test!9_20230313160905289573_TF1UQ.mp4"}], "Q": [{"predictions": [{"label": "Q", "score": 1.5365214951126873, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.52571908880323, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.396588021171409, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3285118805519351, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.2918254098054818, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.2677190956250752, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.27102530635442, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3100740004801605, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3388924996746554, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3581752696246427, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3878658752082789, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.425128668260301, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5290693484131332, "label_video": "Q", "correct": true}], "elapsed_time": 0.8033947027646579, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Q!test!17_20230312122113927354_VF8QE.mp4"}, {"predictions": [{"label": "Q", "score": 1.145618962581248, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.2316790899908723, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3477423173737133, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4041398809063002, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3980818272744342, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4140513344505081, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4046087909834626, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3846990036962046, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3968378607125678, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4027759571846314, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4078143475646256, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4120058920593086, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.4242920890843136, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.419427060310052, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.432529216891046, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.420224393562359, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.3992260630076476, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5173957988487434, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.559382933793285, "label_video": "Q", "correct": true}], "elapsed_time": 0.7156844264582584, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Q!test!17_20230324145302834666_BIX3C.mp4"}, {"predictions": [{"label": "I", "score": 2.2133533219478125, "label_video": "Q", "correct": false}, {"label": "I", "score": 2.280529975215422, "label_video": "Q", "correct": false}, {"label": "Q", "score": 2.1489839958335897, "label_video": "Q", "correct": true}, {"label": "Q", "score": 2.0016970445014963, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.8501674295815542, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.7786353492096318, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.7225088074573882, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.681595408679379, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.653998742326466, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.6083351682705378, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.58122623606575, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5800441161080063, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5785539973636746, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.594725871640634, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.595283910030316, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5986607149165124, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.6004883986086256, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.5835005898128167, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.6280580523588826, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.6847629503700718, "label_video": "Q", "correct": true}, {"label": "Q", "score": 1.8392839671666004, "label_video": "Q", "correct": true}, {"label": "P", "score": 1.8858575741276649, "label_video": "Q", "correct": false}], "elapsed_time": 0.4904535250230269, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Q!test!17_20230307110450465108_H174L.mp4"}], "D": [{"predictions": [{"label": "D", "score": 2.3057575432249444, "label_video": "D", "correct": true}, {"label": "D", "score": 2.1481722493119486, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0767405003245254, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0382236164979526, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0394362312809213, "label_video": "D", "correct": true}, {"label": "D", "score": 2.038240494463748, "label_video": "D", "correct": true}, {"label": "D", "score": 2.036083241664794, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0230946366742124, "label_video": "D", "correct": true}, {"label": "D", "score": 2.01187119272055, "label_video": "D", "correct": true}, {"label": "D", "score": 2.00256880007125, "label_video": "D", "correct": true}, {"label": "D", "score": 1.99568446539218, "label_video": "D", "correct": true}, {"label": "D", "score": 1.992051446345571, "label_video": "D", "correct": true}, {"label": "D", "score": 1.9914216550543862, "label_video": "D", "correct": true}, {"label": "D", "score": 1.986860023373491, "label_video": "D", "correct": true}, {"label": "D", "score": 1.9774050710294389, "label_video": "D", "correct": true}, {"label": "D", "score": 1.906392259315024, "label_video": "D", "correct": true}, {"label": "D", "score": 1.769833292430802, "label_video": "D", "correct": true}], "elapsed_time": 0.6298939480501062, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230301112807012821_XOLFF.mp4"}, {"predictions": [{"label": "D", "score": 2.296772293196052, "label_video": "D", "correct": true}, {"label": "D", "score": 2.3839905842670417, "label_video": "D", "correct": true}, {"label": "D", "score": 2.412333868739108, "label_video": "D", "correct": true}, {"label": "D", "score": 2.445550036995593, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4459384505444888, "label_video": "D", "correct": true}, {"label": "D", "score": 2.446663322938649, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4424593981818, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4620421738819998, "label_video": "D", "correct": true}, {"label": "D", "score": 2.5425306292390215, "label_video": "D", "correct": true}, {"label": "B", "score": 2.4459057842936955, "label_video": "D", "correct": false}], "elapsed_time": 0.8204010248184204, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230228222542563954_XU4DP.mp4"}, {"predictions": [{"label": "B", "score": 2.646583930770677, "label_video": "D", "correct": false}, {"label": "D", "score": 2.450648039352872, "label_video": "D", "correct": true}, {"label": "D", "score": 2.2266784800471435, "label_video": "D", "correct": true}, {"label": "D", "score": 2.262271776861452, "label_video": "D", "correct": true}, {"label": "D", "score": 2.291499068238272, "label_video": "D", "correct": true}, {"label": "D", "score": 2.29137097688987, "label_video": "D", "correct": true}, {"label": "D", "score": 2.2892284520706703, "label_video": "D", "correct": true}, {"label": "D", "score": 2.3003307015670225, "label_video": "D", "correct": true}, {"label": "D", "score": 2.324030719059365, "label_video": "D", "correct": true}, {"label": "D", "score": 2.3573724090922674, "label_video": "D", "correct": true}, {"label": "D", "score": 2.3844152315599976, "label_video": "D", "correct": true}, {"label": "D", "score": 2.409450254352556, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4460756416604275, "label_video": "D", "correct": true}, {"label": "D", "score": 2.425115835744681, "label_video": "D", "correct": true}, {"label": "D", "score": 2.3624431369834835, "label_video": "D", "correct": true}], "elapsed_time": 0.9687370141347249, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230301111013123514_TXYDX.mp4"}, {"predictions": [{"label": "D", "score": 1.9954233536577002, "label_video": "D", "correct": true}, {"label": "D", "score": 1.948270016821692, "label_video": "D", "correct": true}, {"label": "D", "score": 2.016630066711749, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0509941006523014, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0735487662468306, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0868835894869995, "label_video": "D", "correct": true}, {"label": "D", "score": 2.090880167190281, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0904749769878723, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0825669246493304, "label_video": "D", "correct": true}, {"label": "D", "score": 2.072452805290003, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0698148116142434, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0690947489999476, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0686229277341295, "label_video": "D", "correct": true}, {"label": "D", "score": 2.060974478916764, "label_video": "D", "correct": true}, {"label": "D", "score": 2.0404364783544318, "label_video": "D", "correct": true}, {"label": "D", "score": 1.9573634900358496, "label_video": "D", "correct": true}, {"label": "D", "score": 1.7635652861276938, "label_video": "D", "correct": true}, {"label": "D", "score": 1.5193984619988936, "label_video": "D", "correct": true}], "elapsed_time": 0.798392997847663, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230228212158911015_0A9ZW.mp4"}, {"predictions": [{"label": "D", "score": 1.6712654676387697, "label_video": "D", "correct": true}, {"label": "D", "score": 1.7532118346069292, "label_video": "D", "correct": true}, {"label": "D", "score": 1.7972092460400793, "label_video": "D", "correct": true}, {"label": "D", "score": 1.8158007505991136, "label_video": "D", "correct": true}, {"label": "D", "score": 1.814775275943322, "label_video": "D", "correct": true}, {"label": "D", "score": 1.668277545223552, "label_video": "D", "correct": true}], "elapsed_time": 2.3108023007710776, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230313161903793288_9AFD2.mp4"}, {"predictions": [{"label": "D", "score": 2.80293167580694, "label_video": "D", "correct": true}, {"label": "D", "score": 2.845893685501772, "label_video": "D", "correct": true}, {"label": "D", "score": 2.843615227255108, "label_video": "D", "correct": true}, {"label": "D", "score": 2.8531983197014212, "label_video": "D", "correct": true}, {"label": "D", "score": 2.8549021427442214, "label_video": "D", "correct": true}, {"label": "D", "score": 2.8392483721997372, "label_video": "D", "correct": true}, {"label": "D", "score": 2.7968586247943827, "label_video": "D", "correct": true}, {"label": "D", "score": 2.7585036625969304, "label_video": "D", "correct": true}, {"label": "D", "score": 2.7130777775637926, "label_video": "D", "correct": true}, {"label": "D", "score": 2.6635075848203686, "label_video": "D", "correct": true}, {"label": "D", "score": 2.616507324719955, "label_video": "D", "correct": true}, {"label": "D", "score": 2.5685541232807747, "label_video": "D", "correct": true}, {"label": "D", "score": 2.5191544206783614, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4826168113400775, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4514270138111485, "label_video": "D", "correct": true}, {"label": "D", "score": 2.4289633490896123, "label_video": "D", "correct": true}], "elapsed_time": 0.674962967634201, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230225172727976175_2RIBR.mp4"}, {"predictions": [{"label": "B", "score": 2.356838025355003, "label_video": "D", "correct": false}, {"label": "B", "score": 2.395005918881982, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5183050400362266, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5409537725392997, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5544256303177484, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5705526956739453, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5719226305462644, "label_video": "D", "correct": false}, {"label": "B", "score": 2.576512641711594, "label_video": "D", "correct": false}, {"label": "B", "score": 2.574817531935426, "label_video": "D", "correct": false}, {"label": "B", "score": 2.583655920185938, "label_video": "D", "correct": false}, {"label": "B", "score": 2.5380483257825444, "label_video": "D", "correct": false}, {"label": "B", "score": 2.462934602954078, "label_video": "D", "correct": false}, {"label": "B", "score": 2.243637828375149, "label_video": "D", "correct": false}, {"label": "B", "score": 2.102948362275228, "label_video": "D", "correct": false}], "elapsed_time": 0.9898833887917655, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/D!test!4_20230228222814780521_PLU9S.mp4"}], "Z": [{"predictions": [{"label": "U", "score": 2.799463659010134, "label_video": "Z", "correct": false}, {"label": "U", "score": 2.7468476130802775, "label_video": "Z", "correct": false}], "elapsed_time": 5.770528793334961, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Z!test!26_20230313161957278926_80MSW.mp4"}, {"predictions": [], "elapsed_time": 10.298417329788208, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Z!test!26_20230307165445910870_U2XSL.mp4"}, {"predictions": [], "elapsed_time": 9.941589832305908, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Z!test!26_20230313164054142446_A1FDD.mp4"}, {"predictions": [{"label": "K", "score": 2.1791970026699343, "label_video": "Z", "correct": false}], "elapsed_time": 12.05991244316101, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Z!test!26_20230313161447006469_H83BN.mp4"}], "B": [{"predictions": [{"label": "F", "score": 1.9593289077892824, "label_video": "B", "correct": false}, {"label": "B", "score": 1.9867193078990097, "label_video": "B", "correct": true}, {"label": "B", "score": 1.996701272457568, "label_video": "B", "correct": true}, {"label": "B", "score": 1.994058219010588, "label_video": "B", "correct": true}, {"label": "F", "score": 1.9976131585433872, "label_video": "B", "correct": false}, {"label": "F", "score": 1.9885528996237103, "label_video": "B", "correct": false}, {"label": "F", "score": 1.9698340424561807, "label_video": "B", "correct": false}], "elapsed_time": 1.835174867085048, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230228222324124636_0NX8J.mp4"}, {"predictions": [{"label": "B", "score": 1.8134735536006292, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7935288763976316, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7800426191259842, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7710646256493494, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7583081997164984, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7468697362962073, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7393496974854992, "label_video": "B", "correct": true}, {"label": "B", "score": 1.724216345305945, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6982123095096444, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6798424023236962, "label_video": "B", "correct": true}], "elapsed_time": 1.3823610544204712, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230228222929769864_DB9S6.mp4"}, {"predictions": [{"label": "F", "score": 2.119516627400745, "label_video": "B", "correct": false}, {"label": "F", "score": 2.1708251020091014, "label_video": "B", "correct": false}, {"label": "F", "score": 2.1873548520591934, "label_video": "B", "correct": false}, {"label": "F", "score": 2.1849343529151817, "label_video": "B", "correct": false}, {"label": "F", "score": 2.178640238994378, "label_video": "B", "correct": false}, {"label": "F", "score": 2.1775294629508073, "label_video": "B", "correct": false}, {"label": "B", "score": 2.0815286976441527, "label_video": "B", "correct": true}], "elapsed_time": 1.8380905560084753, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230228212047306396_QKEVB.mp4"}, {"predictions": [{"label": "B", "score": 1.374947595620093, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6082246941341234, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6564184146799714, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6830191362149445, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6941172399381697, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7060721752161545, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7105846411248544, "label_video": "B", "correct": true}, {"label": "B", "score": 1.7048764965168126, "label_video": "B", "correct": true}, {"label": "B", "score": 1.6644654619431567, "label_video": "B", "correct": true}], "elapsed_time": 1.6916031042734783, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230301110937167164_IFR49.mp4"}, {"predictions": [{"label": "F", "score": 1.9735447774560109, "label_video": "B", "correct": false}, {"label": "F", "score": 2.028210858122298, "label_video": "B", "correct": false}, {"label": "F", "score": 2.0768377849232516, "label_video": "B", "correct": false}, {"label": "F", "score": 2.1182155275952494, "label_video": "B", "correct": false}, {"label": "F", "score": 2.180150593255882, "label_video": "B", "correct": false}, {"label": "F", "score": 2.215613507107632, "label_video": "B", "correct": false}, {"label": "F", "score": 2.2653942453971, "label_video": "B", "correct": false}, {"label": "F", "score": 2.325170150301084, "label_video": "B", "correct": false}, {"label": "F", "score": 2.3900440970111805, "label_video": "B", "correct": false}, {"label": "D", "score": 2.4488795867045914, "label_video": "B", "correct": false}, {"label": "D", "score": 2.4307100900423526, "label_video": "B", "correct": false}, {"label": "D", "score": 2.4208771855246742, "label_video": "B", "correct": false}, {"label": "D", "score": 2.4116180119079833, "label_video": "B", "correct": false}, {"label": "D", "score": 2.4036897286432386, "label_video": "B", "correct": false}, {"label": "D", "score": 2.399025981350265, "label_video": "B", "correct": false}, {"label": "D", "score": 2.408395066129699, "label_video": "B", "correct": false}, {"label": "D", "score": 2.405034482370881, "label_video": "B", "correct": false}, {"label": "D", "score": 2.423172268072002, "label_video": "B", "correct": false}], "elapsed_time": 0.5887514617707994, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230312122212547903_CCFXR.mp4"}, {"predictions": [{"label": "F", "score": 1.8079722035311632, "label_video": "B", "correct": false}, {"label": "F", "score": 1.910277086705248, "label_video": "B", "correct": false}, {"label": "F", "score": 1.9856366985293057, "label_video": "B", "correct": false}, {"label": "F", "score": 2.0313588783974055, "label_video": "B", "correct": false}, {"label": "F", "score": 2.0513797234280275, "label_video": "B", "correct": false}, {"label": "F", "score": 2.0398561433337843, "label_video": "B", "correct": false}, {"label": "F", "score": 2.0040280626778157, "label_video": "B", "correct": false}, {"label": "F", "score": 1.9786998748987954, "label_video": "B", "correct": false}, {"label": "B", "score": 1.9649310907601665, "label_video": "B", "correct": true}, {"label": "B", "score": 1.8347003945548899, "label_video": "B", "correct": true}], "elapsed_time": 1.4192028760910034, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230301112301936371_7V1RV.mp4"}, {"predictions": [{"label": "F", "score": 2.0527426287880446, "label_video": "B", "correct": false}, {"label": "F", "score": 2.184645188869794, "label_video": "B", "correct": false}, {"label": "F", "score": 2.2522888388180013, "label_video": "B", "correct": false}, {"label": "F", "score": 2.291003799057254, "label_video": "B", "correct": false}, {"label": "F", "score": 2.3044740137128352, "label_video": "B", "correct": false}, {"label": "F", "score": 2.299287548941461, "label_video": "B", "correct": false}, {"label": "F", "score": 2.280136082367257, "label_video": "B", "correct": false}, {"label": "F", "score": 2.2688930816641757, "label_video": "B", "correct": false}, {"label": "F", "score": 2.2473765163546706, "label_video": "B", "correct": false}, {"label": "F", "score": 2.22651302064917, "label_video": "B", "correct": false}], "elapsed_time": 2.0135565757751466, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/B!test!2_20230225172506182079_8VLS0.mp4"}], "G": [{"predictions": [{"label": "G", "score": 1.4301371135384322, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4974900117569445, "label_video": "G", "correct": true}, {"label": "G", "score": 1.5245870592942323, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4921480316971392, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4472210836682593, "label_video": "G", "correct": true}, {"label": "G", "score": 1.391400624088979, "label_video": "G", "correct": true}, {"label": "G", "score": 1.3468968608620044, "label_video": "G", "correct": true}, {"label": "G", "score": 1.3200035727740491, "label_video": "G", "correct": true}], "elapsed_time": 1.296994388103485, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/G!test!7_20230304203737799336_OETKT.mp4"}, {"predictions": [{"label": "G", "score": 1.8539669217206391, "label_video": "G", "correct": true}, {"label": "G", "score": 1.8251237310334638, "label_video": "G", "correct": true}, {"label": "G", "score": 1.7927830816282908, "label_video": "G", "correct": true}, {"label": "G", "score": 1.782609505645209, "label_video": "G", "correct": true}, {"label": "G", "score": 1.7781481366127487, "label_video": "G", "correct": true}, {"label": "G", "score": 1.7661225825784288, "label_video": "G", "correct": true}, {"label": "G", "score": 1.8105019131028404, "label_video": "G", "correct": true}], "elapsed_time": 1.471658434186663, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/G!test!7_20230307164532293278_1JLVG.mp4"}, {"predictions": [{"label": "G", "score": 1.4989045317987613, "label_video": "G", "correct": true}, {"label": "G", "score": 1.7082379795976006, "label_video": "G", "correct": true}, {"label": "G", "score": 1.6130399912165787, "label_video": "G", "correct": true}, {"label": "G", "score": 1.5424357757916185, "label_video": "G", "correct": true}, {"label": "G", "score": 1.519853215675762, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4969461118095473, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4807042075246495, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4652213806739105, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4580001148776403, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4491348654157892, "label_video": "G", "correct": true}, {"label": "G", "score": 1.441969267594473, "label_video": "G", "correct": true}, {"label": "G", "score": 1.4595687898501535, "label_video": "G", "correct": true}], "elapsed_time": 1.0900495648384094, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/G!test!7_20230313161501367571_FROKQ.mp4"}], "F": [{"predictions": [{"label": "F", "score": 1.683977850979644, "label_video": "F", "correct": true}, {"label": "F", "score": 1.7360466364887663, "label_video": "F", "correct": true}, {"label": "F", "score": 1.7207779433994612, "label_video": "F", "correct": true}, {"label": "F", "score": 1.723873439066418, "label_video": "F", "correct": true}, {"label": "F", "score": 1.7086907089298067, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6926664872119241, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6875562727873845, "label_video": "F", "correct": true}, {"label": "F", "score": 1.681644143022973, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6748326012563066, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6710847184863047, "label_video": "F", "correct": true}, {"label": "F", "score": 1.658295594849378, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6402555514049308, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6233260606636044, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6219787308802731, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6248616451637359, "label_video": "F", "correct": true}], "elapsed_time": 0.69434019724528, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/F!test!6_20230312121908462336_I1QIZ.mp4"}, {"predictions": [{"label": "F", "score": 2.1207574911694307, "label_video": "F", "correct": true}, {"label": "B", "score": 2.2562665372732917, "label_video": "F", "correct": false}, {"label": "B", "score": 2.2969340358551324, "label_video": "F", "correct": false}, {"label": "B", "score": 2.287156804884113, "label_video": "F", "correct": false}, {"label": "B", "score": 2.2702685544343697, "label_video": "F", "correct": false}, {"label": "B", "score": 2.266574679631894, "label_video": "F", "correct": false}, {"label": "B", "score": 2.260893538925208, "label_video": "F", "correct": false}, {"label": "B", "score": 2.260487495230335, "label_video": "F", "correct": false}, {"label": "B", "score": 2.2673471664889386, "label_video": "F", "correct": false}, {"label": "B", "score": 2.293105365577211, "label_video": "F", "correct": false}, {"label": "B", "score": 2.3214854074036415, "label_video": "F", "correct": false}, {"label": "B", "score": 2.34950397787049, "label_video": "F", "correct": false}, {"label": "B", "score": 2.3686626711444294, "label_video": "F", "correct": false}, {"label": "B", "score": 2.39291352563878, "label_video": "F", "correct": false}, {"label": "F", "score": 2.326181031694309, "label_video": "F", "correct": true}, {"label": "F", "score": 2.247768166925242, "label_video": "F", "correct": true}, {"label": "F", "score": 2.137569058876306, "label_video": "F", "correct": true}, {"label": "F", "score": 1.8499562772874414, "label_video": "F", "correct": true}, {"label": "F", "score": 1.6953579698189565, "label_video": "F", "correct": true}], "elapsed_time": 0.5504951978984632, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/F!test!6_20230304203640734496_5704C.mp4"}], "T": [{"predictions": [{"label": "T", "score": 1.702636570680647, "label_video": "T", "correct": true}, {"label": "T", "score": 1.7552357309424087, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6940422354562878, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6611673286835407, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6490318727621829, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6446383392125423, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6463570488314998, "label_video": "T", "correct": true}, {"label": "T", "score": 1.65150959530228, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6626707355858623, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6893526910623258, "label_video": "T", "correct": true}, {"label": "T", "score": 1.7185483118825255, "label_video": "T", "correct": true}, {"label": "T", "score": 1.7743127795185047, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8724786034935008, "label_video": "T", "correct": true}, {"label": "T", "score": 1.9894753658542508, "label_video": "T", "correct": true}], "elapsed_time": 0.993323700768607, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/T!test!20_20230307114928366357_UN0B3.mp4"}, {"predictions": [{"label": "T", "score": 1.8626815997796002, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8717868305908714, "label_video": "T", "correct": true}, {"label": "T", "score": 1.9761056450979242, "label_video": "T", "correct": true}, {"label": "T", "score": 1.9029205525719233, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8318674040481382, "label_video": "T", "correct": true}], "elapsed_time": 2.0903223514556886, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/T!test!20_20230324145705628056_ZK1KA.mp4"}, {"predictions": [{"label": "T", "score": 1.6735100679303343, "label_video": "T", "correct": true}, {"label": "T", "score": 1.6957723555240458, "label_video": "T", "correct": true}, {"label": "T", "score": 1.7597382386913731, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8014228457464887, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8181077821742906, "label_video": "T", "correct": true}, {"label": "T", "score": 1.815034297379265, "label_video": "T", "correct": true}, {"label": "T", "score": 1.811523429754144, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8031565813822905, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8036834944419, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8059033587465994, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8164514150817703, "label_video": "T", "correct": true}, {"label": "T", "score": 1.8197420840654803, "label_video": "T", "correct": true}], "elapsed_time": 0.896879255771637, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/T!test!20_20230313163511440077_NZHE1.mp4"}], "H": [{"predictions": [{"label": "R", "score": 1.7472881220296301, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9501123656074728, "label_video": "H", "correct": false}, {"label": "R", "score": 1.933176521720013, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9125445807121348, "label_video": "H", "correct": false}, {"label": "R", "score": 1.8960701618283053, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9461286127198252, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9447095594753083, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9209317847546874, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9192074371830996, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9123479181254004, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9280972617079482, "label_video": "H", "correct": false}, {"label": "R", "score": 1.9512208296403233, "label_video": "H", "correct": false}, {"label": "R", "score": 1.8489050248730157, "label_video": "H", "correct": false}], "elapsed_time": 0.7992158119495099, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/H!test!8_20230313161206595497_18K96.mp4"}], "L": [{"predictions": [{"label": "L", "score": 1.8030368239219225, "label_video": "L", "correct": true}, {"label": "L", "score": 1.6364905426070775, "label_video": "L", "correct": true}, {"label": "L", "score": 1.4974868844292508, "label_video": "L", "correct": true}, {"label": "L", "score": 1.467851654897367, "label_video": "L", "correct": true}, {"label": "L", "score": 1.4820643726962133, "label_video": "L", "correct": true}, {"label": "L", "score": 1.5621705034756703, "label_video": "L", "correct": true}], "elapsed_time": 2.340570052464803, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/L!test!12_20230313161059748851_KNFAO.mp4"}, {"predictions": [{"label": "Z", "score": 2.2185535916614416, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2693125464672486, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2876151789967722, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.28753878163095, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2768432267711414, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2681485609175134, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2454237950488305, "label_video": "L", "correct": false}, {"label": "Z", "score": 2.2013031088362265, "label_video": "L", "correct": false}], "elapsed_time": 1.7585780918598175, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/L!test!12_20230313162934873787_K6OO9.mp4"}, {"predictions": [{"label": "Z", "score": 2.186513930631288, "label_video": "L", "correct": false}, {"label": "L", "score": 2.0039976060827804, "label_video": "L", "correct": true}, {"label": "L", "score": 1.9417806036168002, "label_video": "L", "correct": true}, {"label": "L", "score": 1.9685227948992094, "label_video": "L", "correct": true}, {"label": "L", "score": 2.0136151953302956, "label_video": "L", "correct": true}], "elapsed_time": 2.8315707206726075, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/L!test!12_20230307102535608019_OE26A.mp4"}, {"predictions": [{"label": "L", "score": 2.342915074248626, "label_video": "L", "correct": true}, {"label": "L", "score": 2.3947638460230745, "label_video": "L", "correct": true}, {"label": "L", "score": 2.4103295633717057, "label_video": "L", "correct": true}, {"label": "L", "score": 2.4288855266682505, "label_video": "L", "correct": true}], "elapsed_time": 2.556564211845398, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/L!test!12_20230304204407950798_WP3WI.mp4"}], "R": [{"predictions": [{"label": "D", "score": 2.260694613123889, "label_video": "R", "correct": false}, {"label": "D", "score": 2.34817078287636, "label_video": "R", "correct": false}, {"label": "D", "score": 2.386439379507705, "label_video": "R", "correct": false}, {"label": "D", "score": 2.3997456129762007, "label_video": "R", "correct": false}, {"label": "D", "score": 2.373025054933615, "label_video": "R", "correct": false}, {"label": "D", "score": 2.3372853292810567, "label_video": "R", "correct": false}, {"label": "D", "score": 2.2554291338711536, "label_video": "R", "correct": false}], "elapsed_time": 1.8732103279658727, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/R!test!18_20230324145426494537_7E7GJ.mp4"}, {"predictions": [{"label": "D", "score": 1.5626741851302106, "label_video": "R", "correct": false}, {"label": "D", "score": 1.609061313806437, "label_video": "R", "correct": false}, {"label": "D", "score": 1.6883283508747455, "label_video": "R", "correct": false}, {"label": "D", "score": 1.7006968609116477, "label_video": "R", "correct": false}], "elapsed_time": 3.149934709072113, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/R!test!18_20230312122159916374_ICIOK.mp4"}, {"predictions": [{"label": "H", "score": 2.7709974682417697, "label_video": "R", "correct": false}, {"label": "D", "score": 2.7286950161672743, "label_video": "R", "correct": false}, {"label": "D", "score": 2.5936274841368263, "label_video": "R", "correct": false}, {"label": "D", "score": 2.5940710518039096, "label_video": "R", "correct": false}, {"label": "D", "score": 2.5725782429326056, "label_video": "R", "correct": false}, {"label": "D", "score": 2.51992383668424, "label_video": "R", "correct": false}, {"label": "D", "score": 2.493677986659328, "label_video": "R", "correct": false}, {"label": "D", "score": 2.478957873996398, "label_video": "R", "correct": false}], "elapsed_time": 1.7269577383995056, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/R!test!18_20230313161710218698_DDD0P.mp4"}], "N": [{"predictions": [{"label": "N", "score": 1.6000349552465702, "label_video": "N", "correct": true}, {"label": "N", "score": 1.7127339084004252, "label_video": "N", "correct": true}, {"label": "N", "score": 1.683845535562536, "label_video": "N", "correct": true}, {"label": "N", "score": 1.6724278502371175, "label_video": "N", "correct": true}, {"label": "N", "score": 1.7671211281792334, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8901347259706962, "label_video": "N", "correct": true}, {"label": "N", "score": 2.0174231789160384, "label_video": "N", "correct": true}, {"label": "N", "score": 1.9676380685996346, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8997676770138978, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8572275887742544, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8594555191920372, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8801198281991547, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8887828385074243, "label_video": "N", "correct": true}, {"label": "N", "score": 1.8966785950180114, "label_video": "N", "correct": true}, {"label": "N", "score": 1.899283816058579, "label_video": "N", "correct": true}, {"label": "N", "score": 1.9113840545809537, "label_video": "N", "correct": true}, {"label": "N", "score": 1.7867428519372357, "label_video": "N", "correct": true}, {"label": "N", "score": 1.7137149163151624, "label_video": "N", "correct": true}, {"label": "N", "score": 1.6805654758541004, "label_video": "N", "correct": true}, {"label": "N", "score": 1.6506955379080022, "label_video": "N", "correct": true}], "elapsed_time": 0.7228409886360169, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/N!test!14_20230324145012230578_ZVE37.mp4"}, {"predictions": [{"label": "Y", "score": 1.660276764457777, "label_video": "N", "correct": false}, {"label": "Y", "score": 1.6283682306401877, "label_video": "N", "correct": false}, {"label": "M", "score": 1.624752643516139, "label_video": "N", "correct": false}, {"label": "M", "score": 1.6416881008662783, "label_video": "N", "correct": false}, {"label": "M", "score": 1.6290431366378628, "label_video": "N", "correct": false}, {"label": "Y", "score": 1.6451408488938237, "label_video": "N", "correct": false}, {"label": "Y", "score": 1.649796199758908, "label_video": "N", "correct": false}, {"label": "Y", "score": 1.669685694672358, "label_video": "N", "correct": false}, {"label": "N", "score": 1.6312994846736533, "label_video": "N", "correct": true}, {"label": "N", "score": 1.5982582781345633, "label_video": "N", "correct": true}, {"label": "N", "score": 1.5676649171017984, "label_video": "N", "correct": true}, {"label": "N", "score": 1.5433950865348531, "label_video": "N", "correct": true}, {"label": "N", "score": 1.509052361116376, "label_video": "N", "correct": true}, {"label": "N", "score": 1.4472292509287372, "label_video": "N", "correct": true}], "elapsed_time": 0.8040524210248675, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/N!test!14_20230313163151152753_ES53K.mp4"}, {"predictions": [{"label": "N", "score": 2.204577086620051, "label_video": "N", "correct": true}, {"label": "N", "score": 2.124949379754276, "label_video": "N", "correct": true}, {"label": "N", "score": 1.9841792577095583, "label_video": "N", "correct": true}, {"label": "N", "score": 1.9787796442887655, "label_video": "N", "correct": true}, {"label": "N", "score": 2.0177491827972136, "label_video": "N", "correct": true}, {"label": "N", "score": 2.066034054284687, "label_video": "N", "correct": true}, {"label": "N", "score": 2.1212484454304943, "label_video": "N", "correct": true}, {"label": "N", "score": 2.1725689499665033, "label_video": "N", "correct": true}, {"label": "N", "score": 2.1966706045583146, "label_video": "N", "correct": true}, {"label": "N", "score": 2.207392837970869, "label_video": "N", "correct": true}, {"label": "N", "score": 2.2033016620942494, "label_video": "N", "correct": true}, {"label": "N", "score": 2.1990903020523183, "label_video": "N", "correct": true}, {"label": "N", "score": 2.19488133353123, "label_video": "N", "correct": true}, {"label": "N", "score": 2.16902794970301, "label_video": "N", "correct": true}, {"label": "N", "score": 2.1138409457156557, "label_video": "N", "correct": true}, {"label": "M", "score": 2.0544599490097357, "label_video": "N", "correct": false}], "elapsed_time": 0.8888121098279953, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/N!test!14_20230324145035097834_760QJ.mp4"}], "M": [{"predictions": [{"label": "N", "score": 1.888147405084172, "label_video": "M", "correct": false}, {"label": "N", "score": 1.924729537894959, "label_video": "M", "correct": false}, {"label": "N", "score": 1.917480639579175, "label_video": "M", "correct": false}, {"label": "N", "score": 1.8630728099678582, "label_video": "M", "correct": false}, {"label": "N", "score": 1.8489392057494023, "label_video": "M", "correct": false}, {"label": "N", "score": 1.8265444216181697, "label_video": "M", "correct": false}, {"label": "N", "score": 1.825831669425838, "label_video": "M", "correct": false}, {"label": "N", "score": 1.823505103568021, "label_video": "M", "correct": false}, {"label": "N", "score": 1.8243361638171838, "label_video": "M", "correct": false}, {"label": "N", "score": 1.847854498679807, "label_video": "M", "correct": false}], "elapsed_time": 1.051465630531311, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/M!test!13_20230313161937796761_OBK2P.mp4"}, {"predictions": [{"label": "N", "score": 1.483699049575953, "label_video": "M", "correct": false}, {"label": "N", "score": 1.4170375618712001, "label_video": "M", "correct": false}, {"label": "N", "score": 1.472488784644543, "label_video": "M", "correct": false}, {"label": "N", "score": 1.567055060988601, "label_video": "M", "correct": false}, {"label": "N", "score": 1.6874462793817482, "label_video": "M", "correct": false}, {"label": "M", "score": 1.8514767572646134, "label_video": "M", "correct": true}, {"label": "M", "score": 1.847033174479555, "label_video": "M", "correct": true}, {"label": "M", "score": 1.828819188373617, "label_video": "M", "correct": true}, {"label": "N", "score": 1.8253754052840077, "label_video": "M", "correct": false}, {"label": "N", "score": 1.8212815065636678, "label_video": "M", "correct": false}, {"label": "M", "score": 1.8036375906110003, "label_video": "M", "correct": true}, {"label": "M", "score": 1.7432808985399242, "label_video": "M", "correct": true}, {"label": "M", "score": 1.7841891372492724, "label_video": "M", "correct": true}, {"label": "N", "score": 1.8422030181286173, "label_video": "M", "correct": false}], "elapsed_time": 0.7409014701843262, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/M!test!13_20230324144921129170_XFH81.mp4"}, {"predictions": [{"label": "M", "score": 1.6127403373733602, "label_video": "M", "correct": true}, {"label": "M", "score": 1.7387514666523585, "label_video": "M", "correct": true}, {"label": "M", "score": 1.8714156109061881, "label_video": "M", "correct": true}, {"label": "M", "score": 2.005887558032, "label_video": "M", "correct": true}, {"label": "M", "score": 2.0059595358117255, "label_video": "M", "correct": true}, {"label": "M", "score": 1.9653716490619408, "label_video": "M", "correct": true}, {"label": "M", "score": 1.9545019105704, "label_video": "M", "correct": true}, {"label": "M", "score": 1.9466131012856687, "label_video": "M", "correct": true}, {"label": "M", "score": 1.9333327851149449, "label_video": "M", "correct": true}, {"label": "M", "score": 1.946272479931318, "label_video": "M", "correct": true}, {"label": "M", "score": 1.9474335529021005, "label_video": "M", "correct": true}], "elapsed_time": 1.2929978587410667, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/M!test!13_20230312121958936751_30KVC.mp4"}], "U": [{"predictions": [{"label": "U", "score": 1.6116354374557251, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4475778595848927, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4947799102302053, "label_video": "U", "correct": true}, {"label": "U", "score": 1.5101147616432988, "label_video": "U", "correct": true}, {"label": "U", "score": 1.5049339221687608, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4867041294468373, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4663320299241351, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4564434982523744, "label_video": "U", "correct": true}, {"label": "U", "score": 1.414026382462934, "label_video": "U", "correct": true}], "elapsed_time": 1.322842624452379, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/U!test!21_20230313161315755723_LATPU.mp4"}, {"predictions": [{"label": "U", "score": 0.9505717734539578, "label_video": "U", "correct": true}, {"label": "U", "score": 1.1871154892739897, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2304807012285226, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2392639158076952, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2352813346688998, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2398012598426849, "label_video": "U", "correct": true}, {"label": "U", "score": 1.243541813801613, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2487931810077395, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2572732461478764, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2556294956330643, "label_video": "U", "correct": true}, {"label": "U", "score": 1.2537402648372924, "label_video": "U", "correct": true}], "elapsed_time": 0.9485751065340909, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/U!test!21_20230307123048962355_ZX8XO.mp4"}, {"predictions": [{"label": "U", "score": 1.6867408877910497, "label_video": "U", "correct": true}, {"label": "U", "score": 1.511534258563763, "label_video": "U", "correct": true}, {"label": "U", "score": 1.5004630892693915, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4878845240368255, "label_video": "U", "correct": true}, {"label": "U", "score": 1.477981369468984, "label_video": "U", "correct": true}, {"label": "U", "score": 1.469646681960691, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4634241384288806, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4553297804756304, "label_video": "U", "correct": true}, {"label": "U", "score": 1.448171702045843, "label_video": "U", "correct": true}, {"label": "U", "score": 1.4402640488463159, "label_video": "U", "correct": true}, {"label": "U", "score": 1.42244907787585, "label_video": "U", "correct": true}, {"label": "U", "score": 1.3774115526676312, "label_video": "U", "correct": true}], "elapsed_time": 0.8599359194437662, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/U!test!21_20230313162133908644_CM19N.mp4"}, {"predictions": [{"label": "U", "score": 0.9884716953739091, "label_video": "U", "correct": true}, {"label": "U", "score": 1.0383215492562705, "label_video": "U", "correct": true}, {"label": "U", "score": 1.166233955858768, "label_video": "U", "correct": true}, {"label": "U", "score": 1.1660736814098167, "label_video": "U", "correct": true}, {"label": "U", "score": 1.1622802149482336, "label_video": "U", "correct": true}, {"label": "U", "score": 1.1571488350851091, "label_video": "U", "correct": true}, {"label": "U", "score": 1.147044205541362, "label_video": "U", "correct": true}, {"label": "U", "score": 1.1331373408797407, "label_video": "U", "correct": true}], "elapsed_time": 1.3402684330940247, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/U!test!21_20230313161418806455_9IVRL.mp4"}], "W": [{"predictions": [{"label": "L", "score": 1.6370465821139584, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6426752901846617, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6518608335907181, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6506788960282013, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6513003053647513, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6512888474909668, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6498132569185449, "label_video": "W", "correct": false}, {"label": "L", "score": 1.6487539914843181, "label_video": "W", "correct": false}], "elapsed_time": 0.6326256096363068, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/W!test!163_20230330155433648572_0U0VA.mp4"}], "K": [{"predictions": [{"label": "K", "score": 2.2672320042993617, "label_video": "K", "correct": true}, {"label": "K", "score": 2.1587548817939815, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0982547823306326, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0696777128533217, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0546063972993074, "label_video": "K", "correct": true}, {"label": "K", "score": 2.039647863015503, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0315890674866357, "label_video": "K", "correct": true}, {"label": "K", "score": 2.032571057039241, "label_video": "K", "correct": true}, {"label": "K", "score": 2.037321975999602, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0411834540594875, "label_video": "K", "correct": true}, {"label": "K", "score": 2.052119610163358, "label_video": "K", "correct": true}, {"label": "K", "score": 2.0775831006679506, "label_video": "K", "correct": true}, {"label": "K", "score": 2.127617011298703, "label_video": "K", "correct": true}, {"label": "K", "score": 2.1498151949182778, "label_video": "K", "correct": true}], "elapsed_time": 0.986958384513855, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/K!test!11_20230324144726301532_OCWMC.mp4"}, {"predictions": [{"label": "K", "score": 2.248654259342141, "label_video": "K", "correct": true}, {"label": "K", "score": 2.342394704915502, "label_video": "K", "correct": true}, {"label": "K", "score": 2.381605519121084, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4237003546832674, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4507790731100374, "label_video": "K", "correct": true}, {"label": "K", "score": 2.467410103186921, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4902298180996048, "label_video": "K", "correct": true}, {"label": "K", "score": 2.5186239306816836, "label_video": "K", "correct": true}, {"label": "K", "score": 2.5536025741656654, "label_video": "K", "correct": true}, {"label": "K", "score": 2.591550345169624, "label_video": "K", "correct": true}, {"label": "K", "score": 2.623230274825085, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6563138227278706, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6826655869086884, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6852749424535807, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6905092404439364, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6976115709814525, "label_video": "K", "correct": true}, {"label": "K", "score": 2.7165403539576025, "label_video": "K", "correct": true}, {"label": "K", "score": 2.708684357464087, "label_video": "K", "correct": true}, {"label": "K", "score": 2.692728440948887, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6815927772765584, "label_video": "K", "correct": true}, {"label": "K", "score": 2.6794186683344745, "label_video": "K", "correct": true}], "elapsed_time": 0.521637723559425, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/K!test!11_20230312122042488710_GDN7Q.mp4"}, {"predictions": [{"label": "K", "score": 1.9732807794327665, "label_video": "K", "correct": true}, {"label": "K", "score": 2.1352283093873634, "label_video": "K", "correct": true}, {"label": "K", "score": 2.2315687344027264, "label_video": "K", "correct": true}, {"label": "K", "score": 2.3206994658350566, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4396164830893583, "label_video": "K", "correct": true}, {"label": "K", "score": 2.44793725404019, "label_video": "K", "correct": true}, {"label": "K", "score": 2.454888382121592, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4479808230797206, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4422424504336653, "label_video": "K", "correct": true}, {"label": "K", "score": 2.459234502023693, "label_video": "K", "correct": true}, {"label": "K", "score": 2.475483498517899, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4797025549801472, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4854203516336066, "label_video": "K", "correct": true}, {"label": "K", "score": 2.489647267010964, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4888934252096493, "label_video": "K", "correct": true}, {"label": "K", "score": 2.4850467962373877, "label_video": "K", "correct": true}, {"label": "K", "score": 2.493129380266535, "label_video": "K", "correct": true}, {"label": "K", "score": 2.515856481255385, "label_video": "K", "correct": true}, {"label": "K", "score": 2.5254897912349716, "label_video": "K", "correct": true}, {"label": "K", "score": 2.5258207465620863, "label_video": "K", "correct": true}], "elapsed_time": 0.5414046287536621, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/K!test!11_20230324144715281835_X3QRX.mp4"}, {"predictions": [{"label": "V", "score": 2.1667968931221036, "label_video": "K", "correct": false}, {"label": "V", "score": 1.9303877770941416, "label_video": "K", "correct": false}, {"label": "V", "score": 1.7846575826432947, "label_video": "K", "correct": false}, {"label": "V", "score": 1.6469888351693278, "label_video": "K", "correct": false}, {"label": "V", "score": 1.5469674172865653, "label_video": "K", "correct": false}, {"label": "V", "score": 1.57538695672441, "label_video": "K", "correct": false}, {"label": "V", "score": 1.6191506423388338, "label_video": "K", "correct": false}, {"label": "V", "score": 1.6532492573438289, "label_video": "K", "correct": false}, {"label": "V", "score": 1.6562439864375127, "label_video": "K", "correct": false}, {"label": "V", "score": 1.6833811177551632, "label_video": "K", "correct": false}, {"label": "V", "score": 1.7100215202296418, "label_video": "K", "correct": false}, {"label": "V", "score": 1.7619638278930632, "label_video": "K", "correct": false}, {"label": "V", "score": 1.856988118564069, "label_video": "K", "correct": false}], "elapsed_time": 0.7854204361255352, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/K!test!11_20230307102414445161_600PU.mp4"}], "Y": [{"predictions": [{"label": "Y", "score": 1.5407074212378564, "label_video": "Y", "correct": true}, {"label": "I", "score": 1.526852466839233, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.4317283310558444, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.6215623388914486, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.8233467560232535, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.7341933113713461, "label_video": "Y", "correct": false}], "elapsed_time": 1.6832131544748943, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Y!test!25_20230313162106351685_FMVMX.mp4"}, {"predictions": [{"label": "I", "score": 1.3048899877374178, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.2537776746224836, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.2921600866376375, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.3857511898795396, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.569815292828416, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.965329768417178, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.4572536549320265, "label_video": "Y", "correct": false}, {"label": "M", "score": 2.663211547805386, "label_video": "Y", "correct": false}], "elapsed_time": 1.823844701051712, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Y!test!25_20230313114605974188_BN86E.mp4"}, {"predictions": [{"label": "I", "score": 1.1487403587068192, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.1930614962147925, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.1977684884834534, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.2855756057746743, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.4888095389522211, "label_video": "Y", "correct": false}, {"label": "I", "score": 1.659892972866231, "label_video": "Y", "correct": false}], "elapsed_time": 1.7263616720835369, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Y!test!25_20230313161404838712_C6O15.mp4"}, {"predictions": [{"label": "I", "score": 2.6207027632276008, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.4759192403037162, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.3949342065246175, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.300586527916178, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.355185442479411, "label_video": "Y", "correct": false}, {"label": "I", "score": 2.510276520278757, "label_video": "Y", "correct": false}, {"label": "N", "score": 2.658237802951027, "label_video": "Y", "correct": false}, {"label": "Y", "score": 2.2106353267988306, "label_video": "Y", "correct": true}], "elapsed_time": 1.2919740974903107, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/Y!test!25_20230307165715183873_1M1WC.mp4"}], "P": [{"predictions": [{"label": "N", "score": 1.9886952909664675, "label_video": "P", "correct": false}, {"label": "N", "score": 1.9692347299598332, "label_video": "P", "correct": false}, {"label": "N", "score": 1.9545966317661159, "label_video": "P", "correct": false}, {"label": "N", "score": 2.0318819188479647, "label_video": "P", "correct": false}, {"label": "N", "score": 2.0237501004431384, "label_video": "P", "correct": false}, {"label": "N", "score": 2.070570819308003, "label_video": "P", "correct": false}, {"label": "G", "score": 2.0713412736110457, "label_video": "P", "correct": false}, {"label": "G", "score": 2.0814178181541583, "label_video": "P", "correct": false}, {"label": "G", "score": 1.945766443521458, "label_video": "P", "correct": false}], "elapsed_time": 0.5613908237881131, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/P!test!162_20230330155354980770_LGOLK.mp4"}], "V": [{"predictions": [{"label": "U", "score": 1.148572897675384, "label_video": "V", "correct": false}, {"label": "U", "score": 1.22142970353922, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2689121568872244, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2669617481711342, "label_video": "V", "correct": false}], "elapsed_time": 3.5163474082946777, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/V!test!22_20230313160950968344_FBA6U.mp4"}, {"predictions": [{"label": "U", "score": 1.0193631065419315, "label_video": "V", "correct": false}, {"label": "U", "score": 1.0915292729783541, "label_video": "V", "correct": false}, {"label": "U", "score": 1.1521655660156596, "label_video": "V", "correct": false}, {"label": "U", "score": 1.1845669848269127, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2034898871980537, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2183771090980289, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2267818211636914, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2232732252747784, "label_video": "V", "correct": false}, {"label": "U", "score": 1.2043973666033407, "label_video": "V", "correct": false}], "elapsed_time": 1.150055620405409, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/V!test!22_20230313162446246723_B10GK.mp4"}, {"predictions": [{"label": "U", "score": 0.9812270195535572, "label_video": "V", "correct": false}, {"label": "U", "score": 0.9938835950864909, "label_video": "V", "correct": false}, {"label": "U", "score": 1.0019738339086117, "label_video": "V", "correct": false}, {"label": "U", "score": 1.0134434554804352, "label_video": "V", "correct": false}, {"label": "U", "score": 1.0191736094984285, "label_video": "V", "correct": false}, {"label": "U", "score": 1.0352333422852382, "label_video": "V", "correct": false}], "elapsed_time": 1.6983752648035686, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/V!test!22_20230313162553432304_ORUN1.mp4"}, {"predictions": [{"label": "U", "score": 1.2788418371450925, "label_video": "V", "correct": false}, {"label": "U", "score": 1.3542098721197953, "label_video": "V", "correct": false}, {"label": "U", "score": 1.4018692289473291, "label_video": "V", "correct": false}, {"label": "U", "score": 1.4160120214806957, "label_video": "V", "correct": false}, {"label": "U", "score": 1.418249193387847, "label_video": "V", "correct": false}], "elapsed_time": 2.0222246646881104, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/V!test!22_20230313161536286565_GWYEJ.mp4"}], "J": [{"predictions": [{"label": "I", "score": 1.9540100012287096, "label_video": "J", "correct": false}, {"label": "I", "score": 2.3242634671454265, "label_video": "J", "correct": false}, {"label": "J", "score": 2.3988580696705233, "label_video": "J", "correct": true}, {"label": "J", "score": 2.073665786637484, "label_video": "J", "correct": true}, {"label": "J", "score": 1.8924736229874715, "label_video": "J", "correct": true}, {"label": "J", "score": 1.7722936164662593, "label_video": "J", "correct": true}], "elapsed_time": 2.321108420689901, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/J!test!10_20230313162203343272_ERQQW.mp4"}, {"predictions": [{"label": "A", "score": 2.0019508766909464, "label_video": "J", "correct": false}, {"label": "A", "score": 1.8326434052131533, "label_video": "J", "correct": false}, {"label": "A", "score": 1.6572891372161345, "label_video": "J", "correct": false}, {"label": "A", "score": 1.5596968213325222, "label_video": "J", "correct": false}, {"label": "A", "score": 1.5675629299310134, "label_video": "J", "correct": false}, {"label": "A", "score": 1.6324389751415451, "label_video": "J", "correct": false}], "elapsed_time": 2.3031508525212607, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/J!test!10_20230313162908395643_L6DZP.mp4"}, {"predictions": [{"label": "I", "score": 2.2436100084244646, "label_video": "J", "correct": false}, {"label": "I", "score": 2.5144684941911857, "label_video": "J", "correct": false}, {"label": "J", "score": 2.526096816825506, "label_video": "J", "correct": true}, {"label": "J", "score": 2.457590237245971, "label_video": "J", "correct": true}, {"label": "J", "score": 2.5545244753408163, "label_video": "J", "correct": true}, {"label": "A", "score": 2.3609199750943692, "label_video": "J", "correct": false}, {"label": "A", "score": 2.169197783455962, "label_video": "J", "correct": false}], "elapsed_time": 1.4521524906158447, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/J!test!10_20230313162810909374_9UIYY.mp4"}], "X": [{"predictions": [{"label": "D", "score": 1.8304684907630213, "label_video": "X", "correct": false}, {"label": "D", "score": 1.9139472764999739, "label_video": "X", "correct": false}, {"label": "D", "score": 2.039990646248483, "label_video": "X", "correct": false}, {"label": "D", "score": 2.2173248777950287, "label_video": "X", "correct": false}, {"label": "D", "score": 2.3978255104254194, "label_video": "X", "correct": false}, {"label": "D", "score": 2.5207475393589, "label_video": "X", "correct": false}, {"label": "D", "score": 2.5534397434038834, "label_video": "X", "correct": false}], "elapsed_time": 0.7700640474046979, "video": "/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/X!test!164_20230330155516876101_S8M3V.mp4"}]} \ No newline at end of file diff --git a/predictions/validation.py b/predictions/validation.py new file mode 100644 index 0000000..eea8317 --- /dev/null +++ b/predictions/validation.py @@ -0,0 +1,137 @@ +import json +import os +import time + +import cv2 +import numpy as np +from matplotlib import pyplot as plt + +from predictions.k_nearest import KNearestNeighbours +from predictions.predictor import Predictor +from predictions.svm_model import SVM + +buffer_size = 15 + + +def predict_video(predictor, path_video): + # open mp4 video + cap = cv2.VideoCapture(path_video) + buffer = [] + ret, img = cap.read() # read one frame from the 'capture' object; img is (H, W, C) + desired_fps = 15 + original_fps = int(cap.get(cv2.CAP_PROP_FPS)) + print("Original FPS: ", original_fps) + # Calculate the frame skipping rate based on desired frame rate + frame_skip = original_fps // desired_fps + if frame_skip == 0: + frame_skip = 1 + print("Frame skip: ", frame_skip) + frame_number = 0 + while img is not None: + pose = predictor.extract_keypoints(img) + if pose is not None and frame_number % frame_skip == 0: + buffer.append(pose) + frame_number += 1 + ret, img = cap.read() # read one frame from the 'capture' object; img is (H, W, C) + print(len(buffer)) + return buffer + + +def get_embeddings(predictor, buffer, name): + # check if file exists with name + # if os.path.exists("predictions/test_embeddings/" + name + ".csv"): + # print("Loading embeddings from file") + # # load embeddings from file + # with open("predictions/test_embeddings/" + name + ".csv", 'r') as f: + # embeddings = json.load(f) + # else: + embeddings = [] + for index in range(buffer_size, len(buffer)): + embedding = predictor.get_embedding(buffer[index - buffer_size:index]) + embeddings.append(embedding) + with open("predictions/test_embeddings/" + name + ".csv", 'w') as f: + json.dump(embeddings, f) + return embeddings + + +def compare_embeddings(predictor, embeddings, label_video, ): + results = [] + for embedding in embeddings: + label, score = predictor.predict(embedding) + + results.append({"label": label, "score": score, "label_video": label_video, "correct": label == label_video}) + return results + + +def predict_video_files(predictor, path_video, label_video): + buffer = predict_video(predictor, path_video) + embeddings = get_embeddings(predictor, buffer, path_video.split("/")[-1].split(".")[0]) + return compare_embeddings(predictor, embeddings, label_video) + + +def get_test_data(data_folder): + files = np.array([data_folder + f for f in os.listdir(data_folder) if f.endswith(".mp4")]) + train_test = [f.split("/")[-1].split("!")[1] for f in files] + test_files = files[np.array(train_test) == "test"] + test_labels = [f.split("/")[-1].split("!")[0] for f in test_files] + + return test_files, test_labels + + +def test_data(predictor, data_folder): + results = {} + for path_video, label_video in zip(*get_test_data(data_folder)): + print(path_video, label_video) + start_time = time.time() + prediction = predict_video_files(predictor, path_video, label_video) + end_time = time.time() + elapsed_time = end_time - start_time + + # divide elapsed time by amount of predictions made so it represents an avarage execution time + if len(prediction) > 0: + elapsed_time /= len(prediction) + if label_video not in results: + results[label_video] = [] + results[label_video].append({"predictions": prediction, "elapsed_time": elapsed_time, "video": path_video}) + + print("DONE") + return results + + +def plot_general_accuracy(results): + accuracy = [] + amount = [] + for result in results: + for index, value in enumerate(result[0]): + if len(accuracy) <= index: + accuracy.append(0) + amount.append(0) + accuracy[index] += 1 if value["correct"] else 0 + amount[index] += 1 + # plot the general accuracy + plt.plot(accuracy) + plt.show() + + +if __name__ == "__main__": + type_predictor = "knn" + if type_predictor == "knn": + k = 1 + predictor_type = KNearestNeighbours(k) + elif type_predictor == "svm": + predictor_type = SVM() + else: + predictor_type = KNearestNeighbours(1) + + # embeddings_path = 'embeddings/basic-signs/embeddings.csv' + embeddings_path = 'embeddings/fingerspelling/embeddings.csv' + + predictor = Predictor(embeddings_path, predictor_type) + + data_folder = '/home/tibe/Projects/design_project/sign-predictor/data/fingerspelling/data/' + results = test_data(predictor, data_folder) + # write results to a results json file + with open("predictions/test_results/" + type_predictor + ".json", 'w') as f: + json.dump(results, f) + print(results) + # plot_general_accuracy(results) diff --git a/preprocessing.py b/preprocessing.py index 34ac917..ac4b7f5 100644 --- a/preprocessing.py +++ b/preprocessing.py @@ -1,5 +1,5 @@ from argparse import ArgumentParser -from preprocessing.create_wlasl_landmarks_dataset import parse_create_args, create +from preprocessing.create_fingerspelling_dataset import parse_create_args, create from preprocessing.extract_mediapipe_landmarks import parse_extract_args, extract diff --git a/preprocessing/create_fingerspelling_dataset.py b/preprocessing/create_fingerspelling_dataset.py new file mode 100644 index 0000000..c3793cb --- /dev/null +++ b/preprocessing/create_fingerspelling_dataset.py @@ -0,0 +1,174 @@ +import os +import os.path as op +import json +import shutil + +import cv2 +import mediapipe as mp +import numpy as np +import pandas as pd +from utils import get_logger +from tqdm.auto import tqdm +from sklearn.model_selection import train_test_split +from normalization.blazepose_mapping import map_blazepose_df + +BASE_DATA_FOLDER = 'data/' + +mp_drawing = mp.solutions.drawing_utils +mp_drawing_styles = mp.solutions.drawing_styles +mp_hands = mp.solutions.hands +mp_holistic = mp.solutions.holistic +pose_landmarks = mp_holistic.PoseLandmark +hand_landmarks = mp_holistic.HandLandmark + + +def get_landmarks_names(): + ''' + Returns landmark names for mediapipe holistic model + ''' + pose_lmks = ','.join([f'{lmk.name.lower()}_x,{lmk.name.lower()}_y' for lmk in pose_landmarks]) + left_hand_lmks = ','.join([f'left_hand_{lmk.name.lower()}_x,left_hand_{lmk.name.lower()}_y' + for lmk in hand_landmarks]) + right_hand_lmks = ','.join([f'right_hand_{lmk.name.lower()}_x,right_hand_{lmk.name.lower()}_y' + for lmk in hand_landmarks]) + lmks_names = f'{pose_lmks},{left_hand_lmks},{right_hand_lmks}' + return lmks_names + + +def convert_to_str(arr, precision=6): + if isinstance(arr, np.ndarray): + values = [] + for val in arr: + if val == 0: + values.append('0') + else: + values.append(f'{val:.{precision}f}') + return f"[{','.join(values)}]" + else: + return str(arr) + + +def parse_create_args(parser): + parser.add_argument('--landmarks-dataset', '-lmks', required=True, + help='Path to folder with landmarks npy files. \ + You need to run `extract_mediapipe_landmarks.py` script first') + parser.add_argument('--dataset-folder', '-df', default='data/wlasl', + help='Path to folder where original `WLASL_v0.3.json` and `id_to_label.json` are stored. \ + Note that final CSV files will be saved in this folder too.') + parser.add_argument('--videos-folder', '-videos', default=None, + help='Path to folder with videos. If None, then no information of videos (fps, length, \ + width and height) will be stored in final csv file') + parser.add_argument('--num-classes', '-nc', default=100, type=int, help='Number of classes to use in WLASL dataset') + parser.add_argument('--create-new-split', action='store_true') + parser.add_argument('--test-size', '-ts', default=0.25, type=float, + help='Test split percentage size. Only required if --create-new-split is set') + + +# python3 preprocessing.py --landmarks-dataset=data/landmarks -videos data/wlasl/videos +def create(args): + logger = get_logger(__name__) + + landmarks_dataset = args.landmarks_dataset + videos_folder = args.videos_folder + dataset_folder = args.dataset_folder + num_classes = args.num_classes + test_size = args.test_size + + os.makedirs(dataset_folder, exist_ok=True) + + # shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/id_to_label.json'), dataset_folder) + # shutil.copy(os.path.join(BASE_DATA_FOLDER, 'wlasl/WLASL_v0.3.json'), dataset_folder) + + # get files in landmarks_dataset folder + landmarks_files = os.listdir(landmarks_dataset) + + video_data = [] + for i, file in enumerate(tqdm(landmarks_files)): + + # split by ! + label = file.split('!')[0] + subset = file.split('!')[1].split('.')[0] + + # remove npy and set mp4 + video_id = file.replace('.npy', "") + + + video_dict = {'video_id': video_id, + 'label_name': label, + 'split': subset} + + if videos_folder is not None: + cap = cv2.VideoCapture(op.join(videos_folder, f'{video_id}.mp4')) + if not cap.isOpened(): + logger.warning(f'Video {video_id}.mp4 not found') + continue + width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) + height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) + fps = cap.get(cv2.CAP_PROP_FPS) + length = cap.get(cv2.CAP_PROP_FRAME_COUNT) / float(cap.get(cv2.CAP_PROP_FPS)) + video_info = {'video_width': width, + 'video_height': height, + 'fps': fps, + 'length': length} + video_dict.update(video_info) + video_data.append(video_dict) + + df_video = pd.DataFrame(video_data) + video_ids = df_video['video_id'].unique() + lmks_data = [] + lmks_names = get_landmarks_names().split(',') + + # get labels from df_video + labels = df_video['label_name'].unique() + # map labels to ids + label_to_id = {label: i for i, label in enumerate(labels)} + + # add label_id column to df_video + df_video['labels'] = df_video['label_name'].map(label_to_id) + + # export to json file as id to label + id_to_label = {i: label for label, i in label_to_id.items()} + with open(op.join(dataset_folder, 'id_to_label.json'), 'w') as f: + json.dump(id_to_label, f, indent=4) + + for video_id in video_ids: + lmk_fn = op.join(landmarks_dataset, f'{video_id}.npy') + if not op.exists(lmk_fn): + logger.warning(f'{lmk_fn} file not found. Skipping') + continue + lmk = np.load(lmk_fn).T + lmks_dict = {'video_id': video_id} + for lmk_, name in zip(lmk, lmks_names): + lmks_dict[name] = lmk_ + lmks_data.append(lmks_dict) + + df_lmks = pd.DataFrame(lmks_data) + df = pd.merge(df_video, df_lmks) + aux_columns = ['split', 'video_id', 'labels', 'label_name'] + if videos_folder is not None: + aux_columns += ['video_width', 'video_height', 'fps', 'length'] + df_aux = df[aux_columns] + df = map_blazepose_df(df) + df = pd.concat([df, df_aux], axis=1) + if args.create_new_split: + df_train, df_test = train_test_split(df, test_size=test_size, stratify=df['labels'], random_state=42) + + + print(f'Num classes: {num_classes}') + print(df_train['labels'].value_counts()) + print(df_test['labels'].value_counts()) + assert set(df_train['labels'].unique()) == set(df_test['labels'].unique( + )), 'The labels for train and test dataframe are different. We recommend to download the dataset again, or to use \ + the --create-new-split flag' + for split, df_split in zip(['train', 'val'], + [df_train, df_test]): + fn_out = op.join(dataset_folder, f'{split}.csv') + (df_split.reset_index(drop=True) + .applymap(convert_to_str) + .to_csv(fn_out, index=False)) + + else: + fn_out = op.join(dataset_folder, 'train.csv') + (df.reset_index(drop=True) + .applymap(convert_to_str) + .to_csv(fn_out, index=False)) \ No newline at end of file diff --git a/preprocessing/create_google_asl_landmarks_dataset.py b/preprocessing/create_google_asl_landmarks_dataset.py index 4a4beda..c128356 100644 --- a/preprocessing/create_google_asl_landmarks_dataset.py +++ b/preprocessing/create_google_asl_landmarks_dataset.py @@ -4,6 +4,8 @@ import pandas as pd from tqdm.auto import tqdm import json +from normalization.blazepose_mapping import map_blazepose_df + def create(train_landmark_files, train_csv, dataset_folder, test_size): os.makedirs(dataset_folder, exist_ok=True) @@ -17,15 +19,15 @@ def create(train_landmark_files, train_csv, dataset_folder, test_size): mapping = { 'pose_0': 'nose', 'pose_1': 'leftEye', - 'pose_2': 'rightEye', - 'pose_3': 'leftEar', - 'pose_4': 'rightEar', - 'pose_5': 'leftShoulder', - 'pose_6': 'rightShoulder', - 'pose_7': 'leftElbow', - 'pose_8': 'rightElbow', - 'pose_9': 'leftWrist', - 'pose_10': 'rightWrist', + 'pose_4': 'rightEye', + 'pose_7': 'leftEar', + 'pose_8': 'rightEar', + 'pose_11': 'leftShoulder', + 'pose_12': 'rightShoulder', + 'pose_13': 'leftElbow', + 'pose_14': 'rightElbow', + 'pose_15': 'leftWrist', + 'pose_16': 'rightWrist', 'left_hand_0': 'wrist_left', 'left_hand_1': 'thumbCMC_left', @@ -77,7 +79,7 @@ def create(train_landmark_files, train_csv, dataset_folder, test_size): columns.append(f'{v}_X') columns.append(f'{v}_Y') - for _, row in tqdm(train_df.head(6000).iterrows(), total=6000): + for _, row in tqdm(train_df.head(10000).iterrows(), total=10000): path, participant_id, sequence_id, sign = row['path'], row['participant_id'], row['sequence_id'], row['sign'] parquet_file = os.path.join(train_landmark_files, str(participant_id), f"{sequence_id}.parquet") @@ -136,6 +138,7 @@ def create(train_landmark_files, train_csv, dataset_folder, test_size): video_data.append(new_landmark_data) video_data = pd.concat(video_data, axis=0, ignore_index=True) + video_data = map_blazepose_df(video_data, rename=False) video_data.to_csv(os.path.join(dataset_folder, 'spoter.csv'), index=False) train_landmark_files = 'data/train_landmark_files' diff --git a/preprocessing/create_wlasl_landmarks_dataset.py b/preprocessing/create_wlasl_landmarks_dataset.py index c1e4d5c..53d5cf4 100644 --- a/preprocessing/create_wlasl_landmarks_dataset.py +++ b/preprocessing/create_wlasl_landmarks_dataset.py @@ -110,6 +110,7 @@ def create(args): 'length': length} video_dict.update(video_info) video_data.append(video_dict) + df_video = pd.DataFrame(video_data) video_ids = df_video['video_id'].unique() lmks_data = [] @@ -126,9 +127,7 @@ def create(args): lmks_data.append(lmks_dict) df_lmks = pd.DataFrame(lmks_data) - print(df_lmks) df = pd.merge(df_video, df_lmks) - print(df) aux_columns = ['split', 'video_id', 'labels', 'label_name'] if videos_folder is not None: aux_columns += ['video_width', 'video_height', 'fps', 'length'] diff --git a/preprocessing/extract_mediapipe_landmarks.py b/preprocessing/extract_mediapipe_landmarks.py index 6d63076..f421919 100644 --- a/preprocessing/extract_mediapipe_landmarks.py +++ b/preprocessing/extract_mediapipe_landmarks.py @@ -132,6 +132,12 @@ def extract(args): ret, image_orig = cap.read() height, width = image_orig.shape[:2] landmarks_video = [] + + # make sure fps is 20 by determining the number of frames to be skipped + frame_rate = int(cap.get(cv2.CAP_PROP_FPS)) + frame_skip = (frame_rate // 20) - 1 + + with tqdm(total=int(cap.get(cv2.CAP_PROP_FRAME_COUNT))) as pbar: with mp_holistic.Holistic( static_image_mode=False, @@ -145,6 +151,9 @@ def extract(args): print(e) landmarks = get_landmarks(image_orig, holistic, debug=True) ret, image_orig = cap.read() + for _ in range(frame_skip): + ret, image_orig = cap.read() + pbar.update(1) landmarks_video.append(landmarks) pbar.update(1) landmarks_video = np.vstack(landmarks_video) diff --git a/preprocessing/split_dataset.py b/preprocessing/split_dataset.py index 17e1f55..3fa13c7 100644 --- a/preprocessing/split_dataset.py +++ b/preprocessing/split_dataset.py @@ -8,7 +8,6 @@ dataset = "data/processed/spoter.csv" # read the dataset df = pd.read_csv(dataset) -df = map_blazepose_df(df) with open("data/sign_to_prediction_index_map.json", "r") as f: sign_to_prediction_index_max = json.load(f) diff --git a/requirements.txt b/requirements.txt index 2308b4c..d83a933 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ pandas bokeh==2.4.3 boto3>=1.9 -clearml==1.6.4 ipywidgets==8.0.4 matplotlib==3.5.3 mediapipe==0.8.11 @@ -9,6 +8,8 @@ notebook==6.5.2 opencv-python==4.6.0.66 plotly==5.11.0 scikit-learn==1.0.2 -torch -torchvision +clearml==1.10.3 +torch==2.0.0 +torchvision==0.15.1 tqdm==4.54.1 +optuna==3.1.1 \ No newline at end of file diff --git a/train.py b/train.py index 76fabfe..939ca07 100644 --- a/train.py +++ b/train.py @@ -15,7 +15,7 @@ from torchvision import transforms from torch.utils.data import DataLoader from pathlib import Path import copy - +import numpy as np from datasets import CzechSLRDataset, SLREmbeddingDataset, collate_fn_triplet_padd, collate_fn_padd from models import SPOTER, SPOTER_EMBEDDINGS, train_epoch, evaluate, train_epoch_embedding, \ train_epoch_embedding_online, evaluate_embedding @@ -32,7 +32,7 @@ except ImportError: pass -PROJECT_NAME = "spoter" +PROJECT_NAME = "SpoterEmbedding" CLEARML = "clearml" @@ -75,12 +75,25 @@ def train(args, tracker: Tracker): # Construct the model if not args.classification_model: - slrt_model = SPOTER_EMBEDDINGS( - features=args.vector_length, - hidden_dim=args.hidden_dim, - norm_emb=args.normalize_embeddings, - dropout=args.dropout - ) + # if finetune, load the weights from the classification model + if args.finetune: + checkpoint = torch.load(args.checkpoint_path, map_location=device) + + slrt_model = SPOTER_EMBEDDINGS( + features=checkpoint["config_args"].vector_length, + hidden_dim=checkpoint["config_args"].hidden_dim, + norm_emb=checkpoint["config_args"].normalize_embeddings, + dropout=checkpoint["config_args"].dropout, + ) + else: + slrt_model = SPOTER_EMBEDDINGS( + features=args.vector_length, + hidden_dim=args.hidden_dim, + norm_emb=args.normalize_embeddings, + dropout=args.dropout, + ) + + model_type = 'embed' if args.hard_triplet_mining == "None": cel_criterion = nn.TripletMarginLoss(margin=args.triplet_loss_margin, p=2) diff --git a/train.sh b/train.sh index fe68689..f69cc31 100755 --- a/train.sh +++ b/train.sh @@ -1,22 +1,23 @@ #!/bin/sh -python -m train \ - --save_checkpoints_every 10 \ - --experiment_name "augment_rotate_75_x8" \ - --epochs 300 \ +python3 -m train \ + --save_checkpoints_every 1 \ + --experiment_name "Finetune Basic Signs" \ + --epochs 100 \ --optimizer "ADAM" \ - --lr 0.001 \ + --lr 0.00001 \ --batch_size 16 \ - --dataset_name "processed" \ - --training_set_path "spoter_train.csv" \ - --validation_set_path "spoter_test.csv" \ + --dataset_name "BasicSigns" \ + --training_set_path "train.csv" \ + --validation_set_path "val.csv" \ --vector_length 32 \ --epoch_iters -1 \ - --scheduler_factor 0 \ - --hard_triplet_mining "in_batch" \ + --scheduler_factor 0.05 \ + --hard_triplet_mining "None" \ --filter_easy_triplets \ - --triplet_loss_margin 1 \ + --triplet_loss_margin 2 \ --dropout 0.2 \ - --augmentations_prob=0.75 \ - --hard_mining_scheduler_triplets_threshold=0 \ - --normalize_embeddings \ - --num_classes 100 \ \ No newline at end of file + --tracker=clearml \ + --dataset_loader=clearml \ + --dataset_project="SpoterEmbedding" \ + --finetune \ + --checkpoint_path "checkpoints/checkpoint_embed_3006.pth" \ No newline at end of file diff --git a/training/train_arguments.py b/training/train_arguments.py index 5980aff..1a56874 100644 --- a/training/train_arguments.py +++ b/training/train_arguments.py @@ -81,4 +81,7 @@ def get_default_args(): help="Enables batching grouping scheduler if > 0. Defines threshold for when to decay the \ distance threshold of the batch sorter") + parser.add_argument("--finetune", action='store_true', default=False, help="Fintune the model") + parser.add_argument("--checkpoint_path", type=str, default="") + return parser diff --git a/visualize_data.ipynb b/visualize_data.ipynb new file mode 100644 index 0000000..2146c06 --- /dev/null +++ b/visualize_data.ipynb @@ -0,0 +1,1636 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from augmentations.augment import __preprocess_row_sign" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 path\n", + "1 participant_id\n", + "2 sequence_id\n", + "3 sign\n", + "4 labels\n", + "5 nose_X\n", + "6 nose_Y\n", + "7 leftEye_X\n", + "8 leftEye_Y\n", + "9 rightEye_X\n", + "10 rightEye_Y\n", + "11 leftEar_X\n", + "12 leftEar_Y\n", + "13 rightEar_X\n", + "14 rightEar_Y\n", + "15 leftShoulder_X\n", + "16 leftShoulder_Y\n", + "17 rightShoulder_X\n", + "18 rightShoulder_Y\n", + "19 leftElbow_X\n", + "20 leftElbow_Y\n", + "21 rightElbow_X\n", + "22 rightElbow_Y\n", + "23 leftWrist_X\n", + "24 leftWrist_Y\n", + "25 rightWrist_X\n", + "26 rightWrist_Y\n", + "27 wrist_left_X\n", + "28 wrist_left_Y\n", + "29 thumbCMC_left_X\n", + "30 thumbCMC_left_Y\n", + "31 thumbMP_left_X\n", + "32 thumbMP_left_Y\n", + "33 thumbIP_left_X\n", + "34 thumbIP_left_Y\n", + "35 thumbTip_left_X\n", + "36 thumbTip_left_Y\n", + "37 indexMCP_left_X\n", + "38 indexMCP_left_Y\n", + "39 indexPIP_left_X\n", + "40 indexPIP_left_Y\n", + "41 indexDIP_left_X\n", + "42 indexDIP_left_Y\n", + "43 indexTip_left_X\n", + "44 indexTip_left_Y\n", + "45 middleMCP_left_X\n", + "46 middleMCP_left_Y\n", + "47 middlePIP_left_X\n", + "48 middlePIP_left_Y\n", + "49 middleDIP_left_X\n", + "50 middleDIP_left_Y\n", + "51 middleTip_left_X\n", + "52 middleTip_left_Y\n", + "53 ringMCP_left_X\n", + "54 ringMCP_left_Y\n", + "55 ringPIP_left_X\n", + "56 ringPIP_left_Y\n", + "57 ringDIP_left_X\n", + "58 ringDIP_left_Y\n", + "59 ringTip_left_X\n", + "60 ringTip_left_Y\n", + "61 littleMCP_left_X\n", + "62 littleMCP_left_Y\n", + "63 littlePIP_left_X\n", + "64 littlePIP_left_Y\n", + "65 littleDIP_left_X\n", + "66 littleDIP_left_Y\n", + "67 littleTip_left_X\n", + "68 littleTip_left_Y\n", + "69 wrist_right_X\n", + "70 wrist_right_Y\n", + "71 thumbCMC_right_X\n", + "72 thumbCMC_right_Y\n", + "73 thumbMP_right_X\n", + "74 thumbMP_right_Y\n", + "75 thumbIP_right_X\n", + "76 thumbIP_right_Y\n", + "77 thumbTip_right_X\n", + "78 thumbTip_right_Y\n", + "79 indexMCP_right_X\n", + "80 indexMCP_right_Y\n", + "81 indexPIP_right_X\n", + "82 indexPIP_right_Y\n", + "83 indexDIP_right_X\n", + "84 indexDIP_right_Y\n", + "85 indexTip_right_X\n", + "86 indexTip_right_Y\n", + "87 middleMCP_right_X\n", + "88 middleMCP_right_Y\n", + "89 middlePIP_right_X\n", + "90 middlePIP_right_Y\n", + "91 middleDIP_right_X\n", + "92 middleDIP_right_Y\n", + "93 middleTip_right_X\n", + "94 middleTip_right_Y\n", + "95 ringMCP_right_X\n", + "96 ringMCP_right_Y\n", + "97 ringPIP_right_X\n", + "98 ringPIP_right_Y\n", + "99 ringDIP_right_X\n", + "100 ringDIP_right_Y\n", + "101 ringTip_right_X\n", + "102 ringTip_right_Y\n", + "103 littleMCP_right_X\n", + "104 littleMCP_right_Y\n", + "105 littlePIP_right_X\n", + "106 littlePIP_right_Y\n", + "107 littleDIP_right_X\n", + "108 littleDIP_right_Y\n", + "109 littleTip_right_X\n", + "110 littleTip_right_Y\n", + "111 neck_X\n", + "112 neck_Y\n" + ] + } + ], + "source": [ + "df = pd.read_csv('data/processed/spoter_train.csv')\n", + "for i, e in enumerate(df.columns):\n", + " print(i, e)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "# dataset = 'data/processed/spoter_train.csv'\n", + "\n", + "def plot(dataset):\n", + " df = pd.read_csv(dataset)\n", + " # get columns 0 - 26\n", + " # df = df.iloc[:, 5:27]\n", + "\n", + "\n", + " # df = df.iloc[:, 27:69]\n", + " # df = df.iloc[:, 69:]\n", + "\n", + " if 'wlasl' in dataset:\n", + " df = df.iloc[:, :108]\n", + "\n", + " else:\n", + " df = df.iloc[:, 5:]\n", + "\n", + "\n", + " # get first row\n", + " row = df.iloc[20]\n", + "\n", + " # use matplotlib to create a scatter plot (the columns are X, Y, X, Y, X, Y, X, Y)\n", + " import matplotlib.pyplot as plt\n", + " import ast\n", + "\n", + " def __process_row(coords):\n", + " coords = coords.tolist()\n", + "\n", + " new_coords = [] # string to list\n", + "\n", + " for x in coords:\n", + " new_coords.append(ast.literal_eval(x))\n", + "\n", + " coords = [x[0] for x in new_coords]\n", + "\n", + " return [float(x) for x in coords]\n", + "\n", + "\n", + " # extract X and Y coordinates from the row\n", + " x_coords = row.iloc[::2] # columns 0, 2, 4, 6, ...\n", + " y_coords = row.iloc[1::2] # columns 1, 3, 5, 7, ...\n", + "\n", + " x_coords = __process_row(x_coords)\n", + " y_coords = __process_row(y_coords)\n", + "\n", + " # create a scatter plot\n", + " plt.scatter(x_coords, y_coords)\n", + "\n", + "\n", + " plt.xlim(0, 1)\n", + " plt.ylim(0, 1)\n", + " \n", + " # add axis labels and a title\n", + " plt.xlabel('X')\n", + " plt.ylabel('Y')\n", + " plt.title('Scatter plot of X and Y coordinates')\n", + "\n", + " # show the plot\n", + " plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHHCAYAAABTMjf2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA6QklEQVR4nO3de1yUZf7/8TegzHjgoCEHjURNMzyRKCweMg3DdDFrLdPylJtpZim1q6aJh0rXyqU8a6V9bV3dytoOhgc2tzXZxRVtPaQdxLRWUDPBNEWZ6/eHP2YdAQUDBuZ+PR+PeTyaa677vj/3XEPz9r6v+x4vY4wRAACABXm7uwAAAAB3IQgBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBHuC2227Tbbfd5u4yXOTk5Kh///667rrr5OXlpZSUFHeXVC4iIiI0bNgwd5dRJVz+uTt48KC8vLy0YsUKt9UElBVBCFXWrl271L9/fzVu3Fh2u12NGjVSz549NW/evArb5qpVq4r9wv7vf/+radOmaefOnRW2bXc4c+aMpk2bps2bN5f7usePH6/169dr0qRJWrlypXr16lVsv40bN8rLy0vTp08v8lpWVpZq166t/v37l3t9FWX16tXy8vLSkiVLin199OjRqlmzpj7//PNKrsxzPP/883rvvffcXQY8hQGqoM8++8z4+vqaG2+80cycOdMsW7bMTJ061dxxxx2mWbNmFbbdPn36mMaNGxdp37Ztm5Fkli9fXmHb/iW6detmunXrVubljh07ZiSZ5OTkcq8pJCTEPPDAA6XqO2jQIGOz2cz+/ftd2nv16mX8/f3N999/X+71XavGjRuboUOHXrFPr169TGBgoMnOznZp/9e//mW8vb3N7373uwqssPJc/rlzOBzm559/NhcuXKjQ7dapU+eqYwCUVg13BzGgOM8995wCAgK0bds2BQYGurx29OhR9xRVAU6fPq06deq4u4wKcfTo0SJjV5I//vGP+vjjjzVq1Cj97W9/k3TxyEpqaqpeeeUVNWzYsAIrLX+LFi1Sq1atNH78eK1atUqSVFBQoEceeUQ33HCDpk2b5t4CS6msn08vLy/Z7fYKrAioAO5OYkBxbrrpJnPbbbeVuv/KlStNx44dTa1atUxgYKDp2rWrWb9+vfP19957z/Tu3duEhYUZX19f07RpUzNjxgyXf7l269bNSHJ5NG7c2HzyySdF2nXZ0aF//vOfJiEhwfj7+5tatWqZW2+91WzZssWlxuTkZCPJ7NmzxwwcONAEBgaaqKioEvdp+fLlRpL5+9//bkaOHGnq169v/Pz8zODBg82JEydc+hZ3RCgnJ8c89NBDJjg42NhsNtO2bVuzYsUK5+tZWVnF7tfVjg598803pn///qZevXqmVq1aJjY21nz44YdF6r78cTVLly41ksyKFSvMjz/+aEJDQ03Hjh1NQUHBVZc9ePCgGT16tGnRooWx2+2mfv36pn///iYrK8ulX2FtW7ZsMePHjzdBQUGmdu3apl+/fubo0aMufR0Oh5k5c6Zp1KiRqVWrlrntttvM7t27S3VEyBhj5syZYySZDRs2GGOMmTt3rpFkPv7446sua8zFz9Sdd95pAgMDTe3atU2bNm1MSkqKS5+0tDTTpUsXU7t2bRMQEGD69u1r9u7dW2RdmZmZplevXsbPz8/UqVPH9OjRw6Snpxf73mzevNmMHj3aNGjQwAQGBjpfX7JkiWnatKmx2+2mY8eO5tNPPy3yuSv8TF36tzF06FBTp04d891335m77rrL1KlTxwQFBZknn3yyyJGjF154wcTFxZn69esbu91u2rdvb9566y2XPsV9ti4dj++++84MHz7cBAcHG19fXxMZGWlee+21Iu/JK6+8YiIjI53/z4iOjjZ/+tOfShwPeC6CEKqkO+64w/j5+Zldu3Zdte+0adOMJNOpUyfzwgsvmJdfftkMGjTITJgwwdmnX79+5r777jMvvPCCWbRokbn33nuNJPPUU085+2zYsMFERUWZoKAgs3LlSrNy5Urz7rvvmuzsbDNjxgwjyYwcOdL52jfffGOMufhl5Ovra+Li4sxLL71k/vjHP5q2bdsaX19f869//cu5/sIgFBkZae666y6zcOFCs2DBghL3q/CLqU2bNqZr167mlVdeMWPGjDHe3t7m1ltvNQ6Hw9n38i+kM2fOmJtvvtnUrFnTjB8/3rzyyiuma9euRpLzy/Snn34yixYtMpLM3Xff7dyvzz//vMSasrOzTUhIiPHz8zOTJ082c+fONe3atTPe3t5m7dq1xpiLQWnlypVGkunZs6dzvVfjcDhM586dTVBQkBk4cKDx8fExmZmZV13OGGPeeust065dOzN16lSzdOlS8/TTT5t69eqZxo0bm9OnTxd5T2+55RbTo0cPM2/ePPPkk08aHx8fc99997msc8qUKUaS6d27t5k/f7556KGHTMOGDU1QUFCpgtD58+dNu3btTLNmzcxXX31l6tata+6///5S7c+GDRuMr6+vady4sUlOTjaLFi0yjz/+uImPj3f22bhxo6lRo4Zp0aKFmTNnjpk+fboJCgoy9erVcwmAu3fvNnXq1DFhYWFm5syZZvbs2aZJkybGZrOZf/7zn0Xem8jISNOtWzczb948M3v2bGOMMa+++qrzb+yVV14x48aNM4GBgaZp06alCkJ2u920atXKPPTQQ2bRokXmN7/5jZFkFi5c6LLf119/vXn00UfN/Pnzzdy5c01MTIyR5BK0V65caWw2m+natavzs7V161ZjzMXP5/XXX2/Cw8PNjBkzzKJFi0zfvn2NJPPHP/7RuY7C0N2/f3+zZMkS8/LLL5sRI0aYxx9/vFTjA89CEEKVtGHDBuPj42N8fHxMXFyc+f3vf2/Wr19v8vPzXfp99dVXxtvb29x9991FjhxcGhTOnDlTZBuPPPKIqV27tjl79qyzraxzhBwOh2nevLlJSEgosr0mTZqYnj17OtsKg9DAgQNL9R4UfjFFR0e77HfhkYa//vWvzrbLg1BKSoqRZN58801nW35+vomLizN169Y1eXl5xpiyzxEaN26ckWT+8Y9/ONtOnTplmjRpYiIiIlzGQJIZM2ZMqdZbaPfu3aZmzZpGkhk3blyplytufNPT040k83//93/OtsL3ND4+3mW8xo8fb3x8fMzJkyeNMcYcPXrU+Pr6mj59+rj0e/rpp4scgbiSwjlB9evXL3bOUHEuXLhgmjRpYho3bmx+/PFHl9curSUqKsoEBwebH374wdn2+eefG29vbzNkyBBnW79+/Yyvr68zuBtjzH//+1/j5+dnbr31Vmdb4XvTpUsXlyM1+fn5Jjg42ERFRZlz58452wvDRGmCkCQzY8YMl3255ZZbTHR0tEvb5eOYn59vWrdubXr06OHSXtIcoREjRpiwsDBz/Phxl/b777/fBAQEONd/1113mVatWhVZHtbEVWOoknr27Kn09HT17dtXn3/+uebMmaOEhAQ1atRI77//vrPfe++9J4fDoalTp8rb2/Xj7OXl5fzvWrVqOf/71KlTOn78uLp27aozZ85o375911znzp079dVXX2nQoEH64YcfdPz4cR0/flynT5/W7bffrk8//VQOh8NlmVGjRpVpGyNHjlTNmjWdz0ePHq0aNWpo3bp1JS6zbt06hYaGauDAgc62mjVr6vHHH9dPP/2kv//972Wq4dL1xsTEqEuXLs62unXrauTIkTp48KD27t17Test5O/vL19fX0nSHXfcUerlLh3f8+fP64cfftCNN96owMBAZWZmFuk/cuRIl89H165dVVBQoG+//VaStGnTJuXn52vs2LEu/caNG1em/YmJidGoUaN04sQJzZo1SyEhIVddZseOHcrKytK4ceOKzLEqrOXIkSPauXOnhg0bpvr16ztfb9u2rXr27On8bBQUFGjDhg3q16+fmjZt6uwXFhamQYMGacuWLcrLy3PZxsMPPywfHx/n83//+986evSoRo0a5RwbSRo2bJgCAgJK/V5c/rnv2rWrDhw44NJ26Tj++OOPys3NVdeuXYsdw8sZY/TOO+8oMTFRxhjn3+Lx48eVkJCg3Nxc53oCAwP13Xffadu2baWuH56LIIQqq2PHjlq7dq1+/PFHZWRkaNKkSTp16pT69+/v/ML95ptv5O3trcjIyCuua8+ePbr77rsVEBAgf39/NWjQQA8++KAkKTc395pr/OqrryRJQ4cOVYMGDVwer776qs6dO1dk/U2aNCnTNpo3b+7yvG7dugoLC9PBgwdLXObbb79V8+bNi4TDm2++2fn6tfj222910003FWn/pest9Nhjj8nb21uNGzfWk08+qfPnz5dquZ9//llTp05VeHi4bDabgoKC1KBBA508ebLY8b3hhhtcnterV0/SxS/fS/fj8ve+QYMGzr6l1bFjR0lShw4dStX/m2++kSS1bt26xD6F9ZU0FoVh/NixYzpz5kyJ/RwOhw4fPuzSfvnns6T3ombNmi7h6krsdrsaNGjg0lavXj3n+13oww8/1K9+9SvZ7XbVr19fDRo00KJFi0r1N3rs2DGdPHlSS5cuLfK3OHz4cEn/u9BiwoQJqlu3rmJiYtS8eXONGTNGn332Wan2BZ6Hq8ZQ5fn6+qpjx47q2LGjWrRooeHDh+utt95ScnJyqZY/efKkunXrJn9/f82YMUPNmjWT3W5XZmamJkyYUOSITVkULvvCCy8oKiqq2D5169Z1eX7pv3rxP2vXrtX777+vlJQUNW/eXH369NELL7ygp59++qrLjh07VsuXL9e4ceMUFxengIAAeXl56f777y92fC894nEpY8wv3o/qriI+nyW935f6xz/+ob59++rWW2/VwoULFRYWppo1a2r58uXOK++upHCcH3zwQQ0dOrTYPm3btpV0MQTu379fH374oVJTU/XOO+9o4cKFmjp1arH3s4JnIwihWin8V/WRI0ckSc2aNZPD4dDevXtLDCKbN2/WDz/8oLVr1+rWW291tmdlZRXpe+lpkNK0N2vWTNLFUzrx8fGl3o+y+Oqrr9S9e3fn859++klHjhxR7969S1ymcePG+s9//iOHw+FyVKjwNGDjxo0llbxfV1rv/v37i7Rfvt6yOnXqlB5//HG1b99ejz32mHx8fPSb3/xGzz77rAYOHHjVo2hvv/22hg4dqpdeesnZdvbsWZ08efKa6incj6+++srlqMexY8eKHMUob4Wfqd27d5f4mSqsr6SxCAoKUp06dWS321W7du0S+3l7eys8PPyK9Vz6XvTo0cPZfv78eWVlZaldu3al27GreOedd2S327V+/XrZbDZn+/Lly4v0Le5z26BBA/n5+amgoKBUf4t16tTRgAEDNGDAAOXn5+uee+7Rc889p0mTJnELAIvh1BiqpE8++aTYf50Xzn0oPNTfr18/eXt7a8aMGUX+5V+4fOG/Ri9dX35+vhYuXFhk/XXq1Cn2MHzhvVQu/2KNjo5Ws2bN9OKLL+qnn34qstyxY8dK3MfSWrp0qcspokWLFunChQu68847S1ymd+/eys7O1po1a5xtFy5c0Lx581S3bl1169ZNklS7dm1JRffrSuvNyMhQenq6s+306dNaunSpIiIirnqKsiRTpkzRkSNHtGTJEud4vfzyy/Lx8dFjjz121eV9fHyKfF7mzZungoKCa6onPj5eNWvW1Lx581zWWxk/E9K+fXs1adJEKSkpRcalsJawsDBFRUXpjTfecOmze/dubdiwwRmSfXx8dMcdd+ivf/2ry6nUnJwcrVq1Sl26dJG/v/8V6+nQoYMaNGigxYsXKz8/39m+YsWKaw6axfHx8ZGXl5fLmB08eLDYO0jXqVOnyLYLw/M777yj3bt3F1nm0r/FH374weU1X19fRUZGyhhT6tOx8BwcEUKVNHbsWJ05c0Z33323WrZsqfz8fG3dulVr1qxRRESE85z/jTfeqMmTJ2vmzJnq2rWr7rnnHtlsNm3btk0NGzbUrFmz1KlTJ9WrV09Dhw7V448/Li8vL61cubLYoBUdHa01a9YoKSlJHTt2VN26dZWYmKhmzZopMDBQixcvlp+fn+rUqaPY2Fg1adJEr776qu688061atVKw4cPV6NGjfT999/rk08+kb+/vz744INf9F7k5+fr9ttv13333af9+/dr4cKF6tKli/r27VviMiNHjtSSJUs0bNgwbd++XREREXr77bf12WefKSUlRX5+fpIungaJjIzUmjVr1KJFC9WvX1+tW7cucX7KxIkT9ec//1l33nmnHn/8cdWvX19vvPGGsrKy9M477xSZk1Qa27dv14IFCzRmzBiXeTSNGjXSjBkzlJSUpHfeeUe/+c1vSlzHr3/9a61cuVIBAQGKjIxUenq6Nm3apOuuu67M9UgXjy489dRTmjVrln7961+rd+/e2rFjhz7++GMFBQVd0zpLy9vbW4sWLVJiYqKioqI0fPhwhYWFad++fdqzZ4/Wr18v6eLp2DvvvFNxcXEaMWKEfv75Z82bN08BAQEuN2x89tlntXHjRnXp0kWPPvqoatSooSVLlujcuXOaM2fOVeupWbOmnn32WT3yyCPq0aOHBgwYoKysLC1fvrzUc4RKo0+fPpo7d6569eqlQYMG6ejRo1qwYIFuvPFG/ec//3HpGx0drU2bNmnu3Llq2LChmjRpotjYWM2ePVuffPKJYmNj9fDDDysyMlInTpxQZmamNm3apBMnTki6OBE/NDRUnTt3VkhIiL744gvNnz9fffr0cf5twELcdLUacEUff/yxeeihh0zLli1N3bp1nT+3MXbsWJOTk1Ok/+uvv25uueUWY7PZTL169Uy3bt3Mxo0bna9/9tln5le/+pWpVauWadiwofNyfEnmk08+cfb76aefzKBBg0xgYKDzhoqF/vrXv5rIyEhTo0aNIpcI79ixw9xzzz3muuuuMzabzTRu3Njcd999Ji0tzdmn8PL5Y8eOleo9uPyGivXq1TN169Y1DzzwgMsl08aUfEPF4cOHm6CgIOPr62vatGlT7E+EbN261URHRxtfX98y3VAxMDDQ2O12ExMT43Kfl0IqxeXzFy5cMO3btzcNGzY0ubm5xb4eFRVlrr/+enPq1KkS1/Pjjz8697Vu3bomISHB7Nu3r8jNDwvf023btrks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g7Vs2TIFBQWVaplJkyYpNzfX+Th8+HAFVwkAAKqLGu7ceFBQkHx8fJSTk+PSnpOTo9DQ0CL9v/nmGx08eFCJiYnONofDIUmqUaOG9u/fr2bNmrksY7PZZLPZKqB6AABQ3bn1iJCvr6+io6OVlpbmbHM4HEpLS1NcXFyR/i1bttSuXbu0c+dO56Nv377q3r27du7cyWkvAABQJm49IiRJSUlJGjp0qDp06KCYmBilpKTo9OnTGj58uCRpyJAhatSokWbNmiW73a7WrVu7LB8YGChJRdoBAACuxu1BaMCAATp27JimTp2q7OxsRUVFKTU11TmB+tChQ/L2rlZTmQAAQDXhZYwx7i6iMuXl5SkgIEC5ubny9/d3dzkAAKAUKur7m0MtAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsmq4uwAAqAwFDqOMrBM6euqsgv3simlSXz7eXu4uC4CbEYQAeLzU3Uc0/YO9OpJ71tkWFmBXcmKkerUOc2NlANyNU2MAPFrq7iMa/WamSwiSpOzcsxr9ZqZSdx9xU2UAqgKCEACPVeAwmv7BXpliXitsm/7BXhU4iusBwAoIQgA8VkbWiSJHgi5lJB3JPauMrBOVVxSAKoUgBMBjHT1Vcgi6ln4APA+TpQF4lEuvDjt+6lyplgn2s1dwVVfGFW2A+xCEAHiM4q4O8/aSSpoC5CUpNOBi8HAXrmgD3ItTYwA8QklXh10pBElScmKk246+cEUb4H4EIQDV3pWuDit0edYJDbBr0YPt3XbUhSvagKqBU2MAqr2rXR0mXTwy9EyfmxXkZ6sS83DKckVbXLPrKq8wwGIIQgCqvdJe9RXkZ9NdUY0quJrS4Yo2oGrg1BiAaq+0V325++qwS1XHmgFPRBACUO3FNKmvsAC7SjrR5aWLV2K58+qwy1XHmgFPRBAC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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot('data/wlasl/WLASL100_train.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHHCAYAAABTMjf2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA+8UlEQVR4nO3de1zUVeL/8TcgzHgDNBTQyFuWkRcShaU00zAs17LWMi1vtVmmllK7apakVrpdzPKulfa1bXW738wb5bYWu7iilZlWimmt4C3BNEXh/P7wx6zDRWdwhhnm83o+HjwezeF8Zs5nPkPz9pzzOSfIGGMEAABgQcG+bgAAAICvEIQAAIBlEYQAAIBlEYQAAIBlEYQAAIBlEYQAAIBlEYQAAIBlEYQAAIBlEYQAAIBlEYSAAHDNNdfommuu8XUznOTn56tfv3664IILFBQUpJkzZ/q6SR7RvHlzDR061NfN8AtlP3e7du1SUFCQlixZ4rM2Ae4iCMFvff311+rXr5+aNWsmu92upk2bqmfPnpo1a5bXXvP111+v8Av7v//9rx5//HFt3rzZa6/tC8eOHdPjjz+udevWefy5x44dq1WrVmnChAlaunSpevXqVWG9NWvWKCgoSJMnTy73u9zcXNWpU0f9+vXzePu8ZdmyZQoKCtKCBQsq/P2IESMUGhqqL7/8sppbFjieeuopvfvuu75uBgKFAfzQ559/bsLCwszFF19spk6dahYtWmQmTZpkrrvuOtOqVSuvvW7v3r1Ns2bNypVv2LDBSDKLFy/22mufj27duplu3bq5fdz+/fuNJJORkeHxNkVHR5s77rjDpboDBw40NpvNbN++3am8V69eJjw83Pz8888eb19VNWvWzAwZMuSsdXr16mUiIyNNXl6eU/m///1vExwcbP70pz95sYXVp+znrqSkxPz222/m1KlTXn3dunXrnvMaAK6q5esgBlTkySefVEREhDZs2KDIyEin3+3bt883jfKCo0ePqm7dur5uhlfs27ev3LWrzPPPP6+PP/5Y9913nz755BNJp3tWVq5cqRdffFFNmjTxYks9b968ebr88ss1duxYvf7665Kk4uJi3Xvvvbrooov0+OOP+7aBLnL38xkUFCS73e7FFgFe4OskBlTk0ksvNddcc43L9ZcuXWo6d+5sateubSIjI03Xrl3NqlWrHL9/9913zQ033GBiY2NNWFiYadmypZkyZYrTv1y7detmJDn9NGvWzHz66aflylWmd+hf//qXSUtLM+Hh4aZ27drm6quvNuvXr3dqY0ZGhpFkvvnmGzNgwAATGRlpEhISKj2nxYsXG0nmH//4hxk+fLhp2LChqV+/vhk0aJA5dOiQU92KeoTy8/PNXXfdZRo3bmxsNptp3769WbJkieP3ubm5FZ7XuXqHduzYYfr162caNGhgateubZKTk82HH35Yrt1lf85l4cKFRpJZsmSJ+eWXX0xMTIzp3LmzKS4uPuexu3btMiNGjDCXXHKJsdvtpmHDhqZfv34mNzfXqV5p29avX2/Gjh1roqKiTJ06dUzfvn3Nvn37nOqWlJSYqVOnmqZNm5ratWuba665xmzZssWlHiFjjHn66aeNJLN69WpjjDEzZswwkszHH398zmONOf2Zuv76601kZKSpU6eOadeunZk5c6ZTnczMTNOlSxdTp04dExERYW688UazdevWcs+Vk5NjevXqZerXr2/q1q1revToYbKysip8b9atW2dGjBhhGjVqZCIjIx2/X7BggWnZsqWx2+2mc+fO5rPPPiv3uSv9TJ35tzFkyBBTt25d89NPP5mbbrrJ1K1b10RFRZmHHnqoXM/RM888Y1JSUkzDhg2N3W43HTt2NG+88YZTnYo+W2dej59++skMGzbMNG7c2ISFhZn4+Hjz8ssvl3tPXnzxRRMfH+/4f0ZiYqL561//Wun1QOAiCMEvXXfddaZ+/frm66+/Pmfdxx9/3EgyV155pXnmmWfMCy+8YAYOHGjGjRvnqNO3b19z2223mWeeecbMmzfP3HrrrUaSefjhhx11Vq9ebRISEkxUVJRZunSpWbp0qXnnnXdMXl6emTJlipFkhg8f7vjdjh07jDGnv4zCwsJMSkqKee6558zzzz9v2rdvb8LCwsy///1vx/OXBqH4+Hhz0003mblz55o5c+ZUel6lX0zt2rUzXbt2NS+++KIZOXKkCQ4ONldffbUpKSlx1C37hXTs2DFz2WWXmdDQUDN27Fjz4osvmq5duxpJji/TX3/91cybN89IMjfffLPjvL788stK25SXl2eio6NN/fr1zcSJE82MGTNMhw4dTHBwsHn77beNMaeD0tKlS40k07NnT8fznktJSYm56qqrTFRUlBkwYIAJCQkxOTk55zzOGGPeeOMN06FDBzNp0iSzcOFC88gjj5gGDRqYZs2amaNHj5Z7T6+44grTo0cPM2vWLPPQQw+ZkJAQc9tttzk956OPPmokmRtuuMHMnj3b3HXXXaZJkyYmKirKpSB08uRJ06FDB9OqVSvz/fffm3r16pnbb7/dpfNZvXq1CQsLM82aNTMZGRlm3rx55oEHHjCpqamOOmvWrDG1atUyl1xyiXn66afN5MmTTVRUlGnQoIFTANyyZYupW7euiY2NNVOnTjXTp083LVq0MDabzfzrX/8q997Ex8ebbt26mVmzZpnp06cbY4x56aWXHH9jL774ohkzZoyJjIw0LVu2dCkI2e12c/nll5u77rrLzJs3z/zhD38wkszcuXOdzvvCCy80999/v5k9e7aZMWOGSUpKMpKcgvbSpUuNzWYzXbt2dXy2vvjiC2PM6c/nhRdeaOLi4syUKVPMvHnzzI033mgkmeeff97xHKWhu1+/fmbBggXmhRdeMHfffbd54IEHXLo+CCwEIfil1atXm5CQEBMSEmJSUlLMn//8Z7Nq1SpTVFTkVO/77783wcHB5uabby7Xc3BmUDh27Fi517j33ntNnTp1zPHjxx1l7s4RKikpMa1btzZpaWnlXq9FixamZ8+ejrLSIDRgwACX3oPSL6bExESn8y7taXjvvfccZWWD0MyZM40k89prrznKioqKTEpKiqlXr54pLCw0xrg/R2jMmDFGkvnnP//pKDty5Ihp0aKFad68udM1kGRGjhzp0vOW2rJliwkNDTWSzJgxY1w+rqLrm5WVZSSZ//u//3OUlb6nqampTtdr7NixJiQkxBw+fNgYY8y+fftMWFiY6d27t1O9Rx55pFwPxNmUzglq2LBhhXOGKnLq1CnTokUL06xZM/PLL784/e7MtiQkJJjGjRubgwcPOsq+/PJLExwcbAYPHuwo69u3rwkLC3MEd2OM+e9//2vq169vrr76akdZ6XvTpUsXp56aoqIi07hxY5OQkGBOnDjhKC8NE64EIUlmypQpTudyxRVXmMTERKeystexqKjItG3b1vTo0cOpvLI5QnfffbeJjY01Bw4ccCq//fbbTUREhOP5b7rpJnP55ZeXOx7WxF1j8Es9e/ZUVlaWbrzxRn355Zd6+umnlZaWpqZNm+r999931Hv33XdVUlKiSZMmKTjY+eMcFBTk+O/atWs7/vvIkSM6cOCAunbtqmPHjmnbtm1VbufmzZv1/fffa+DAgTp48KAOHDigAwcO6OjRo7r22mv12WefqaSkxOmY++67z63XGD58uEJDQx2PR4wYoVq1amnFihWVHrNixQrFxMRowIABjrLQ0FA98MAD+vXXX/WPf/zDrTac+bxJSUnq0qWLo6xevXoaPny4du3apa1bt1bpeUuFh4crLCxMknTddde5fNyZ1/fkyZM6ePCgLr74YkVGRionJ6dc/eHDhzt9Prp27ari4mL9+OOPkqS1a9eqqKhIo0ePdqo3ZswYt84nKSlJ9913nw4dOqRp06YpOjr6nMds2rRJubm5GjNmTLk5VqVt2bt3rzZv3qyhQ4eqYcOGjt+3b99ePXv2dHw2iouLtXr1avXt21ctW7Z01IuNjdXAgQO1fv16FRYWOr3GPffco5CQEMfj//znP9q3b5/uu+8+x7WRpKFDhyoiIsLl96Ls575r167auXOnU9mZ1/GXX35RQUGBunbtWuE1LMsYo7feekt9+vSRMcbxt3jgwAGlpaWpoKDA8TyRkZH66aeftGHDBpfbj8BFEILf6ty5s95++2398ssvys7O1oQJE3TkyBH169fP8YW7Y8cOBQcHKz4+/qzP9c033+jmm29WRESEwsPD1ahRI915552SpIKCgiq38fvvv5ckDRkyRI0aNXL6eemll3TixIlyz9+iRQu3XqN169ZOj+vVq6fY2Fjt2rWr0mN+/PFHtW7dulw4vOyyyxy/r4off/xRl156abny833eUqNGjVJwcLCaNWumhx56SCdPnnTpuN9++02TJk1SXFycbDaboqKi1KhRIx0+fLjC63vRRRc5PW7QoIGk01++Z55H2fe+UaNGjrqu6ty5sySpU6dOLtXfsWOHJKlt27aV1iltX2XXojSM79+/X8eOHau0XklJifbs2eNUXvbzWdl7ERoa6hSuzsZut6tRo0ZOZQ0aNHC836U+/PBD/e53v5PdblfDhg3VqFEjzZs3z6W/0f379+vw4cNauHBhub/FYcOGSfrfjRbjxo1TvXr1lJSUpNatW2vkyJH6/PPPXToXBB7uGoPfCwsLU+fOndW5c2ddcsklGjZsmN544w1lZGS4dPzhw4fVrVs3hYeHa8qUKWrVqpXsdrtycnI0bty4cj027ig99plnnlFCQkKFderVq+f0+Mx/9eJ/3n77bb3//vuaOXOmWrdurd69e+uZZ57RI488cs5jR48ercWLF2vMmDFKSUlRRESEgoKCdPvtt1d4fc/s8TiTMea8z6Om88bns7L3+0z//Oc/deONN+rqq6/W3LlzFRsbq9DQUC1evNhx593ZlF7nO++8U0OGDKmwTvv27SWdDoHbt2/Xhx9+qJUrV+qtt97S3LlzNWnSpArXs0JgIwihRin9V/XevXslSa1atVJJSYm2bt1aaRBZt26dDh48qLfffltXX321ozw3N7dc3TOHQVwpb9WqlaTTQzqpqakun4c7vv/+e3Xv3t3x+Ndff9XevXt1ww03VHpMs2bN9NVXX6mkpMSpV6h0GLBZs2aSKj+vsz3v9u3by5WXfV53HTlyRA888IA6duyoUaNGKSQkRH/4wx/0xBNPaMCAAefsRXvzzTc1ZMgQPffcc46y48eP6/Dhw1VqT+l5fP/99069Hvv37y/Xi+FppZ+pLVu2VPqZKm1fZdciKipKdevWld1uV506dSqtFxwcrLi4uLO258z3okePHo7ykydPKjc3Vx06dHDtxM7hrbfekt1u16pVq2Sz2RzlixcvLle3os9to0aNVL9+fRUXF7v0t1i3bl31799f/fv3V1FRkW655RY9+eSTmjBhAksAWAxDY/BLn376aYX/Oi+d+1Da1d+3b18FBwdrypQp5f7lX3p86b9Gz3y+oqIizZ07t9zz161bt8Ju+NK1VMp+sSYmJqpVq1Z69tln9euvv5Y7bv/+/ZWeo6sWLlzoNEQ0b948nTp1Stdff32lx9xwww3Ky8vT8uXLHWWnTp3SrFmzVK9ePXXr1k2SVKdOHUnlz+tsz5udna2srCxH2dGjR7Vw4UI1b978nEOUlXn00Ue1d+9eLViwwHG9XnjhBYWEhGjUqFHnPD4kJKTc52XWrFkqLi6uUntSU1MVGhqqWbNmOT1vdWwT0rFjR7Vo0UIzZ84sd11K2xIbG6uEhAS9+uqrTnW2bNmi1atXO0JySEiIrrvuOr333ntOQ6n5+fl6/fXX1aVLF4WHh5+1PZ06dVKjRo00f/58FRUVOcqXLFlS5aBZkZCQEAUFBTlds127dlW4gnTdunXLvXZpeH7rrbe0ZcuWcsec+bd48OBBp9+FhYUpPj5exhiXh2MROOgRgl8aPXq0jh07pptvvllt2rRRUVGRvvjiCy1fvlzNmzd3jPlffPHFmjhxoqZOnaquXbvqlltukc1m04YNG9SkSRNNmzZNV155pRo0aKAhQ4bogQceUFBQkJYuXVph0EpMTNTy5cuVnp6uzp07q169eurTp49atWqlyMhIzZ8/X/Xr11fdunWVnJysFi1a6KWXXtL111+vyy+/XMOGDVPTpk31888/69NPP1V4eLg++OCD83ovioqKdO211+q2227T9u3bNXfuXHXp0kU33nhjpccMHz5cCxYs0NChQ7Vx40Y1b95cb775pj7//HPNnDlT9evXl3R6GCQ+Pl7Lly/XJZdcooYNG6pt27aVzk8ZP368/va3v+n666/XAw88oIYNG+rVV19Vbm6u3nrrrXJzklyxceNGzZkzRyNHjnSaR9O0aVNNmTJF6enpeuutt/SHP/yh0uf4/e9/r6VLlyoiIkLx8fHKysrS2rVrdcEFF7jdHul078LDDz+sadOm6fe//71uuOEGbdq0SR9//LGioqKq9JyuCg4O1rx589SnTx8lJCRo2LBhio2N1bZt2/TNN99o1apVkk4Px15//fVKSUnR3Xffrd9++02zZs1SRESE04KNTzzxhNasWaMuXbro/vvvV61atbRgwQKdOHFCTz/99DnbExoaqieeeEL33nuvevToof79+ys3N1eLFy92eY6QK3r37q0ZM2aoV69eGjhwoPbt26c5c+bo4osv1ldffeVUNzExUWvXrtWMGTPUpEkTtWjRQsnJyZo+fbo+/fRTJScn65577lF8fLwOHTqknJwcrV27VocOHZJ0eiJ+TEyMrrrqKkVHR+vbb7/V7Nmz1bt3b8ffBizER3erAWf18ccfm7vuusu0adPG1KtXz7HdxujRo01+fn65+q+88oq54oorjM1mMw0aNDDdunUza9ascfz+888/N7/73e9M7dq1TZMmTRy340syn376qaPer7/+agYOHGgiIyMdCyqWeu+990x8fLypVatWuVuEN23aZG655RZzwQUXGJvNZpo1a2Zuu+02k5mZ6ahTevv8/v37XXoPyi6o2KBBA1OvXj1zxx13ON0ybUzlCyoOGzbMREVFmbCwMNOuXbsKtwj54osvTGJiogkLC3NrQcXIyEhjt9tNUlKS0zovpeTC7fOnTp0yHTt2NE2aNDEFBQUV/j4hIcFceOGF5siRI5U+zy+//OI413r16pm0tDSz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6m3lgbwadVmubtxaih41AO4iCAFV4M4t8Gfba8zdvcistnaOu/N8YgL4vQDgHQQhoAp8cQt8ZXNlSofiAnFIzdV5PqO6t9JVFzeq9t4xK/XOAYGKIARUQXXfAu+t1aj9/Yvc1Tvsxva8tNqHFK3WOwcEKoIQUAXVfQu8p4bizlQTvsg9dYedp8/Vir1zQKDirjGgCkq/oKX/fSGX8saEXU8PxdWkLSrO9w47T58rK1sDgYUeIaCKSr+gy/Y0eGPCrieH4mripq/nc4edp8/VG71zqHn8fVgZriMIAefBWzurl+XJobia+kXu7h12knfOlb3iUBOGleE6hsaA8+TpndUrew1PDcVZ6YvcG+fKXnHWVpOGleEaghBQQ3hqNWorfZF741xLe+cqi5ysbB24mB8WmBgaA2oQTwzFWWnTV2+cK3vFWVdNHVbG2dEjBNQw5zsUV913vPmSt86VveKsyUrDylZCjxBgQdV5x5uveetcq2uiPPyHlYaVrSTIGGOpwczCwkJFRESooKBA4eHhvm4O4FNWugXYSucK7yguMeryl0/OOdS6flwPPlte4K3vb3qEAAuryi3pNZWVzhXewfywwMQcIQAAXMT8sMBDjxAAAG5gflhgIQgBAOAmhloDB0NjAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsghCAADAsnwehObMmaPmzZvLbrcrOTlZ2dnZZ61/+PBhjRw5UrGxsbLZbLrkkku0YsWKamotAAAIJLV8+eLLly9Xenq65s+fr+TkZM2cOVNpaWnavn27GjduXK5+UVGRevbsqcaNG+vNN99U06ZN9eOPPyoyMrL6Gw8AAGq8IGOM8dWLJycnq3Pnzpo9e7YkqaSkRHFxcRo9erTGjx9frv78+fP1zDPPaNu2bQoNDa3SaxYWFioiIkIFBQUKDw8/r/YDAIDq4a3vb58NjRUVFWnjxo1KTU39X2OCg5WamqqsrKwKj3n//feVkpKikSNHKjo6Wm3bttVTTz2l4uLiSl/nxIkTKiwsdPoBAACQfBiEDhw4oOLiYkVHRzuVR0dHKy8vr8Jj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tcrExsaasWPHVnPLA8+KFSvMxIkTzdtvv20kmXfeeees9Xfu3Gnq1Klj0tPTzdatW82sWbNMSEiIWblypVuvG3BBKCkpyYwcOdLxuLi42DRp0sRMmzatwvq33Xab6d27t1NZcnKyuffee73aTitw91qUderUKVO/fn3z6quvequJllKV63Hq1Clz5ZVXmpdeeskMGTKEIOQh7l6LefPmmZYtW5qioqLqaqJluHstRo4caXr06OFUlp6ebq666iqvttNqXAlCf/7zn83ll1/uVNa/f3+Tlpbm1msF1NBYUVGRNm7cqNTUVEdZcHCwUlNTlZWVVeExWVlZTvUlKS0trdL6cE1VrkVZx44d08mTJz2+wZ4VVfV6TJkyRY0bN9bdd99dHc20hKpci/fff18pKSkaOXKkoqOj1bZtWz311FMqLi6urmYHpKpciyuvvFIbN250DJ/t3LlTK1as0A033FAtbcb/eOr72y9WlvaUAwcOqLi42LE9R6no6Ght27atwmPy8vIqrJ+Xl+e1dlpBVa5FWePGjVOTJk3KfdDhvqpcj/Xr1+vll1/W5s2bq6GF1lGVa7Fz50598sknuuOOO7RixQr98MMPuv/++3Xy5EllZGRUR7MDUlWuxcCBA3XgwAF16dJFxhidOnVK9913nx555JHqaDLOUNn3d2FhoX777TfVrl3bpecJqB4hBI7p06dr2bJleuedd2S3233dHMs5cuSIBg0apEWLFikqKsrXzbG8kpISNW7cWAsXLlRiYqL69++viRMnav78+b5umuWsW7dOTz31lObOnaucnBy9/fbb+uijjzR16lRfNw1VFFA9QlFRUQoJCVF+fr5TeX5+vmJiYio8JiYmxq36cE1VrkWpZ599VtOnT9fatWvVvn17bzbTMty9Hjt27NCuXbvUp08fR1lJSYkkqVatWtq+fbtatWrl3UYHqKr8bcTGxio0NFQhISGOsssuu0x5eXkqKipSWFiYV9scqKpyLR577DENGjRIf/zjHyVJ7dq109GjRzV8+HBNnDjRaZNweFdl39/h4eEu9wZJAdYjFBYWpsTERGVmZjrKSkpKlJmZqZSUlAqPSUlJcaovSWvWrKm0PlxTlWshSU8//bSmTp2qlStXqlOnTtXRVEtw93q0adNGX3/9tTZv3uz4ufHGG9W9e3dt3rxZcXFx1dn8gFKVv42rrrpKP/zwgyOMStJ3332n2NhYQtB5qMq1OHbsWLmwUxpQDVt3ViuPfX+7N4/b/y1btszYbDazZMkSs3XrVjN8+HATGRlp8vLyjDHGDBo0yIwfP95R//PPPze1atUyzz77rPn2229NRkYGt897iLvXYvr06SYsLMy8+eabZu/evY6fI0eO+OoUAoq716Ms7hrzHHevxe7du039+vXNqFGjzPbt282HH35oGjdubJ544glfnULAcPdaZGRkmPr165u//e1vZufOnWb16tWmVatW5rbbbvPVKQSMI0eOmE2bNplNmzYZSWbGjBlm06ZN5scffzTGGDN+/HgzaNAgR/3S2+f/9Kc/mW+//dbMmTOH2+dLzZo1y1x00UUmLCzMJCUlmX/961+O33Xr1s0MGTLEqf7f//53c8kll5iwsDBz+eWXm48++qiaWxy43LkWzZo1M5LK/WRkZFR/wwOUu38bZyIIeZa71+KLL74wycnJxmazmZYtW5onn3zSnDp1qppbHZjcuRYnT540jz/+uGnVqpWx2+0mLi7O3H///eaXX36p/oYHmE8//bTC74DS93/IkCGmW7du5Y5JSEgwYWFhpmXLlmbx4sVuv26QMfTlAQAAawqoOUIAAADuIAgBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBAADLIggBqNGKi4t15ZVX6pZbbnEqLygoUFxcnCZOnOijlgGoCVhZGkCN99133ykhIUGLFi3SHXfcIUkaPHiwvvzyS23YsIGNSQFUiiAEICC8+OKLevzxx/XNN98oOztbt956qzZs2KAOHTr4umkA/BhBCEBAMMaoR48eCgkJ0ddff63Ro0fr0Ucf9XWzAPg5ghCAgLFt2zZddtllateunXJyclSrVi1fNwmAn2OyNICA8corr6hOnTrKzc3VTz/95OvmAKgB6BECEBC++OILdevWTatXr9YTTzwhSVq7dq2CgoJ83DIA/oweIQA13rFjxzR06FCNGDFC3bt318svv6zs7GzNnz/f100D4OfoEQJQ4z344INasWKFvvzyS9WpU0eStGDBAj388MP6+uuv1bx5c982EIDfIggBqNH+8Y9/6Nprr9W6devUpUsXp9+lpaXp1KlTDJEBqBRBCAAAWBZzhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGURhAAAgGX9P8sDe9jobEdbAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot('data/processed/spoter_train.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[18 19 20 21 22 23 24 25 26 27 28 29 30]\n", + " frame row_id type landmark_index x y z\n", + "3801 25 25-face-0 face 0 0.498506 0.494856 -0.018860\n", + "3802 25 25-face-1 face 1 0.506121 0.470006 -0.056474\n", + "3803 25 25-face-2 face 2 0.505620 0.475341 -0.025482\n", + "3804 25 25-face-3 face 3 0.497120 0.439673 -0.049148\n", + "3805 25 25-face-4 face 4 0.506552 0.461902 -0.062083\n" + ] + }, + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "customdata": [ + [ + "wrist_left" + ], + [ + "thumbCMC_left" + ], + [ + "thumbMP_left" + ], + [ + "thumbIP_left" + ], + [ + "thumbTip_left" + ], + [ + "indexMCP_left" + ], + [ + "indexPIP_left" + ], + [ + "indexDIP_left" + ], + [ + "indexTip_left" + ], + [ + "middleMCP_left" + ], + [ + "middlePIP_left" + ], + [ + "middleDIP_left" + ], + [ + "middleTip_left" + ], + [ + "ringMCP_left" + ], + [ + "ringPIP_left" + ], + [ + "ringDIP_left" + ], + [ + "ringTip_left" + ], + [ + "littleMCP_left" + ], + [ + "littlePIP_left" + ], + [ + "littleDIP_left" + ], + [ + "littleTip_left" + ] + ], + "hovertemplate": "type=left_hand
x=%{x}
y=%{y}
name=%{customdata[0]}", + "legendgroup": "left_hand", + "marker": { + "color": "#636efa", + "symbol": "circle" + }, + "mode": "markers", + "name": "left_hand", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + "xaxis": "x", + "y": [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + "yaxis": "y" + }, + { + "customdata": [ + [ + "nose" + ], + [ + "leftEye" + ], + [ + "rightEye" + ], + [ + "leftEar" + ], + [ + "rightEar" + ], + [ + "leftShoulder" + ], + [ + "rightShoulder" + ], + [ + "leftElbow" + ], + [ + "rightElbow" + ], + [ + "leftWrist" + ], + [ + "rightWrist" + ] + ], + "hovertemplate": "type=pose
x=%{x}
y=%{y}
name=%{customdata[0]}", + "legendgroup": "pose", + "marker": { + "color": "#EF553B", + "symbol": "circle" + }, + "mode": "markers", + "name": "pose", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + 0.5037816762924194, + 0.544114351272583, + 0.47258099913597107, + 0.6112894415855408, + 0.42202046513557434, + 0.790356457233429, + 0.30560430884361267, + 0.8586887121200562, + 0.052559275180101395, + 0.8901190161705017, + 0.14568309485912323 + ], + "xaxis": "x", + "y": [ + 0.5385957062244415, + 0.5870676934719086, + 0.5835375487804413, + 0.5667203366756439, + 0.5620827376842499, + 0.3601607084274292, + 0.3561617136001587, + 0.10383915901184082, + 0.12815016508102417, + -0.1593785285949707, + 0.4648846983909607 + ], + "yaxis": "y" + }, + { + "customdata": [ + [ + "wrist_right" + ], + [ + "thumbCMC_right" + ], + [ + "thumbMP_right" + ], + [ + "thumbIP_right" + ], + [ + "thumbTip_right" + ], + [ + "indexMCP_right" + ], + [ + "indexPIP_right" + ], + [ + "indexDIP_right" + ], + [ + "indexTip_right" + ], + [ + "middleMCP_right" + ], + [ + "middlePIP_right" + ], + [ + "middleDIP_right" + ], + [ + "middleTip_right" + ], + [ + "ringMCP_right" + ], + [ + "ringPIP_right" + ], + [ + "ringDIP_right" + ], + [ + "ringTip_right" + ], + [ + "littleMCP_right" + ], + [ + "littlePIP_right" + ], + [ + "littleDIP_right" + ], + [ + "littleTip_right" + ] + ], + "hovertemplate": "type=right_hand
x=%{x}
y=%{y}
name=%{customdata[0]}", + "legendgroup": "right_hand", + "marker": { + "color": "#00cc96", + "symbol": "circle" + }, + "mode": "markers", + "name": "right_hand", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": [ + 0.1788196861743927, + 0.23843127489089966, + 0.25467628240585327, + 0.27044928073883057, + 0.2871263027191162, + 0.19056828320026398, + 0.2649158835411072, + 0.3157113492488861, + 0.3494824171066284, + 0.18622460961341858, + 0.2733367681503296, + 0.32277774810791016, + 0.3569425642490387, + 0.19574135541915894, + 0.2806362509727478, + 0.3286181688308716, + 0.36066585779190063, + 0.21657982468605042, + 0.2816353738307953, + 0.31945061683654785, + 0.34714818000793457 + ], + "xaxis": "x", + "y": [ + 0.4631972312927246, + 0.49802637100219727, + 0.5355206429958344, + 0.5633883774280548, + 0.5824070870876312, + 0.5867454409599304, + 0.6103077828884125, + 0.6078206300735474, + 0.6010101139545441, + 0.5849654078483582, + 0.6130928993225098, + 0.6087997257709503, + 0.6008164584636688, + 0.5775772035121918, + 0.6042222082614899, + 0.6019154489040375, + 0.5936585664749146, + 0.564491868019104, + 0.5853257775306702, + 0.5884504020214081, + 0.5863424837589264 + ], + "yaxis": "y" + } + ], + "layout": { + "legend": { + "title": { + "text": "type" + }, + "tracegroupgap": 0 + }, + "margin": { + "t": 60 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "xaxis": { + "anchor": "y", + "constrain": "domain", + "domain": [ + 0, + 1 + ], + "range": [ + 0, + 1 + ], + "title": { + "text": "x" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "range": [ + 0, + 1 + ], + "scaleanchor": "x", + "scaleratio": 1, + "title": { + "text": "y" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# read parquet file at data/train_landmark_files/2044/635217.parquet\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "df = pd.read_parquet('data/train_landmark_files/37779/254554888.parquet')\n", + "\n", + "# print all unique frame numbers\n", + "print(df['frame'].unique())\n", + "\n", + "# filter where type is pose\n", + "df = df[df['frame'] == 25]\n", + "\n", + "print(df.head())\n", + "\n", + "mapping = {\n", + " 'pose_0': 'nose',\n", + " 'pose_1': 'leftEye',\n", + " 'pose_4': 'rightEye',\n", + " 'pose_7': 'leftEar',\n", + " 'pose_8': 'rightEar',\n", + " 'pose_11': 'leftShoulder',\n", + " 'pose_12': 'rightShoulder',\n", + " 'pose_13': 'leftElbow',\n", + " 'pose_14': 'rightElbow',\n", + " 'pose_15': 'leftWrist',\n", + " 'pose_16': 'rightWrist',\n", + "\n", + " 'left_hand_0': 'wrist_left',\n", + " 'left_hand_1': 'thumbCMC_left',\n", + " 'left_hand_2': 'thumbMP_left',\n", + " 'left_hand_3': 'thumbIP_left',\n", + " 'left_hand_4': 'thumbTip_left',\n", + " 'left_hand_5': 'indexMCP_left',\n", + " 'left_hand_6': 'indexPIP_left',\n", + " 'left_hand_7': 'indexDIP_left',\n", + " 'left_hand_8': 'indexTip_left',\n", + " 'left_hand_9': 'middleMCP_left',\n", + " 'left_hand_10': 'middlePIP_left',\n", + " 'left_hand_11': 'middleDIP_left',\n", + " 'left_hand_12': 'middleTip_left',\n", + " 'left_hand_13': 'ringMCP_left',\n", + " 'left_hand_14': 'ringPIP_left',\n", + " 'left_hand_15': 'ringDIP_left',\n", + " 'left_hand_16': 'ringTip_left',\n", + " 'left_hand_17': 'littleMCP_left',\n", + " 'left_hand_18': 'littlePIP_left',\n", + " 'left_hand_19': 'littleDIP_left',\n", + " 'left_hand_20': 'littleTip_left',\n", + "\n", + " 'right_hand_0': 'wrist_right',\n", + " 'right_hand_1': 'thumbCMC_right',\n", + " 'right_hand_2': 'thumbMP_right',\n", + " 'right_hand_3': 'thumbIP_right',\n", + " 'right_hand_4': 'thumbTip_right',\n", + " 'right_hand_5': 'indexMCP_right',\n", + " 'right_hand_6': 'indexPIP_right',\n", + " 'right_hand_7': 'indexDIP_right',\n", + " 'right_hand_8': 'indexTip_right',\n", + " 'right_hand_9': 'middleMCP_right',\n", + " 'right_hand_10': 'middlePIP_right',\n", + " 'right_hand_11': 'middleDIP_right',\n", + " 'right_hand_12': 'middleTip_right',\n", + " 'right_hand_13': 'ringMCP_right',\n", + " 'right_hand_14': 'ringPIP_right',\n", + " 'right_hand_15': 'ringDIP_right',\n", + " 'right_hand_16': 'ringTip_right',\n", + " 'right_hand_17': 'littleMCP_right',\n", + " 'right_hand_18': 'littlePIP_right',\n", + " 'right_hand_19': 'littleDIP_right',\n", + " 'right_hand_20': 'littleTip_right',\n", + " }\n", + "\n", + "# scatter plot and when hovering over the point, show the frame number\n", + "import plotly.express as px\n", + "\n", + "# combine type and landmark index\n", + "df['landmark_id'] = df['type'] + '_' + df['landmark_index'].astype(str)\n", + "# only keep rows where landmark_id is in the mapping\n", + "df = df[df['landmark_id'].isin(mapping.keys())]\n", + "df['name'] = df['landmark_id'].apply(lambda x: mapping[x])\n", + "\n", + "# flip vertically\n", + "df['y'] = 1 - df['y']\n", + "\n", + "# keep aspect ratio\n", + "\n", + "# scatter with px and set color of points based on the type\n", + "fig = px.scatter(df, x='x', y='y', color='type', hover_data=['name'])\n", + "\n", + "fig.update_xaxes(range=[0, 1], constrain='domain')\n", + "fig.update_yaxes(scaleanchor='x', scaleratio=1, range=[0, 1])\n", + "\n", + "# show the plot\n", + "fig.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from training dataset\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n" + ] + } + ], + "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.8.10" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/webcam.py b/webcam.py index d381c71..acf4855 100644 --- a/webcam.py +++ b/webcam.py @@ -1,338 +1,54 @@ - -from collections import Counter - import cv2 -import mediapipe as mp -import numpy as np -import pandas as pd -import torch -device = torch.device("cpu") -if torch.cuda.is_available(): - device = torch.device("cuda") -from models import SPOTER_EMBEDDINGS +from predictions.k_nearest import KNearestNeighbours +from predictions.predictor import Predictor +from predictions.svm_model import SVM -# Initialize MediaPipe Hands model -holistic = mp.solutions.holistic.Holistic( - min_detection_confidence=0.5, - min_tracking_confidence=0.5, - model_complexity=2 - ) -mp_holistic = mp.solutions.holistic -mp_drawing = mp.solutions.drawing_utils +if __name__ == '__main__': + buffer = [] + # open webcam stream + cap = cv2.VideoCapture(0) -BODY_IDENTIFIERS = [ - 0, - 33, - 5, - 2, - 8, - 7, - 12, - 11, - 14, - 13, - 16, - 15, -] - -HAND_IDENTIFIERS = [ - 0, - 8, - 7, - 6, - 5, - 12, - 11, - 10, - 9, - 16, - 15, - 14, - 13, - 20, - 19, - 18, - 17, - 4, - 3, - 2, - 1, -] - -def extract_keypoints(image_orig): - image = cv2.cvtColor(image_orig, cv2.COLOR_BGR2RGB) - results = holistic.process(image) - - def extract_keypoints(lmks): - if lmks: - a = np.array([[float(lmk.x), float(lmk.y)] for lmk in lmks.landmark]) - return a - return None - - def calculate_neck(keypoints): - left_shoulder = keypoints[11] - right_shoulder = keypoints[12] - - neck = [(float(left_shoulder[0]) + float(right_shoulder[0])) / 2, (float(left_shoulder[1]) + float(right_shoulder[1])) / 2] - # add neck to keypoints - keypoints = np.append(keypoints, [neck], axis=0) - return keypoints - - pose = extract_keypoints(results.pose_landmarks) - pose = calculate_neck(pose) - pose_norm = normalize_pose(pose) - # filter out keypoints that are not in BODY_IDENTIFIERS and make sure they are in the correct order - pose_norm = pose_norm[BODY_IDENTIFIERS] - - left_hand = extract_keypoints(results.left_hand_landmarks) - right_hand = extract_keypoints(results.right_hand_landmarks) - - if left_hand is None and right_hand is None: - return None - - # normalize hands - if left_hand is not None: - left_hand = normalize_hand(left_hand) + type_predictor = "svm" + if type_predictor == "knn": + k = 10 + predictor_type = KNearestNeighbours(k) + elif type_predictor == "svm": + predictor_type = SVM() else: - left_hand = np.zeros((21, 2)) - if right_hand is not None: - right_hand = normalize_hand(right_hand) - else: - right_hand = np.zeros((21, 2)) - - left_hand = left_hand[HAND_IDENTIFIERS] - - right_hand = right_hand[HAND_IDENTIFIERS] - - # combine pose and hands - pose_norm = np.append(pose_norm, left_hand, axis=0) - pose_norm = np.append(pose_norm, right_hand, axis=0) - - # move interval - pose_norm -= 0.5 - - return pose_norm + predictor_type = KNearestNeighbours(1) -buffer = [] -left_shoulder_index = 11 -right_shoulder_index = 12 -neck_index = 33 -nose_index = 0 -left_eye_index = 2 + # embeddings_path = 'embeddings/basic-signs/embeddings.csv' + embeddings_path = 'embeddings/fingerspelling/embeddings.csv' -# if we have the keypoints, normalize single body, keypoints is numpy array of (identifiers, 2) -def normalize_pose(keypoints): - left_shoulder = keypoints[left_shoulder_index] - right_shoulder = keypoints[right_shoulder_index] + predictor = Predictor(embeddings_path, predictor_type) - neck = keypoints[neck_index] - nose = keypoints[nose_index] + index = 0 - # Prevent from even starting the analysis if some necessary elements are not present - if (left_shoulder[0] == 0 or right_shoulder[0] == 0 - or (left_shoulder[0] == right_shoulder[0] and left_shoulder[1] == right_shoulder[1])) and ( - neck[0] == 0 or nose[0] == 0 or (neck[0] == nose[0] and neck[1] == nose[1])): - return keypoints - - if left_shoulder[0] != 0 and right_shoulder[0] != 0 and (left_shoulder[0] != right_shoulder[0] or left_shoulder[1] != right_shoulder[1]): - shoulder_distance = ((((left_shoulder[0] - right_shoulder[0]) ** 2) + ((left_shoulder[1] - right_shoulder[1]) ** 2)) ** 0.5) - head_metric = shoulder_distance - else: - neck_nose_distance = ((((neck[0] - nose[0]) ** 2) + ((neck[1] - nose[1]) ** 2)) ** 0.5) - head_metric = neck_nose_distance + while cap.isOpened(): + # Wait for key press to exit + if cv2.waitKey(5) & 0xFF == 27: + break - # Set the starting and ending point of the normalization bounding box - starting_point = [keypoints[neck_index][0] - 3 * head_metric, keypoints[left_eye_index][1] + head_metric] - ending_point = [keypoints[neck_index][0] + 3 * head_metric, starting_point[1] - 6 * head_metric] + ret, frame = cap.read() + pose = predictor.extract_keypoints(frame) - if starting_point[0] < 0: - starting_point[0] = 0 - if starting_point[1] < 0: - starting_point[1] = 0 - if ending_point[0] < 0: - ending_point[0] = 0 - if ending_point[1] < 0: - ending_point[1] = 0 + if pose is None: + cv2.imshow('MediaPipe Hands', frame) + continue - # Normalize the keypoints - for i in range(len(keypoints)): - keypoints[i][0] = (keypoints[i][0] - starting_point[0]) / (ending_point[0] - starting_point[0]) - keypoints[i][1] = (keypoints[i][1] - ending_point[1]) / (starting_point[1] - ending_point[1]) + buffer.append(pose) + if len(buffer) > 15: + buffer.pop(0) - return keypoints + if len(buffer) == 15: + label, score = predictor.make_prediction(buffer) -def normalize_hand(keypoints): - x_values = [keypoints[i][0] for i in range(len(keypoints)) if keypoints[i][0] != 0] - y_values = [keypoints[i][1] for i in range(len(keypoints)) if keypoints[i][1] != 0] + # draw label + cv2.putText(frame, str(label), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA) + cv2.putText(frame, str(score), (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA) - if not x_values or not y_values: - return keypoints - - width, height = max(x_values) - min(x_values), max(y_values) - min(y_values) - if width > height: - delta_x = 0.1 * width - delta_y = delta_x + ((width - height) / 2) - else: - delta_y = 0.1 * height - delta_x = delta_y + ((height - width) / 2) - - starting_point = (min(x_values) - delta_x, min(y_values) - delta_y) - ending_point = (max(x_values) + delta_x, max(y_values) + delta_y) - - if ending_point[0] - starting_point[0] == 0 or ending_point[1] - starting_point[1] == 0: - return keypoints - - # normalize keypoints - for i in range(len(keypoints)): - keypoints[i][0] = (keypoints[i][0] - starting_point[0]) / (ending_point[0] - starting_point[0]) - keypoints[i][1] = (keypoints[i][1] - starting_point[1]) / (ending_point[1] - starting_point[1]) - - return keypoints - - -# load training embedding csv -df = pd.read_csv('embeddings/basic-signs/embeddings.csv') - -def minkowski_distance_p(x, y, p=2): - x = np.asarray(x) - y = np.asarray(y) - - # Find smallest common datatype with float64 (return type of this - # function) - addresses #10262. - # Don't just cast to float64 for complex input case. - common_datatype = np.promote_types(np.promote_types(x.dtype, y.dtype), - 'float64') - - # Make sure x and y are NumPy arrays of correct datatype. - x = x.astype(common_datatype) - y = y.astype(common_datatype) - - if p == np.inf: - return np.amax(np.abs(y-x), axis=-1) - elif p == 1: - return np.sum(np.abs(y-x), axis=-1) - else: - return np.sum(np.abs(y-x)**p, axis=-1) - -def minkowski_distance(x, y, p=2): - x = np.asarray(x) - y = np.asarray(y) - if p == np.inf or p == 1: - return minkowski_distance_p(x, y, p) - else: - return minkowski_distance_p(x, y, p)**(1./p) - - -def distance_matrix(keypoints, embeddings, p=2, threshold=1000000): - - x = np.array(keypoints) - m, k = x.shape - y = np.asarray(embeddings) - n, kk = y.shape - - if k != kk: - raise ValueError(f"x contains {k}-dimensional vectors but y contains " - f"{kk}-dimensional vectors") - - if m*n*k <= threshold: - return minkowski_distance(x[:,np.newaxis,:],y[np.newaxis,:,:],p) - else: - result = np.empty((m,n),dtype=float) # FIXME: figure out the best dtype - if m < n: - for i in range(m): - result[i,:] = minkowski_distance(x[i],y,p) - else: - for j in range(n): - result[:,j] = minkowski_distance(x,y[j],p) - return result - - -CHECKPOINT_PATH = "checkpoints/checkpoint_embed_1105.pth" -checkpoint = torch.load(CHECKPOINT_PATH, map_location=device) - -model = SPOTER_EMBEDDINGS( - features=checkpoint["config_args"].vector_length, - hidden_dim=checkpoint["config_args"].hidden_dim, - norm_emb=checkpoint["config_args"].normalize_embeddings, -).to(device) - -model.load_state_dict(checkpoint["state_dict"]) -embeddings = df.drop(columns=['labels', 'label_name', 'embeddings']) - -# convert embedding from string to list of floats -embeddings["embeddings"] = embeddings["embeddings2"].apply(lambda x: [float(i) for i in x[1:-1].split(", ")]) -# drop embeddings2 -embeddings = embeddings.drop(columns=['embeddings2']) -# to list -embeddings = embeddings["embeddings"].tolist() - -def make_prediction(keypoints): - # run model on frame - model.eval() - with torch.no_grad(): - keypoints = torch.from_numpy(np.array([keypoints])).float().to(device) - new_embeddings = model(keypoints).cpu().numpy().tolist()[0] - - # calculate distance matrix - dist_matrix = distance_matrix(new_embeddings, embeddings, p=2, threshold=1000000) - - # get the 5 closest matches and select the class that is most common and use the average distance as the score - # get the 5 closest matches - indeces = np.argsort(dist_matrix)[0][:5] - # get the labels - labels = df["label_name"].iloc[indeces].tolist() - c = Counter(labels).most_common()[0][0] - - # filter indeces to only include the most common label - indeces = [i for i in indeces if df["label_name"].iloc[i] == c] - # get the average distance - score = np.mean(dist_matrix[0][indeces]) - - return c, score - -# open webcam stream -cap = cv2.VideoCapture(0) - -while cap.isOpened(): - # read frame - ret, frame = cap.read() - pose = extract_keypoints(frame) - - if pose is None: - cv2.imshow('MediaPipe Hands', frame) - continue - - buffer.append(pose) - if len(buffer) > 15: - buffer.pop(0) - - if len(buffer) == 15: - label, score = make_prediction(buffer) - - # draw label - cv2.putText(frame, label, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA) - cv2.putText(frame, str(score), (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA) - - # Show the frame - cv2.imshow('MediaPipe Hands', frame) - - # Wait for key press to exit - if cv2.waitKey(5) & 0xFF == 27: - break - -# open video A.mp4 -# cap = cv2.VideoCapture('E.mp4') -# while cap.isOpened(): -# # read frame -# ret, frame = cap.read() -# if frame is None: -# break -# pose = extract_keypoints(frame) - -# buffer.append(pose) - -# label, score = make_prediction(buffer) -# print(label, score) \ No newline at end of file + # Show the frame + cv2.imshow('MediaPipe Hands', frame) \ No newline at end of file