Fruits-262¶
The data for this project was taken from Kaggle
The following fruit types/labels/clades are included: abiu, acai, acerola, ackee, alligator apple, ambarella, apple, apricot, araza, avocado, bael, banana, barbadine, barberry, bayberry, beach plum, bearberry, bell pepper, betel nut, bignay, bilimbi, bitter gourd, black berry, black cherry, black currant, black mullberry, black sapote, blueberry, bolwarra, bottle gourd, brazil nut, bread fruit, buddha s hand, buffaloberry, burdekin plum, burmese grape, caimito, camu camu, canistel, cantaloupe, cape gooseberry, carambola, cardon, cashew, cedar bay cherry, cempedak, ceylon gooseberry, che, chenet, cherimoya, cherry, chico, chokeberry, clementine, cloudberry, cluster fig, cocoa bean, coconut, coffee, common buckthorn, corn kernel, cornelian cherry, crab apple, cranberry, crowberry, cupuacu, custard apple, damson, date, desert fig, desert lime, dewberry, dragonfruit, durian, eggplant, elderberry, elephant apple, emblic, entawak, etrog, feijoa, fibrous satinash, fig, finger lime, galia melon, gandaria, genipap, goji, gooseberry, goumi, grape, grapefruit, greengage, grenadilla, guanabana, guarana, guava, guavaberry, hackberry, hard kiwi, hawthorn, hog plum, honeyberry, honeysuckle, horned melon, illawarra plum, indian almond, indian strawberry, ita palm, jaboticaba, jackfruit, jalapeno, jamaica cherry, jambul, japanese raisin, jasmine, jatoba, jocote, jostaberry, jujube, juniper berry, kaffir lime, kahikatea, kakadu plum, keppel, kiwi, kumquat, kundong, kutjera, lablab, langsat, lapsi, lemon, lemon aspen, leucaena, lillipilli, lime, lingonberry, loganberry, longan, loquat, lucuma, lulo, lychee, mabolo, macadamia, malay apple, mamey apple, mandarine, mango, mangosteen, manila tamarind, marang, mayhaw, maypop, medlar, melinjo, melon pear, midyim, miracle fruit, mock strawberry, monkfruit, monstera deliciosa, morinda, mountain papaya, mountain soursop, mundu, muskmelon, myrtle, nance, nannyberry, naranjilla, native cherry, native gooseberry, nectarine, neem, nungu, nutmeg, oil palm, old world sycomore, olive, orange, oregon grape, otaheite apple, papaya, passion fruit, pawpaw, pea, peanut, pear, pequi, persimmon, pigeon plum, pigface, pili nut, pineapple, pineberry, pitomba, plumcot, podocarpus, pomegranate, pomelo, prikly pear, pulasan, pumpkin, pupunha, purple apple berry, quandong, quince, rambutan, rangpur, raspberry, red mulberry, redcurrant, riberry, ridged gourd, rimu, rose hip, rose myrtle, rose-leaf bramble, saguaro, salak, salal, salmonberry, sandpaper fig, santol, sapodilla, saskatoon, sea buckthorn, sea grape, snowberry, soncoya, strawberry, strawberry guava, sugar apple, surinam cherry, sycamore fig, tamarillo, tangelo, tanjong, taxus baccata, tayberry, texas persimmon, thimbleberry, tomato, toyon, ugli fruit, vanilla, velvet tamarind, watermelon, wax gourd, white aspen, white currant, white mulberry, white sapote, wineberry, wongi, yali pear, yellow plum, yuzu, zigzag vine, zucchini
Dataset Properties¶
Total number of images: 225,640.
Number of classes: 262 fruits.
Number of images per label: Average: 861, Median: 1007, StDev: 276. (Initial target was 1,000 per label)
Image Width: Average: 213, Median: 209, StDev: 19.
Image Height: Average: 262, Median: 255, StDev: 30.
Missing Images from the initial 1,000 target: Average: 580, Median: 567, StDev: 258.
Format: a directory name represents a label and in each directory all the image data under the said label (the images are numbered but there might be missing numbers. The "renumber.py" script, if run, will fix the number gap problem).
Different varieties of the same fruit are generally stored in the same directory (Example: green, yellow and red apple).
The fruit images present in the dataset can contain the fruit in all the stages of its life and also can contain slices of the fruit.
Images contain at least 50% fruit information (according to the manual filtering selection paradigm).
The background of the images can be anything (due to the nature of the data): monochromatic backgrounds, human hands, natural habitats of the fruit, leaves etc.
There are no duplicate images but there are some images (of the same label) with a high degree of similarity.
Images can contain small watermarks.
Some fruits which had between 50-100 usable images still remain in the dataset, but can be discarded for a better balance and lesser variety. This is also one big reason for the high variance in the missing images statistic provided above.
!wget https://raw.githubusercontent.com/Hrushi11/Dogs_VS_Cats/main/helper_functions.py
--2021-07-03 08:16:35-- https://raw.githubusercontent.com/Hrushi11/Dogs_VS_Cats/main/helper_functions.py Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ... Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 10139 (9.9K) [text/plain] Saving to: ‘helper_functions.py’ helper_functions.py 100%[===================>] 9.90K --.-KB/s in 0s 2021-07-03 08:16:35 (69.6 MB/s) - ‘helper_functions.py’ saved [10139/10139]
Importing dependancies¶
Packages and modules required for successful running of this notebook
# Importing depeandancies
import os
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.layers.experimental import preprocessing
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from helper_functions import create_tensorboard_callback, plot_loss_curves, unzip_data, compare_historys, walk_through_dir, make_confusion_matrix
Getting our data ready¶
# Unzipping our data
unzip_data("/content/fruits262.zip")
# Check for dir in provided data
walk_through_dir("/content/Fruit-262")
There are 262 directories and 0 images in '/content/Fruit-262'. There are 0 directories and 1038 images in '/content/Fruit-262/otaheite apple'. There are 0 directories and 1021 images in '/content/Fruit-262/cupuacu'. There are 0 directories and 1022 images in '/content/Fruit-262/indian strawberry'. There are 0 directories and 756 images in '/content/Fruit-262/tamarillo'. There are 0 directories and 1018 images in '/content/Fruit-262/oil palm'. There are 0 directories and 1012 images in '/content/Fruit-262/grapefruit'. There are 0 directories and 999 images in '/content/Fruit-262/bottle gourd'. There are 0 directories and 925 images in '/content/Fruit-262/miracle fruit'. There are 0 directories and 1000 images in '/content/Fruit-262/bell pepper'. There are 0 directories and 1021 images in '/content/Fruit-262/chico'. There are 0 directories and 1046 images in '/content/Fruit-262/kumquat'. There are 0 directories and 1007 images in '/content/Fruit-262/carambola'. There are 0 directories and 1003 images in '/content/Fruit-262/coffee'. There are 0 directories and 864 images in '/content/Fruit-262/peanut'. There are 0 directories and 522 images in '/content/Fruit-262/cedar bay cherry'. There are 0 directories and 749 images in '/content/Fruit-262/nungu'. There are 0 directories and 1014 images in '/content/Fruit-262/lablab'. There are 0 directories and 780 images in '/content/Fruit-262/white sapote'. There are 0 directories and 1018 images in '/content/Fruit-262/jambul'. There are 0 directories and 500 images in '/content/Fruit-262/thimbleberry'. There are 0 directories and 1003 images in '/content/Fruit-262/cherry'. There are 0 directories and 1035 images in '/content/Fruit-262/plumcot'. There are 0 directories and 666 images in '/content/Fruit-262/nutmeg'. There are 0 directories and 1010 images in '/content/Fruit-262/rangpur'. There are 0 directories and 1012 images in '/content/Fruit-262/jalapeno'. There are 0 directories and 1010 images in '/content/Fruit-262/bilimbi'. There are 0 directories and 305 images in '/content/Fruit-262/cardon'. There are 0 directories and 1021 images in '/content/Fruit-262/emblic'. There are 0 directories and 908 images in '/content/Fruit-262/desert fig'. There are 0 directories and 920 images in '/content/Fruit-262/velvet tamarind'. There are 0 directories and 177 images in '/content/Fruit-262/rose myrtle'. There are 0 directories and 616 images in '/content/Fruit-262/soncoya'. There are 0 directories and 1008 images in '/content/Fruit-262/bael'. There are 0 directories and 1004 images in '/content/Fruit-262/marang'. There are 0 directories and 1052 images in '/content/Fruit-262/salak'. There are 0 directories and 500 images in '/content/Fruit-262/lillipilli'. There are 0 directories and 1405 images in '/content/Fruit-262/pea'. There are 0 directories and 650 images in '/content/Fruit-262/salal'. There are 0 directories and 273 images in '/content/Fruit-262/native cherry'. There are 0 directories and 839 images in '/content/Fruit-262/jatoba'. There are 0 directories and 1009 images in '/content/Fruit-262/zucchini'. There are 0 directories and 1268 images in '/content/Fruit-262/mock strawberry'. There are 0 directories and 1010 images in '/content/Fruit-262/yuzu'. There are 0 directories and 256 images in '/content/Fruit-262/nectarine'. There are 0 directories and 1004 images in '/content/Fruit-262/cloudberry'. There are 0 directories and 529 images in '/content/Fruit-262/fibrous satinash'. There are 0 directories and 610 images in '/content/Fruit-262/sea grape'. There are 0 directories and 302 images in '/content/Fruit-262/midyim'. There are 0 directories and 1033 images in '/content/Fruit-262/grape'. There are 0 directories and 1007 images in '/content/Fruit-262/lulo'. There are 0 directories and 1014 images in '/content/Fruit-262/langsat'. There are 0 directories and 538 images in '/content/Fruit-262/burdekin plum'. There are 0 directories and 1117 images in '/content/Fruit-262/rambutan'. There are 0 directories and 881 images in '/content/Fruit-262/monstera deliciosa'. There are 0 directories and 346 images in '/content/Fruit-262/sandpaper fig'. There are 0 directories and 1017 images in '/content/Fruit-262/malay apple'. There are 0 directories and 1011 images in '/content/Fruit-262/guanabana'. There are 0 directories and 1002 images in '/content/Fruit-262/mayhaw'. There are 0 directories and 206 images in '/content/Fruit-262/pigeon plum'. There are 0 directories and 1000 images in '/content/Fruit-262/tomato'. There are 0 directories and 1032 images in '/content/Fruit-262/mountain soursop'. There are 0 directories and 1003 images in '/content/Fruit-262/bearberry'. There are 0 directories and 1062 images in '/content/Fruit-262/brazil nut'. There are 0 directories and 1031 images in '/content/Fruit-262/jackfruit'. There are 0 directories and 1105 images in '/content/Fruit-262/sugar apple'. There are 0 directories and 1007 images in '/content/Fruit-262/gandaria'. There are 0 directories and 158 images in '/content/Fruit-262/white aspen'. There are 0 directories and 451 images in '/content/Fruit-262/saguaro'. There are 0 directories and 638 images in '/content/Fruit-262/galia melon'. There are 0 directories and 1036 images in '/content/Fruit-262/hog plum'. There are 0 directories and 774 images in '/content/Fruit-262/beach plum'. There are 0 directories and 1097 images in '/content/Fruit-262/ambarella'. There are 0 directories and 335 images in '/content/Fruit-262/myrtle'. There are 0 directories and 1006 images in '/content/Fruit-262/lucuma'. There are 0 directories and 996 images in '/content/Fruit-262/watermelon'. There are 0 directories and 1043 images in '/content/Fruit-262/gooseberry'. There are 0 directories and 1243 images in '/content/Fruit-262/acerola'. There are 0 directories and 1035 images in '/content/Fruit-262/dragonfruit'. There are 0 directories and 1009 images in '/content/Fruit-262/manila tamarind'. There are 0 directories and 1023 images in '/content/Fruit-262/rose-leaf bramble'. There are 0 directories and 946 images in '/content/Fruit-262/common buckthorn'. There are 0 directories and 1016 images in '/content/Fruit-262/redcurrant'. There are 0 directories and 1031 images in '/content/Fruit-262/yellow plum'. There are 0 directories and 1013 images in '/content/Fruit-262/sapodilla'. There are 0 directories and 324 images in '/content/Fruit-262/white mulberry'. There are 0 directories and 470 images in '/content/Fruit-262/neem'. There are 0 directories and 98 images in '/content/Fruit-262/rimu'. There are 0 directories and 603 images in '/content/Fruit-262/honeysuckle'. There are 0 directories and 1010 images in '/content/Fruit-262/kiwi'. There are 0 directories and 419 images in '/content/Fruit-262/nannyberry'. There are 0 directories and 636 images in '/content/Fruit-262/elephant apple'. There are 0 directories and 1024 images in '/content/Fruit-262/hard kiwi'. There are 0 directories and 488 images in '/content/Fruit-262/guavaberry'. There are 0 directories and 1013 images in '/content/Fruit-262/pomegranate'. There are 0 directories and 1007 images in '/content/Fruit-262/crab apple'. There are 0 directories and 1007 images in '/content/Fruit-262/cocoa bean'. There are 0 directories and 745 images in '/content/Fruit-262/tangelo'. There are 0 directories and 1089 images in '/content/Fruit-262/morinda'. There are 0 directories and 848 images in '/content/Fruit-262/muskmelon'. There are 0 directories and 865 images in '/content/Fruit-262/nance'. There are 0 directories and 343 images in '/content/Fruit-262/sycamore fig'. There are 0 directories and 1169 images in '/content/Fruit-262/avocado'. There are 0 directories and 96 images in '/content/Fruit-262/pigface'. There are 0 directories and 1018 images in '/content/Fruit-262/longan'. There are 0 directories and 1010 images in '/content/Fruit-262/loganberry'. There are 0 directories and 1008 images in '/content/Fruit-262/wax gourd'. There are 0 directories and 1009 images in '/content/Fruit-262/ridged gourd'. There are 0 directories and 1275 images in '/content/Fruit-262/abiu'. There are 0 directories and 1018 images in '/content/Fruit-262/cranberry'. There are 0 directories and 1001 images in '/content/Fruit-262/etrog'. There are 0 directories and 533 images in '/content/Fruit-262/japanese raisin'. There are 0 directories and 821 images in '/content/Fruit-262/orange'. There are 0 directories and 1045 images in '/content/Fruit-262/white currant'. There are 0 directories and 1024 images in '/content/Fruit-262/cashew'. There are 0 directories and 463 images in '/content/Fruit-262/pequi'. There are 0 directories and 1019 images in '/content/Fruit-262/grenadilla'. There are 0 directories and 1028 images in '/content/Fruit-262/strawberry guava'. There are 0 directories and 927 images in '/content/Fruit-262/black cherry'. There are 0 directories and 403 images in '/content/Fruit-262/old world sycomore'. There are 0 directories and 1031 images in '/content/Fruit-262/barbadine'. There are 0 directories and 1024 images in '/content/Fruit-262/coconut'. There are 0 directories and 1002 images in '/content/Fruit-262/canistel'. There are 0 directories and 879 images in '/content/Fruit-262/melinjo'. There are 0 directories and 1007 images in '/content/Fruit-262/juniper berry'. There are 0 directories and 1007 images in '/content/Fruit-262/pear'. There are 0 directories and 511 images in '/content/Fruit-262/tayberry'. There are 0 directories and 1077 images in '/content/Fruit-262/bitter gourd'. There are 0 directories and 1021 images in '/content/Fruit-262/camu camu'. There are 0 directories and 1017 images in '/content/Fruit-262/hawthorn'. There are 0 directories and 1023 images in '/content/Fruit-262/horned melon'. There are 0 directories and 479 images in '/content/Fruit-262/che'. There are 0 directories and 1005 images in '/content/Fruit-262/black currant'. There are 0 directories and 1015 images in '/content/Fruit-262/taxus baccata'. There are 0 directories and 1000 images in '/content/Fruit-262/burmese grape'. There are 0 directories and 656 images in '/content/Fruit-262/goji'. There are 0 directories and 1026 images in '/content/Fruit-262/goumi'. There are 0 directories and 291 images in '/content/Fruit-262/mundu'. There are 0 directories and 1014 images in '/content/Fruit-262/kaffir lime'. There are 0 directories and 1008 images in '/content/Fruit-262/mamey apple'. There are 0 directories and 1018 images in '/content/Fruit-262/corn kernel'. There are 0 directories and 1014 images in '/content/Fruit-262/medlar'. There are 0 directories and 1008 images in '/content/Fruit-262/lychee'. There are 0 directories and 1053 images in '/content/Fruit-262/quince'. There are 0 directories and 716 images in '/content/Fruit-262/bignay'. There are 0 directories and 294 images in '/content/Fruit-262/kundong'. There are 0 directories and 1038 images in '/content/Fruit-262/barberry'. There are 0 directories and 1008 images in '/content/Fruit-262/cantaloupe'. There are 0 directories and 1027 images in '/content/Fruit-262/papaya'. There are 0 directories and 1012 images in '/content/Fruit-262/greengage'. There are 0 directories and 51 images in '/content/Fruit-262/podocarpus'. There are 0 directories and 845 images in '/content/Fruit-262/kakadu plum'. There are 0 directories and 1001 images in '/content/Fruit-262/wongi'. There are 0 directories and 689 images in '/content/Fruit-262/pili nut'. There are 0 directories and 1003 images in '/content/Fruit-262/crowberry'. There are 0 directories and 1009 images in '/content/Fruit-262/pulasan'. There are 0 directories and 1002 images in '/content/Fruit-262/blueberry'. There are 0 directories and 1012 images in '/content/Fruit-262/jocote'. There are 0 directories and 881 images in '/content/Fruit-262/native gooseberry'. There are 0 directories and 1005 images in '/content/Fruit-262/black sapote'. There are 0 directories and 1162 images in '/content/Fruit-262/banana'. There are 0 directories and 111 images in '/content/Fruit-262/tanjong'. There are 0 directories and 210 images in '/content/Fruit-262/kahikatea'. There are 0 directories and 1010 images in '/content/Fruit-262/snowberry'. There are 0 directories and 1002 images in '/content/Fruit-262/bread fruit'. There are 0 directories and 1007 images in '/content/Fruit-262/cape gooseberry'. There are 0 directories and 1011 images in '/content/Fruit-262/lemon'. There are 0 directories and 1277 images in '/content/Fruit-262/jujube'. There are 0 directories and 482 images in '/content/Fruit-262/genipap'. There are 0 directories and 1015 images in '/content/Fruit-262/mandarine'. There are 0 directories and 1011 images in '/content/Fruit-262/pomelo'. There are 0 directories and 1013 images in '/content/Fruit-262/elderberry'. There are 0 directories and 1016 images in '/content/Fruit-262/sea buckthorn'. There are 0 directories and 887 images in '/content/Fruit-262/keppel'. There are 0 directories and 200 images in '/content/Fruit-262/texas persimmon'. There are 0 directories and 1035 images in '/content/Fruit-262/rose hip'. There are 0 directories and 1013 images in '/content/Fruit-262/yali pear'. There are 0 directories and 1126 images in '/content/Fruit-262/apricot'. There are 0 directories and 686 images in '/content/Fruit-262/guarana'. There are 0 directories and 1007 images in '/content/Fruit-262/buffaloberry'. There are 0 directories and 1002 images in '/content/Fruit-262/date'. There are 0 directories and 1025 images in '/content/Fruit-262/black mullberry'. There are 0 directories and 1050 images in '/content/Fruit-262/prikly pear'. There are 0 directories and 765 images in '/content/Fruit-262/araza'. There are 0 directories and 928 images in '/content/Fruit-262/persimmon'. There are 0 directories and 1032 images in '/content/Fruit-262/olive'. There are 0 directories and 442 images in '/content/Fruit-262/purple apple berry'. There are 0 directories and 517 images in '/content/Fruit-262/pineberry'. There are 0 directories and 548 images in '/content/Fruit-262/leucaena'. There are 0 directories and 1026 images in '/content/Fruit-262/durian'. There are 0 directories and 1051 images in '/content/Fruit-262/feijoa'. There are 0 directories and 1025 images in '/content/Fruit-262/mango'. There are 0 directories and 1203 images in '/content/Fruit-262/apple'. There are 0 directories and 1051 images in '/content/Fruit-262/cempedak'. There are 0 directories and 1012 images in '/content/Fruit-262/eggplant'. There are 0 directories and 1012 images in '/content/Fruit-262/fig'. There are 0 directories and 1007 images in '/content/Fruit-262/toyon'. There are 0 directories and 1015 images in '/content/Fruit-262/dewberry'. There are 0 directories and 1022 images in '/content/Fruit-262/betel nut'. There are 0 directories and 465 images in '/content/Fruit-262/lapsi'. There are 0 directories and 498 images in '/content/Fruit-262/salmonberry'. There are 0 directories and 1027 images in '/content/Fruit-262/santol'. There are 0 directories and 705 images in '/content/Fruit-262/pitomba'. There are 0 directories and 1169 images in '/content/Fruit-262/ackee'. There are 0 directories and 1011 images in '/content/Fruit-262/mountain papaya'. There are 0 directories and 1011 images in '/content/Fruit-262/surinam cherry'. There are 0 directories and 523 images in '/content/Fruit-262/jostaberry'. There are 0 directories and 464 images in '/content/Fruit-262/maypop'. There are 0 directories and 475 images in '/content/Fruit-262/pumpkin'. There are 0 directories and 1031 images in '/content/Fruit-262/cherimoya'. There are 0 directories and 1074 images in '/content/Fruit-262/custard apple'. There are 0 directories and 722 images in '/content/Fruit-262/bolwarra'. There are 0 directories and 1024 images in '/content/Fruit-262/guava'. There are 0 directories and 1020 images in '/content/Fruit-262/jaboticaba'. There are 0 directories and 862 images in '/content/Fruit-262/indian almond'. There are 0 directories and 521 images in '/content/Fruit-262/desert lime'. There are 0 directories and 1030 images in '/content/Fruit-262/cluster fig'. There are 0 directories and 1003 images in '/content/Fruit-262/macadamia'. There are 0 directories and 1010 images in '/content/Fruit-262/loquat'. There are 0 directories and 242 images in '/content/Fruit-262/kutjera'. There are 0 directories and 1023 images in '/content/Fruit-262/mabolo'. There are 0 directories and 991 images in '/content/Fruit-262/monkfruit'. There are 0 directories and 1032 images in '/content/Fruit-262/ugli fruit'. There are 0 directories and 676 images in '/content/Fruit-262/saskatoon'. There are 0 directories and 948 images in '/content/Fruit-262/caimito'. There are 0 directories and 1010 images in '/content/Fruit-262/lime'. There are 0 directories and 1006 images in '/content/Fruit-262/clementine'. There are 0 directories and 879 images in '/content/Fruit-262/alligator apple'. There are 0 directories and 787 images in '/content/Fruit-262/hackberry'. There are 0 directories and 141 images in '/content/Fruit-262/zigzag vine'. There are 0 directories and 1005 images in '/content/Fruit-262/honeyberry'. There are 0 directories and 1129 images in '/content/Fruit-262/black berry'. There are 0 directories and 1006 images in '/content/Fruit-262/cornelian cherry'. There are 0 directories and 201 images in '/content/Fruit-262/illawarra plum'. There are 0 directories and 1021 images in '/content/Fruit-262/pawpaw'. There are 0 directories and 1028 images in '/content/Fruit-262/passion fruit'. There are 0 directories and 1026 images in '/content/Fruit-262/chokeberry'. There are 0 directories and 314 images in '/content/Fruit-262/entawak'. There are 0 directories and 793 images in '/content/Fruit-262/red mulberry'. There are 0 directories and 1027 images in '/content/Fruit-262/finger lime'. There are 0 directories and 246 images in '/content/Fruit-262/lemon aspen'. There are 0 directories and 1107 images in '/content/Fruit-262/acai'. There are 0 directories and 204 images in '/content/Fruit-262/jasmine'. There are 0 directories and 1000 images in '/content/Fruit-262/melon pear'. There are 0 directories and 1000 images in '/content/Fruit-262/buddha's hand'. There are 0 directories and 1012 images in '/content/Fruit-262/chenet'. There are 0 directories and 1020 images in '/content/Fruit-262/jamaica cherry'. There are 0 directories and 1020 images in '/content/Fruit-262/damson'. There are 0 directories and 904 images in '/content/Fruit-262/pupunha'. There are 0 directories and 893 images in '/content/Fruit-262/ceylon gooseberry'. There are 0 directories and 758 images in '/content/Fruit-262/oregon grape'. There are 0 directories and 585 images in '/content/Fruit-262/naranjilla'. There are 0 directories and 1010 images in '/content/Fruit-262/ita palm'. There are 0 directories and 1037 images in '/content/Fruit-262/pineapple'. There are 0 directories and 1008 images in '/content/Fruit-262/lingonberry'. There are 0 directories and 1012 images in '/content/Fruit-262/raspberry'. There are 0 directories and 1005 images in '/content/Fruit-262/vanilla'. There are 0 directories and 634 images in '/content/Fruit-262/quandong'. There are 0 directories and 998 images in '/content/Fruit-262/bayberry'. There are 0 directories and 1105 images in '/content/Fruit-262/mangosteen'. There are 0 directories and 511 images in '/content/Fruit-262/riberry'. There are 0 directories and 1002 images in '/content/Fruit-262/strawberry'. There are 0 directories and 1010 images in '/content/Fruit-262/wineberry'.
The data set with us is quite uneven and so it would be best if we balance our data limiting to only 200 images per class and dropping the other remaining.
Balancing the data¶
# balancing the data allowing only similar number of images
dir="/content/Fruit-262"
filepaths=[]
labels=[]
classlist=os.listdir(dir)
for label in classlist:
classpath=os.path.join(dir,label)
if os.path.isdir(classpath):
flist=os.listdir(classpath)
for f in flist:
fpath=os.path.join(classpath,f)
filepaths.append(fpath)
labels.append(label)
Fseries= pd.Series(filepaths, name='filepaths')
Lseries=pd.Series(labels, name='labels')
df=pd.concat([Fseries, Lseries], axis=1)
print(df.head())
print(df['labels'].value_counts())
filepaths labels 0 /content/Fruit-262/otaheite apple/674.jpg otaheite apple 1 /content/Fruit-262/otaheite apple/102.jpg otaheite apple 2 /content/Fruit-262/otaheite apple/878.jpg otaheite apple 3 /content/Fruit-262/otaheite apple/508.jpg otaheite apple 4 /content/Fruit-262/otaheite apple/232.jpg otaheite apple pea 1405 jujube 1277 abiu 1275 mock strawberry 1268 acerola 1243 ... zigzag vine 141 tanjong 111 rimu 98 pigface 96 podocarpus 51 Name: labels, Length: 262, dtype: int64
balance=df['labels'].value_counts()
blist=list(balance)
print(blist)
[1405, 1277, 1275, 1268, 1243, 1203, 1169, 1169, 1162, 1129, 1126, 1117, 1107, 1105, 1105, 1097, 1089, 1077, 1074, 1062, 1053, 1052, 1051, 1051, 1050, 1046, 1045, 1043, 1038, 1038, 1037, 1036, 1035, 1035, 1035, 1033, 1032, 1032, 1032, 1031, 1031, 1031, 1031, 1030, 1028, 1028, 1027, 1027, 1027, 1026, 1026, 1026, 1025, 1025, 1024, 1024, 1024, 1024, 1023, 1023, 1023, 1022, 1022, 1021, 1021, 1021, 1021, 1021, 1020, 1020, 1020, 1019, 1018, 1018, 1018, 1018, 1018, 1017, 1017, 1016, 1016, 1015, 1015, 1015, 1014, 1014, 1014, 1014, 1013, 1013, 1013, 1013, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1011, 1011, 1011, 1011, 1011, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1009, 1009, 1009, 1009, 1008, 1008, 1008, 1008, 1008, 1008, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 1006, 1006, 1006, 1005, 1005, 1005, 1005, 1004, 1004, 1003, 1003, 1003, 1003, 1003, 1002, 1002, 1002, 1002, 1002, 1002, 1001, 1001, 1000, 1000, 1000, 1000, 1000, 999, 998, 996, 991, 948, 946, 928, 927, 925, 920, 908, 904, 893, 887, 881, 881, 879, 879, 865, 864, 862, 848, 845, 839, 821, 793, 787, 780, 774, 765, 758, 756, 749, 745, 722, 716, 705, 689, 686, 676, 666, 656, 650, 638, 636, 634, 616, 610, 603, 585, 548, 538, 533, 529, 523, 522, 521, 517, 511, 511, 500, 500, 498, 488, 482, 479, 475, 470, 465, 464, 463, 451, 442, 419, 403, 346, 343, 335, 324, 314, 305, 302, 294, 291, 273, 256, 246, 242, 210, 206, 204, 201, 200, 177, 158, 141, 111, 98, 96, 51]
Converting the data into dataframe¶
# The data set given would be best to handle when converted into dataframe
print ('original number of classes: ', len(df['labels'].unique()))
size=200 # set number of samples for each class
samples=[]
group=df.groupby(labels)
for label in df['labels'].unique():
Lgroup=group.get_group(label)
count=int(Lgroup['labels'].value_counts())
if count>=size:
sample=Lgroup.sample(size, axis=0)
samples.append(sample)
df=pd.concat(samples, axis=0).reset_index(drop=True)
print (len(df))
print ('final number of classes: ', len(df['labels'].unique()))
print (df['labels'].value_counts())
original number of classes: 262 51000 final number of classes: 255 morinda 200 japanese raisin 200 soncoya 200 grapefruit 200 dragonfruit 200 ... salmonberry 200 velvet tamarind 200 lucuma 200 langsat 200 monkfruit 200 Name: labels, Length: 255, dtype: int64
Splitting the dataset¶
# Getting dataframes ready for train, test and validation
train_split=.9
test_split=.05
dummy_split=test_split/(1-train_split)
train_df, dummy_df=train_test_split(df,
train_size=train_split,
shuffle=True,
random_state=123)
test_df, valid_df=train_test_split(dummy_df,
train_size=dummy_split,
shuffle=True,
random_state=123)
print ('train_df length: ', len(train_df), ' test_df length: ', len(test_df), ' valid_df length: ', len(valid_df))
train_df length: 45900 test_df length: 2550 valid_df length: 2550
# Image generators
train_datagen = ImageDataGenerator()
val_datagen = ImageDataGenerator()
test_datagen = ImageDataGenerator()
valid_df.head()
filepaths | labels | |
---|---|---|
39832 | /content/Fruit-262/jostaberry/178.jpg | jostaberry |
19604 | /content/Fruit-262/avocado/126.jpg | avocado |
3378 | /content/Fruit-262/lablab/787.jpg | lablab |
39961 | /content/Fruit-262/jostaberry/342.jpg | jostaberry |
15008 | /content/Fruit-262/dragonfruit/423.jpg | dragonfruit |
# Converting data ready into batches so that it is easier to train our model
train_data = train_datagen.flow_from_dataframe(train_df,
x_col='filepaths',
y_col='labels',
target_size = (224, 224),
batch_size = 32,
seed=42,
class_mode = 'categorical')
test_data = test_datagen.flow_from_dataframe(test_df,
x_col='filepaths',
y_col='labels',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical',
shuffle=False)
val_data = test_datagen.flow_from_dataframe(valid_df,
x_col='filepaths',
y_col='labels',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical',
shuffle=False)
Found 45900 validated image filenames belonging to 255 classes. Found 2550 validated image filenames belonging to 255 classes. Found 2550 validated image filenames belonging to 255 classes.
Viewing random image from the dataset¶
# Viewing random image
files = pd.unique(train_df["filepaths"])
pic = random.choice(files)
img = plt.imread(pic)
pic = pic[19:]
plt.title(pic.split("/")[0])
plt.imshow(img)
plt.axis(False);
# Setting up augmentation layer
data_augmentation = tf.keras.models.Sequential([
preprocessing.RandomFlip("horizontal"),
preprocessing.RandomRotation(0.2),
preprocessing.RandomHeight(0.2),
preprocessing.RandomWidth(0.2),
preprocessing.RandomZoom(0.2),
], name="data_augmentation_layer")
Model 1¶
# Setup base model and freeze its layers (this will extract features)
base_model = tf.keras.applications.EfficientNetB0(include_top=False)
base_model.trainable = False
# Setup model architecture with trainable top layers
inputs = tf.keras.layers.Input(shape=(224, 224, 3), name="input_layer")
x = data_augmentation(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling")(x)
outputs = tf.keras.layers.Dense(255, activation="softmax", name="output_layer")(x)
model_1 = tf.keras.Model(inputs, outputs)
Downloading data from https://storage.googleapis.com/keras-applications/efficientnetb0_notop.h5 16711680/16705208 [==============================] - 0s 0us/step
# Compile
model_1.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Fit
history_1 = model_1.fit(train_data,
epochs=5,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data))
Epoch 1/5 1435/1435 [==============================] - 313s 194ms/step - loss: 2.8141 - accuracy: 0.3973 - val_loss: 1.9294 - val_accuracy: 0.5467 Epoch 2/5 1435/1435 [==============================] - 185s 129ms/step - loss: 1.8217 - accuracy: 0.5660 - val_loss: 1.6885 - val_accuracy: 0.5871 Epoch 3/5 1435/1435 [==============================] - 161s 112ms/step - loss: 1.5568 - accuracy: 0.6201 - val_loss: 1.6207 - val_accuracy: 0.6000 Epoch 4/5 1435/1435 [==============================] - 147s 102ms/step - loss: 1.4010 - accuracy: 0.6528 - val_loss: 1.5672 - val_accuracy: 0.6071 Epoch 5/5 1435/1435 [==============================] - 138s 96ms/step - loss: 1.2796 - accuracy: 0.6793 - val_loss: 1.5284 - val_accuracy: 0.6231
# Create early stopping (once our model stops improving, stop training)
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
patience=3)
history_2 = model_1.fit(train_data,
epochs=20,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data),
callbacks=early_stopping)
Epoch 1/20 1435/1435 [==============================] - 127s 88ms/step - loss: 0.6715 - accuracy: 0.8204 - val_loss: 1.3935 - val_accuracy: 0.6639 Epoch 2/20 1435/1435 [==============================] - 126s 88ms/step - loss: 0.6464 - accuracy: 0.8245 - val_loss: 1.3788 - val_accuracy: 0.6616 Epoch 3/20 1435/1435 [==============================] - 127s 88ms/step - loss: 0.6168 - accuracy: 0.8330 - val_loss: 1.4015 - val_accuracy: 0.6659 Epoch 4/20 1435/1435 [==============================] - 126s 88ms/step - loss: 0.5861 - accuracy: 0.8388 - val_loss: 1.3863 - val_accuracy: 0.6729 Epoch 5/20 1435/1435 [==============================] - 126s 88ms/step - loss: 0.5645 - accuracy: 0.8462 - val_loss: 1.3837 - val_accuracy: 0.6682 Epoch 6/20 1435/1435 [==============================] - 127s 88ms/step - loss: 0.5389 - accuracy: 0.8516 - val_loss: 1.3967 - val_accuracy: 0.6627 Epoch 7/20 1435/1435 [==============================] - 126s 88ms/step - loss: 0.5147 - accuracy: 0.8585 - val_loss: 1.3922 - val_accuracy: 0.6706
model_1_results = model_1.evaluate(test_data)
model_1_results
80/80 [==============================] - 8s 98ms/step - loss: 1.5329 - accuracy: 0.6118
[1.5328636169433594, 0.6117647290229797]
model_1.evaluate(test_data)
80/80 [==============================] - 6s 80ms/step - loss: 1.4017 - accuracy: 0.6651
[1.4016666412353516, 0.6650980114936829]
plot_loss_curves(history_1)
# Unfreeze all of the layers in the base model
base_model.trainable = True
# Refreeze every layer except for the last 5
for layer in base_model.layers[:-5]:
layer.trainable = False
# Recompile model with lower learning rate
model_1.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
# Fine-tune for 5 more epochs
fine_tune_epochs = 10
history_1_fine_tune_1 = model_1.fit(train_data,
epochs=fine_tune_epochs,
validation_data=val_data,
validation_steps=len(val_data),
initial_epoch=history_1.epoch[-1])
model_1.evaluate(test_data)
plot_loss_curves(history_1_fine_tune_1)
compare_historys(history_1, history_1_fine_tune_1, initial_epochs=5)
# Unfreeze all of the layers in the base model
base_model.trainable = True
# Refreeze every layer except for the last 5
for layer in base_model.layers[:-10]:
layer.trainable = False
# Recompile model with lower learning rate
model_1.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-5),
metrics=['accuracy'])
# Fine-tune for 5 more epochs
fine_tune_epochs = 15
history_1_fine_tune_2 = model_1.fit(train_data,
epochs=fine_tune_epochs,
validation_data=val_data,
validation_steps=len(val_data),
initial_epoch=history_1_fine_tune_1.epoch[-1])
model_1.evaluate(test_data)
plot_loss_curves(history_1_fine_tune_2)
compare_historys(history_1_fine_tune_1, history_1_fine_tune_2, initial_epochs=10)
Model 2¶
# Setup base model and freeze its layers (this will extract features)
base_model = tf.keras.applications.EfficientNetB2(include_top=False)
base_model.trainable = False
# Setup model architecture with trainable top layers
inputs = tf.keras.layers.Input(shape=(224, 224, 3), name="input_layer")
x = data_augmentation(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling")(x)
outputs = tf.keras.layers.Dense(255, activation="softmax", name="output_layer")(x)
model_2 = tf.keras.Model(inputs, outputs)
# Compile
model_2.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Fit
history_2 = model_2.fit(train_data,
epochs=5,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data))
model_2.evaluate(test_data)
plot_loss_curves(history_2)
# Unfreeze all of the layers in the base model
base_model.trainable = True
# Refreeze every layer except for the last 5
for layer in base_model.layers[:-5]:
layer.trainable = False
# Recompile model with lower learning rate
model_2.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
# Fine-tune for 5 more epochs
fine_tune_epochs = 10
history_2_fine_tune_1 = model_2.fit(train_data,
epochs=fine_tune_epochs,
validation_data=val_data,
validation_steps=len(val_data),
initial_epoch=history_2.epoch[-1])
model_2.evaluate(test_data)
plot_loss_curves(history_2_fine_tune_1)
compare_historys(history_2, history_2_fine_tune_1, initial_epochs=5)
Model 3¶
# Setup base model and freeze its layers (this will extract features)
base_model = tf.keras.applications.EfficientNetB3(include_top=False)
base_model.trainable = False
# Setup model architecture with trainable top layers
inputs = tf.keras.layers.Input(shape=(224, 224, 3), name="input_layer")
x = data_augmentation(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling")(x)
outputs = tf.keras.layers.Dense(255, activation="softmax", name="output_layer")(x)
model_3 = tf.keras.Model(inputs, outputs)
Downloading data from https://storage.googleapis.com/keras-applications/efficientnetb3_notop.h5 43941888/43941136 [==============================] - 0s 0us/step
# Compile
model_3.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Create early stopping (once our model stops improving, stop training)
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
patience=3)
history_3 = model_3.fit(train_data,
epochs=25,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data),
callbacks=early_stopping)
Epoch 1/25 1435/1435 [==============================] - 555s 321ms/step - loss: 2.8019 - accuracy: 0.3890 - val_loss: 2.0242 - val_accuracy: 0.5086 Epoch 2/25 1435/1435 [==============================] - 308s 215ms/step - loss: 1.8403 - accuracy: 0.5550 - val_loss: 1.8085 - val_accuracy: 0.5506 Epoch 3/25 1435/1435 [==============================] - 253s 176ms/step - loss: 1.5729 - accuracy: 0.6112 - val_loss: 1.7116 - val_accuracy: 0.5725 Epoch 4/25 1435/1435 [==============================] - 230s 160ms/step - loss: 1.4156 - accuracy: 0.6432 - val_loss: 1.6782 - val_accuracy: 0.5851 Epoch 5/25 1435/1435 [==============================] - 215s 149ms/step - loss: 1.3017 - accuracy: 0.6708 - val_loss: 1.6601 - val_accuracy: 0.5894 Epoch 6/25 1435/1435 [==============================] - 205s 143ms/step - loss: 1.2163 - accuracy: 0.6889 - val_loss: 1.6428 - val_accuracy: 0.6004 Epoch 7/25 1435/1435 [==============================] - 200s 139ms/step - loss: 1.1337 - accuracy: 0.7080 - val_loss: 1.6083 - val_accuracy: 0.6071 Epoch 8/25 1435/1435 [==============================] - 195s 136ms/step - loss: 1.0829 - accuracy: 0.7182 - val_loss: 1.6128 - val_accuracy: 0.6047 Epoch 9/25 1435/1435 [==============================] - 191s 133ms/step - loss: 1.0295 - accuracy: 0.7304 - val_loss: 1.6234 - val_accuracy: 0.6000 Epoch 10/25 1435/1435 [==============================] - 191s 133ms/step - loss: 0.9886 - accuracy: 0.7398 - val_loss: 1.5905 - val_accuracy: 0.6110 Epoch 11/25 1435/1435 [==============================] - 187s 130ms/step - loss: 0.9439 - accuracy: 0.7497 - val_loss: 1.6088 - val_accuracy: 0.6137 Epoch 12/25 1435/1435 [==============================] - 187s 131ms/step - loss: 0.9186 - accuracy: 0.7565 - val_loss: 1.5928 - val_accuracy: 0.6098 Epoch 13/25 1435/1435 [==============================] - 186s 130ms/step - loss: 0.8794 - accuracy: 0.7637 - val_loss: 1.6133 - val_accuracy: 0.6000 Epoch 14/25 1435/1435 [==============================] - 186s 129ms/step - loss: 0.8464 - accuracy: 0.7723 - val_loss: 1.6035 - val_accuracy: 0.6051
model_3.evaluate(test_data)
80/80 [==============================] - 9s 116ms/step - loss: 1.5996 - accuracy: 0.6075
[1.5996389389038086, 0.6074509620666504]
plot_loss_curves(history_3)
Model 4¶
# Setup base model and freeze its layers (this will extract features)
base_model = tf.keras.applications.EfficientNetB0(include_top=False)
base_model.trainable = False
# Setup model architecture with trainable top layers
inputs = tf.keras.layers.Input(shape=(224, 224, 3), name="input_layer")
x = data_augmentation(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling")(x)
outputs = tf.keras.layers.Dense(255, activation="softmax", name="output_layer")(x)
model_4 = tf.keras.Model(inputs, outputs)
# Compile
model_4.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Fit
history_4 = model_4.fit(train_data,
epochs=5,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data))
Downloading data from https://storage.googleapis.com/keras-applications/efficientnetb0_notop.h5 16711680/16705208 [==============================] - 0s 0us/step Epoch 1/5 1435/1435 [==============================] - 321s 200ms/step - loss: 2.8269 - accuracy: 0.3931 - val_loss: 1.9797 - val_accuracy: 0.5278 Epoch 2/5 1435/1435 [==============================] - 185s 129ms/step - loss: 1.8304 - accuracy: 0.5640 - val_loss: 1.7472 - val_accuracy: 0.5733 Epoch 3/5 1435/1435 [==============================] - 156s 108ms/step - loss: 1.5587 - accuracy: 0.6214 - val_loss: 1.6709 - val_accuracy: 0.5941 Epoch 4/5 1435/1435 [==============================] - 146s 102ms/step - loss: 1.3974 - accuracy: 0.6545 - val_loss: 1.6232 - val_accuracy: 0.6086 Epoch 5/5 1435/1435 [==============================] - 135s 94ms/step - loss: 1.2881 - accuracy: 0.6796 - val_loss: 1.5965 - val_accuracy: 0.6020
plot_loss_curves(history_4)
# Unfreeze all of the layers in the base model
base_model.trainable = True
# Refreeze every layer except for the last 5
for layer in base_model.layers[:-100]:
layer.trainable = False
# Recompile model with lower learning rate
model_4.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
patience=3)
# Fine-tune for 5 more epochs
fine_tune_epochs = 50
history_4_fine_tune_1 = model_4.fit(train_data,
epochs=fine_tune_epochs,
validation_data=val_data,
validation_steps=len(val_data),
initial_epoch=history_4.epoch[-1],
callbacks=early_stopping)
Epoch 5/50 1435/1435 [==============================] - 192s 129ms/step - loss: 1.0004 - accuracy: 0.7380 - val_loss: 1.4534 - val_accuracy: 0.6502 Epoch 6/50 1435/1435 [==============================] - 175s 122ms/step - loss: 0.7869 - accuracy: 0.7875 - val_loss: 1.3825 - val_accuracy: 0.6655 Epoch 7/50 1435/1435 [==============================] - 172s 120ms/step - loss: 0.6489 - accuracy: 0.8212 - val_loss: 1.4613 - val_accuracy: 0.6710 Epoch 8/50 1435/1435 [==============================] - 169s 118ms/step - loss: 0.5478 - accuracy: 0.8466 - val_loss: 1.4318 - val_accuracy: 0.6769 Epoch 9/50 1435/1435 [==============================] - 170s 118ms/step - loss: 0.4648 - accuracy: 0.8671 - val_loss: 1.4554 - val_accuracy: 0.6729 Epoch 10/50 1435/1435 [==============================] - 169s 118ms/step - loss: 0.3912 - accuracy: 0.8846 - val_loss: 1.5007 - val_accuracy: 0.6824 Epoch 11/50 1435/1435 [==============================] - 167s 117ms/step - loss: 0.3375 - accuracy: 0.8985 - val_loss: 1.5475 - val_accuracy: 0.6788 Epoch 12/50 1435/1435 [==============================] - 167s 116ms/step - loss: 0.2924 - accuracy: 0.9102 - val_loss: 1.6088 - val_accuracy: 0.6773 Epoch 13/50 1435/1435 [==============================] - 167s 117ms/step - loss: 0.2546 - accuracy: 0.9215 - val_loss: 1.6707 - val_accuracy: 0.6796
plot_loss_curves(history_4_fine_tune_1)
compare_historys(history_4, history_4_fine_tune_1, initial_epochs=5)
Model 5¶
# Setup base model and freeze its layers (this will extract features)
base_model = tf.keras.applications.EfficientNetB3(include_top=False)
base_model.trainable = False
# Setup model architecture with trainable top layers
inputs = tf.keras.layers.Input(shape=(224, 224, 3), name="input_layer")
x = data_augmentation(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.GlobalAveragePooling2D(name="global_average_pooling")(x)
outputs = tf.keras.layers.Dense(255, activation="softmax", name="output_layer")(x)
model_B3 = tf.keras.Model(inputs, outputs)
# Compile
model_B3.compile(loss="categorical_crossentropy",
optimizer=tf.keras.optimizers.Adam(),
metrics=["accuracy"])
# Fit
history_B3 = model_B3.fit(train_data,
epochs=5,
steps_per_epoch=len(train_data),
validation_data=val_data,
validation_steps=len(val_data))
Downloading data from https://storage.googleapis.com/keras-applications/efficientnetb3_notop.h5 43941888/43941136 [==============================] - 0s 0us/step Epoch 1/5 1435/1435 [==============================] - 506s 327ms/step - loss: 2.8071 - accuracy: 0.3873 - val_loss: 2.0247 - val_accuracy: 0.5075 Epoch 2/5 1435/1435 [==============================] - 306s 214ms/step - loss: 1.8404 - accuracy: 0.5536 - val_loss: 1.8049 - val_accuracy: 0.5467 Epoch 3/5 1435/1435 [==============================] - 254s 177ms/step - loss: 1.5791 - accuracy: 0.6086 - val_loss: 1.6956 - val_accuracy: 0.5710 Epoch 4/5 1435/1435 [==============================] - 232s 162ms/step - loss: 1.4148 - accuracy: 0.6430 - val_loss: 1.6495 - val_accuracy: 0.5859 Epoch 5/5 1435/1435 [==============================] - 215s 150ms/step - loss: 1.2917 - accuracy: 0.6715 - val_loss: 1.6320 - val_accuracy: 0.5902
plot_loss_curves(history_B3)
# Unfreeze all of the layers in the base model
base_model.trainable = True
# Refreeze every layer except for the last 50
for layer in base_model.layers[:-50]:
layer.trainable = False
# Recompile model with lower learning rate
model_B3.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_accuracy",
patience=3)
# Fine-tune for 45 more epochs (5+45)
fine_tune_epochs = 50
history_B3_fine_tune_1 = model_B3.fit(train_data,
epochs=fine_tune_epochs,
validation_data=val_data,
validation_steps=len(val_data),
initial_epoch=history_B3.epoch[-1],
callbacks=early_stopping)
Epoch 5/50 1435/1435 [==============================] - 224s 151ms/step - loss: 0.1849 - accuracy: 0.9434 - val_loss: 1.6478 - val_accuracy: 0.6812 Epoch 6/50 1435/1435 [==============================] - 219s 153ms/step - loss: 0.1643 - accuracy: 0.9488 - val_loss: 1.6688 - val_accuracy: 0.6745 Epoch 7/50 1435/1435 [==============================] - 220s 153ms/step - loss: 0.1513 - accuracy: 0.9527 - val_loss: 1.6500 - val_accuracy: 0.6910 Epoch 8/50 1435/1435 [==============================] - 216s 151ms/step - loss: 0.1399 - accuracy: 0.9571 - val_loss: 1.6851 - val_accuracy: 0.6769 Epoch 9/50 1435/1435 [==============================] - 217s 151ms/step - loss: 0.1293 - accuracy: 0.9590 - val_loss: 1.7226 - val_accuracy: 0.6843 Epoch 10/50 1435/1435 [==============================] - 217s 151ms/step - loss: 0.1281 - accuracy: 0.9598 - val_loss: 1.6509 - val_accuracy: 0.6969 Epoch 11/50 1435/1435 [==============================] - 218s 152ms/step - loss: 0.1217 - accuracy: 0.9622 - val_loss: 1.6366 - val_accuracy: 0.6882 Epoch 12/50 1435/1435 [==============================] - 217s 151ms/step - loss: 0.1119 - accuracy: 0.9649 - val_loss: 1.6618 - val_accuracy: 0.6898 Epoch 13/50 1435/1435 [==============================] - 216s 150ms/step - loss: 0.1108 - accuracy: 0.9660 - val_loss: 1.6824 - val_accuracy: 0.6871
plot_loss_curves(history_B3_fine_tune_1)
compare_historys(history_B3, history_B3_fine_tune_1, initial_epochs=5)
Saving and loading the best model¶
tf.keras.models.save_model(model_B3, "/content/drive/MyDrive/Fruits-262_Model")
/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/utils/generic_utils.py:497: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument. category=CustomMaskWarning)
INFO:tensorflow:Assets written to: /content/drive/MyDrive/Fruits-262_Model/assets
model_load = tf.keras.models.load_model("/content/drive/MyDrive/Fruits-262_Model")
Evaluation of best model¶
model_load.evaluate(test_data)
80/80 [==============================] - 11s 118ms/step - loss: 1.7351 - accuracy: 0.6965
[1.735092043876648, 0.6964705586433411]
Insights of the best Model¶
preds = model_load.predict(test_data)
preds
array([[3.2967772e-16, 1.3262458e-09, 1.2792330e-14, ..., 2.6424347e-16, 2.0012646e-19, 1.1931388e-17], [1.4423055e-13, 5.1208959e-12, 8.5394198e-09, ..., 8.6216861e-14, 1.2716658e-16, 1.5510660e-11], [2.4595640e-12, 3.8157321e-11, 4.0989000e-12, ..., 4.6068169e-10, 1.3204209e-07, 5.8626395e-04], ..., [1.7037593e-05, 2.6440478e-06, 3.3086530e-07, ..., 2.1191319e-05, 5.2426234e-02, 2.5961395e-09], [2.0389165e-10, 2.5027229e-12, 9.6114635e-12, ..., 6.3187695e-09, 9.9374479e-01, 2.5175513e-15], [3.6685952e-14, 3.5023043e-12, 5.6985550e-16, ..., 1.1945985e-12, 5.7556120e-11, 6.2296425e-11]], dtype=float32)
preds[0].argmax()
218
dict_class = test_data.class_indices
classes = []
for elem in dict_class.keys():
classes.append(elem)
dict_class.keys()
dict_keys(['abiu', 'acai', 'acerola', 'ackee', 'alligator apple', 'ambarella', 'apple', 'apricot', 'araza', 'avocado', 'bael', 'banana', 'barbadine', 'barberry', 'bayberry', 'beach plum', 'bearberry', 'bell pepper', 'betel nut', 'bignay', 'bilimbi', 'bitter gourd', 'black berry', 'black cherry', 'black currant', 'black mullberry', 'black sapote', 'blueberry', 'bolwarra', 'bottle gourd', 'brazil nut', 'bread fruit', "buddha's hand", 'buffaloberry', 'burdekin plum', 'burmese grape', 'caimito', 'camu camu', 'canistel', 'cantaloupe', 'cape gooseberry', 'carambola', 'cardon', 'cashew', 'cedar bay cherry', 'cempedak', 'ceylon gooseberry', 'che', 'chenet', 'cherimoya', 'cherry', 'chico', 'chokeberry', 'clementine', 'cloudberry', 'cluster fig', 'cocoa bean', 'coconut', 'coffee', 'common buckthorn', 'corn kernel', 'cornelian cherry', 'crab apple', 'cranberry', 'crowberry', 'cupuacu', 'custard apple', 'damson', 'date', 'desert fig', 'desert lime', 'dewberry', 'dragonfruit', 'durian', 'eggplant', 'elderberry', 'elephant apple', 'emblic', 'entawak', 'etrog', 'feijoa', 'fibrous satinash', 'fig', 'finger lime', 'galia melon', 'gandaria', 'genipap', 'goji', 'gooseberry', 'goumi', 'grape', 'grapefruit', 'greengage', 'grenadilla', 'guanabana', 'guarana', 'guava', 'guavaberry', 'hackberry', 'hard kiwi', 'hawthorn', 'hog plum', 'honeyberry', 'honeysuckle', 'horned melon', 'illawarra plum', 'indian almond', 'indian strawberry', 'ita palm', 'jaboticaba', 'jackfruit', 'jalapeno', 'jamaica cherry', 'jambul', 'japanese raisin', 'jasmine', 'jatoba', 'jocote', 'jostaberry', 'jujube', 'juniper berry', 'kaffir lime', 'kahikatea', 'kakadu plum', 'keppel', 'kiwi', 'kumquat', 'kundong', 'kutjera', 'lablab', 'langsat', 'lapsi', 'lemon', 'lemon aspen', 'leucaena', 'lillipilli', 'lime', 'lingonberry', 'loganberry', 'longan', 'loquat', 'lucuma', 'lulo', 'lychee', 'mabolo', 'macadamia', 'malay apple', 'mamey apple', 'mandarine', 'mango', 'mangosteen', 'manila tamarind', 'marang', 'mayhaw', 'maypop', 'medlar', 'melinjo', 'melon pear', 'midyim', 'miracle fruit', 'mock strawberry', 'monkfruit', 'monstera deliciosa', 'morinda', 'mountain papaya', 'mountain soursop', 'mundu', 'muskmelon', 'myrtle', 'nance', 'nannyberry', 'naranjilla', 'native cherry', 'native gooseberry', 'nectarine', 'neem', 'nungu', 'nutmeg', 'oil palm', 'old world sycomore', 'olive', 'orange', 'oregon grape', 'otaheite apple', 'papaya', 'passion fruit', 'pawpaw', 'pea', 'peanut', 'pear', 'pequi', 'persimmon', 'pigeon plum', 'pili nut', 'pineapple', 'pineberry', 'pitomba', 'plumcot', 'pomegranate', 'pomelo', 'prikly pear', 'pulasan', 'pumpkin', 'pupunha', 'purple apple berry', 'quandong', 'quince', 'rambutan', 'rangpur', 'raspberry', 'red mulberry', 'redcurrant', 'riberry', 'ridged gourd', 'rose hip', 'rose-leaf bramble', 'saguaro', 'salak', 'salal', 'salmonberry', 'sandpaper fig', 'santol', 'sapodilla', 'saskatoon', 'sea buckthorn', 'sea grape', 'snowberry', 'soncoya', 'strawberry', 'strawberry guava', 'sugar apple', 'surinam cherry', 'sycamore fig', 'tamarillo', 'tangelo', 'taxus baccata', 'tayberry', 'texas persimmon', 'thimbleberry', 'tomato', 'toyon', 'ugli fruit', 'vanilla', 'velvet tamarind', 'watermelon', 'wax gourd', 'white currant', 'white mulberry', 'white sapote', 'wineberry', 'wongi', 'yali pear', 'yellow plum', 'yuzu', 'zucchini'])
classes
['abiu', 'acai', 'acerola', 'ackee', 'alligator apple', 'ambarella', 'apple', 'apricot', 'araza', 'avocado', 'bael', 'banana', 'barbadine', 'barberry', 'bayberry', 'beach plum', 'bearberry', 'bell pepper', 'betel nut', 'bignay', 'bilimbi', 'bitter gourd', 'black berry', 'black cherry', 'black currant', 'black mullberry', 'black sapote', 'blueberry', 'bolwarra', 'bottle gourd', 'brazil nut', 'bread fruit', "buddha's hand", 'buffaloberry', 'burdekin plum', 'burmese grape', 'caimito', 'camu camu', 'canistel', 'cantaloupe', 'cape gooseberry', 'carambola', 'cardon', 'cashew', 'cedar bay cherry', 'cempedak', 'ceylon gooseberry', 'che', 'chenet', 'cherimoya', 'cherry', 'chico', 'chokeberry', 'clementine', 'cloudberry', 'cluster fig', 'cocoa bean', 'coconut', 'coffee', 'common buckthorn', 'corn kernel', 'cornelian cherry', 'crab apple', 'cranberry', 'crowberry', 'cupuacu', 'custard apple', 'damson', 'date', 'desert fig', 'desert lime', 'dewberry', 'dragonfruit', 'durian', 'eggplant', 'elderberry', 'elephant apple', 'emblic', 'entawak', 'etrog', 'feijoa', 'fibrous satinash', 'fig', 'finger lime', 'galia melon', 'gandaria', 'genipap', 'goji', 'gooseberry', 'goumi', 'grape', 'grapefruit', 'greengage', 'grenadilla', 'guanabana', 'guarana', 'guava', 'guavaberry', 'hackberry', 'hard kiwi', 'hawthorn', 'hog plum', 'honeyberry', 'honeysuckle', 'horned melon', 'illawarra plum', 'indian almond', 'indian strawberry', 'ita palm', 'jaboticaba', 'jackfruit', 'jalapeno', 'jamaica cherry', 'jambul', 'japanese raisin', 'jasmine', 'jatoba', 'jocote', 'jostaberry', 'jujube', 'juniper berry', 'kaffir lime', 'kahikatea', 'kakadu plum', 'keppel', 'kiwi', 'kumquat', 'kundong', 'kutjera', 'lablab', 'langsat', 'lapsi', 'lemon', 'lemon aspen', 'leucaena', 'lillipilli', 'lime', 'lingonberry', 'loganberry', 'longan', 'loquat', 'lucuma', 'lulo', 'lychee', 'mabolo', 'macadamia', 'malay apple', 'mamey apple', 'mandarine', 'mango', 'mangosteen', 'manila tamarind', 'marang', 'mayhaw', 'maypop', 'medlar', 'melinjo', 'melon pear', 'midyim', 'miracle fruit', 'mock strawberry', 'monkfruit', 'monstera deliciosa', 'morinda', 'mountain papaya', 'mountain soursop', 'mundu', 'muskmelon', 'myrtle', 'nance', 'nannyberry', 'naranjilla', 'native cherry', 'native gooseberry', 'nectarine', 'neem', 'nungu', 'nutmeg', 'oil palm', 'old world sycomore', 'olive', 'orange', 'oregon grape', 'otaheite apple', 'papaya', 'passion fruit', 'pawpaw', 'pea', 'peanut', 'pear', 'pequi', 'persimmon', 'pigeon plum', 'pili nut', 'pineapple', 'pineberry', 'pitomba', 'plumcot', 'pomegranate', 'pomelo', 'prikly pear', 'pulasan', 'pumpkin', 'pupunha', 'purple apple berry', 'quandong', 'quince', 'rambutan', 'rangpur', 'raspberry', 'red mulberry', 'redcurrant', 'riberry', 'ridged gourd', 'rose hip', 'rose-leaf bramble', 'saguaro', 'salak', 'salal', 'salmonberry', 'sandpaper fig', 'santol', 'sapodilla', 'saskatoon', 'sea buckthorn', 'sea grape', 'snowberry', 'soncoya', 'strawberry', 'strawberry guava', 'sugar apple', 'surinam cherry', 'sycamore fig', 'tamarillo', 'tangelo', 'taxus baccata', 'tayberry', 'texas persimmon', 'thimbleberry', 'tomato', 'toyon', 'ugli fruit', 'vanilla', 'velvet tamarind', 'watermelon', 'wax gourd', 'white currant', 'white mulberry', 'white sapote', 'wineberry', 'wongi', 'yali pear', 'yellow plum', 'yuzu', 'zucchini']
classes[218]
'salal'
len(classes)
255
preds.shape
(2550, 255)
preds = preds.argmax(axis=1)
preds
array([218, 210, 164, ..., 53, 253, 32])
test_df.head()
filepaths | labels | |
---|---|---|
7253 | /content/Fruit-262/salal/332.jpg | salal |
34972 | /content/Fruit-262/black mullberry/845.jpg | black mullberry |
39483 | /content/Fruit-262/mountain papaya/542.jpg | mountain papaya |
43154 | /content/Fruit-262/ugli fruit/732.jpg | ugli fruit |
7337 | /content/Fruit-262/salal/90.jpg | salal |
y_labels = np.array(pd.Series(test_df["labels"]))
y_labels[:5]
array(['salal', 'black mullberry', 'mountain papaya', 'ugli fruit', 'salal'], dtype=object)
true = []
for i in y_labels:
for j in range(0, 255):
if i == classes[j]:
true.append(j)
break
len(true)
2550
true[0]
218
len(preds)
2550
preds[0]
218
pred_probs = model_load.predict(test_data)
pred_probs
array([[3.2967772e-16, 1.3262458e-09, 1.2792330e-14, ..., 2.6424347e-16, 2.0012646e-19, 1.1931388e-17], [1.4423055e-13, 5.1208959e-12, 8.5394198e-09, ..., 8.6216861e-14, 1.2716658e-16, 1.5510660e-11], [2.4595640e-12, 3.8157321e-11, 4.0989000e-12, ..., 4.6068169e-10, 1.3204209e-07, 5.8626395e-04], ..., [1.7037593e-05, 2.6440478e-06, 3.3086530e-07, ..., 2.1191319e-05, 5.2426234e-02, 2.5961395e-09], [2.0389165e-10, 2.5027229e-12, 9.6114635e-12, ..., 6.3187695e-09, 9.9374479e-01, 2.5175513e-15], [3.6685952e-14, 3.5023043e-12, 5.6985550e-16, ..., 1.1945985e-12, 5.7556120e-11, 6.2296425e-11]], dtype=float32)
sklearn_accuracy = accuracy_score(true, preds)
sklearn_accuracy
0.6964705882352941
Confusion Matrix¶
# Plot a confusion matrix with all 25250 predictions, ground truth labels and 255 classes
make_confusion_matrix(y_true=true,
y_pred=preds,
classes=classes,
figsize=(100,100),
text_size=20,
norm=False,
savefig=True)
print(classification_report(true, preds))
precision recall f1-score support 0 0.62 0.56 0.59 9 1 0.80 0.44 0.57 9 2 0.43 0.33 0.38 9 3 0.75 0.86 0.80 7 4 0.75 0.67 0.71 9 5 0.38 0.56 0.45 9 6 1.00 0.62 0.77 8 7 0.29 0.33 0.31 6 8 0.43 0.82 0.56 11 9 0.57 1.00 0.73 8 10 0.67 0.67 0.67 9 11 1.00 1.00 1.00 10 12 0.71 0.42 0.53 12 13 0.82 0.90 0.86 10 14 0.78 0.88 0.82 8 15 0.52 0.69 0.59 16 16 0.56 0.83 0.67 6 17 1.00 0.89 0.94 9 18 0.64 0.75 0.69 12 19 0.62 0.62 0.62 8 20 0.92 0.92 0.92 13 21 0.86 0.67 0.75 9 22 0.65 0.85 0.73 13 23 0.64 0.75 0.69 12 24 0.60 0.50 0.55 12 25 1.00 0.18 0.31 11 26 0.50 0.67 0.57 6 27 0.82 0.75 0.78 12 28 0.50 0.38 0.43 8 29 0.50 0.50 0.50 4 30 1.00 0.57 0.73 7 31 0.78 0.50 0.61 14 32 1.00 0.91 0.95 11 33 0.67 0.62 0.64 13 34 0.92 1.00 0.96 12 35 0.00 0.00 0.00 5 36 0.75 0.90 0.82 10 37 0.88 0.88 0.88 8 38 0.43 0.50 0.46 12 39 0.24 0.42 0.30 12 40 0.43 0.50 0.46 6 41 0.91 0.91 0.91 11 42 0.50 0.86 0.63 7 43 1.00 0.55 0.71 11 44 0.56 0.62 0.59 8 45 0.80 0.62 0.70 13 46 0.56 1.00 0.72 9 47 0.80 0.80 0.80 5 48 1.00 0.70 0.82 10 49 0.67 0.31 0.42 13 50 0.50 0.88 0.64 8 51 0.29 0.40 0.33 10 52 0.53 0.73 0.62 11 53 0.69 0.45 0.55 20 54 0.83 0.71 0.77 7 55 0.75 0.46 0.57 13 56 0.56 0.71 0.63 7 57 1.00 1.00 1.00 14 58 0.67 0.25 0.36 8 59 0.80 0.89 0.84 9 60 1.00 1.00 1.00 11 61 0.57 0.44 0.50 9 62 0.25 0.50 0.33 4 63 0.40 0.33 0.36 6 64 1.00 1.00 1.00 15 65 0.71 0.56 0.63 9 66 0.20 0.43 0.27 7 67 0.50 0.36 0.42 14 68 0.62 0.71 0.67 7 69 0.67 0.60 0.63 10 70 0.59 0.77 0.67 13 71 0.77 0.62 0.69 16 72 1.00 0.44 0.62 9 73 0.83 1.00 0.91 10 74 0.94 0.94 0.94 17 75 0.83 0.50 0.62 10 76 0.73 0.89 0.80 9 77 1.00 0.71 0.83 7 78 0.80 1.00 0.89 8 79 0.88 0.70 0.78 10 80 0.50 0.50 0.50 4 81 0.40 0.62 0.48 13 82 0.67 0.80 0.73 5 83 0.90 0.90 0.90 10 84 0.50 0.50 0.50 10 85 0.62 0.50 0.56 10 86 0.85 0.92 0.88 12 87 1.00 0.62 0.76 13 88 1.00 0.92 0.96 12 89 0.80 0.80 0.80 15 90 1.00 0.80 0.89 10 91 0.50 0.42 0.45 12 92 0.78 0.64 0.70 11 93 0.57 0.73 0.64 11 94 0.54 1.00 0.70 7 95 1.00 0.77 0.87 13 96 0.67 0.46 0.55 13 97 0.90 0.82 0.86 11 98 0.83 0.71 0.77 7 99 0.50 0.71 0.59 7 100 0.57 0.57 0.57 7 101 0.25 0.33 0.29 6 102 1.00 0.80 0.89 10 103 0.77 0.71 0.74 14 104 1.00 1.00 1.00 11 105 0.87 1.00 0.93 13 106 0.20 0.14 0.17 7 107 0.00 0.00 0.00 11 108 0.70 1.00 0.82 7 109 0.64 0.78 0.70 9 110 0.74 0.93 0.82 15 111 1.00 0.75 0.86 8 112 0.67 0.50 0.57 12 113 0.60 0.43 0.50 7 114 0.83 1.00 0.91 10 115 0.78 0.64 0.70 11 116 0.53 0.77 0.62 13 117 0.44 0.44 0.44 9 118 0.88 0.88 0.88 8 119 0.71 0.50 0.59 10 120 0.88 0.70 0.78 10 121 0.75 0.86 0.80 7 122 1.00 0.89 0.94 9 123 0.78 0.54 0.64 13 124 0.92 0.86 0.89 14 125 0.71 0.56 0.63 9 126 0.44 0.44 0.44 9 127 0.67 0.86 0.75 7 128 0.90 0.69 0.78 13 129 1.00 0.88 0.93 8 130 0.71 0.62 0.67 8 131 0.83 0.50 0.62 10 132 0.56 0.42 0.48 12 133 0.88 0.70 0.78 10 134 0.79 1.00 0.88 11 135 0.09 0.20 0.13 5 136 0.12 0.17 0.14 6 137 0.67 0.33 0.44 6 138 0.60 0.67 0.63 9 139 0.60 0.55 0.57 11 140 0.89 0.73 0.80 11 141 0.33 0.45 0.38 11 142 0.20 0.50 0.29 6 143 1.00 0.50 0.67 6 144 0.73 0.80 0.76 10 145 0.25 0.20 0.22 5 146 0.33 0.38 0.35 8 147 0.54 0.78 0.64 9 148 0.36 0.50 0.42 8 149 0.25 0.50 0.33 6 150 0.80 1.00 0.89 12 151 0.92 0.92 0.92 12 152 0.90 1.00 0.95 9 153 1.00 0.42 0.59 12 154 0.70 0.70 0.70 10 155 0.61 0.79 0.69 14 156 0.89 0.89 0.89 9 157 0.86 0.86 0.86 14 158 1.00 0.88 0.93 8 159 0.62 0.80 0.70 10 160 0.42 0.73 0.53 11 161 0.89 0.80 0.84 10 162 1.00 0.89 0.94 9 163 0.90 0.90 0.90 10 164 0.79 0.58 0.67 19 165 0.25 0.33 0.29 6 166 0.60 0.50 0.55 6 167 0.50 0.29 0.37 17 168 0.77 0.91 0.83 11 169 1.00 0.14 0.25 7 170 0.75 0.60 0.67 10 171 0.80 0.44 0.57 18 172 1.00 0.75 0.86 8 173 0.75 0.55 0.63 11 174 0.64 0.82 0.72 11 175 1.00 0.64 0.78 14 176 0.64 1.00 0.78 7 177 1.00 0.70 0.82 10 178 0.81 0.93 0.87 14 179 0.92 0.79 0.85 14 180 1.00 0.50 0.67 16 181 0.36 0.71 0.48 7 182 0.90 0.90 0.90 10 183 0.33 0.42 0.37 12 184 0.62 0.62 0.62 13 185 0.40 0.33 0.36 6 186 0.59 0.83 0.69 12 187 1.00 0.70 0.82 10 188 0.67 0.75 0.71 8 189 0.80 1.00 0.89 4 190 0.83 0.38 0.53 13 191 0.80 0.80 0.80 10 192 0.88 0.88 0.88 17 193 0.90 1.00 0.95 9 194 0.82 1.00 0.90 9 195 0.94 1.00 0.97 16 196 0.86 0.55 0.67 11 197 0.43 0.27 0.33 11 198 0.56 0.71 0.63 7 199 0.44 0.67 0.53 6 200 0.82 0.75 0.78 12 201 0.92 0.92 0.92 12 202 0.82 1.00 0.90 9 203 0.89 0.73 0.80 11 204 1.00 1.00 1.00 3 205 0.73 0.92 0.81 12 206 0.62 0.67 0.64 12 207 0.75 1.00 0.86 3 208 0.17 0.33 0.22 6 209 0.57 0.73 0.64 11 210 0.59 0.83 0.69 12 211 0.50 0.25 0.33 4 212 0.88 0.44 0.58 16 213 0.75 0.86 0.80 7 214 0.86 0.75 0.80 16 215 0.71 0.45 0.56 11 216 0.92 0.86 0.89 14 217 0.88 1.00 0.93 7 218 0.92 0.86 0.89 14 219 1.00 0.86 0.92 7 220 0.58 1.00 0.74 7 221 1.00 0.77 0.87 13 222 0.50 0.45 0.48 11 223 0.90 0.75 0.82 12 224 1.00 0.92 0.96 12 225 0.93 0.87 0.90 15 226 1.00 0.89 0.94 9 227 0.92 1.00 0.96 11 228 0.78 0.78 0.78 9 229 0.43 0.75 0.55 8 230 0.43 0.25 0.32 12 231 0.71 1.00 0.83 5 232 0.72 0.93 0.81 14 233 0.64 0.88 0.74 8 234 0.67 0.73 0.70 11 235 1.00 0.80 0.89 10 236 0.67 0.57 0.62 7 237 0.92 0.92 0.92 13 238 0.50 0.71 0.59 7 239 0.82 0.93 0.87 15 240 0.64 0.78 0.70 9 241 0.55 0.75 0.63 8 242 0.86 1.00 0.92 6 243 0.69 0.75 0.72 12 244 1.00 0.78 0.88 18 245 0.55 0.75 0.63 8 246 1.00 0.86 0.92 7 247 0.71 1.00 0.83 10 248 0.71 0.50 0.59 10 249 0.44 0.57 0.50 7 250 0.44 0.36 0.40 11 251 0.67 0.80 0.73 5 252 0.56 0.62 0.59 8 253 0.57 0.73 0.64 11 254 0.90 0.82 0.86 11 accuracy 0.70 2550 macro avg 0.71 0.69 0.68 2550 weighted avg 0.73 0.70 0.70 2550
# Get a dictionary of the classification report
classification_report_dict = classification_report(true, preds, output_dict=True)
classification_report_dict
{'0': {'f1-score': 0.5882352941176471, 'precision': 0.625, 'recall': 0.5555555555555556, 'support': 9}, '1': {'f1-score': 0.5714285714285714, 'precision': 0.8, 'recall': 0.4444444444444444, 'support': 9}, '10': {'f1-score': 0.6666666666666666, 'precision': 0.6666666666666666, 'recall': 0.6666666666666666, 'support': 9}, '100': {'f1-score': 0.5714285714285714, 'precision': 0.5714285714285714, 'recall': 0.5714285714285714, 'support': 7}, '101': {'f1-score': 0.28571428571428575, 'precision': 0.25, 'recall': 0.3333333333333333, 'support': 6}, '102': {'f1-score': 0.888888888888889, 'precision': 1.0, 'recall': 0.8, 'support': 10}, '103': {'f1-score': 0.7407407407407408, 'precision': 0.7692307692307693, 'recall': 0.7142857142857143, 'support': 14}, '104': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 11}, '105': {'f1-score': 0.9285714285714286, 'precision': 0.8666666666666667, 'recall': 1.0, 'support': 13}, '106': {'f1-score': 0.16666666666666666, 'precision': 0.2, 'recall': 0.14285714285714285, 'support': 7}, '107': {'f1-score': 0.0, 'precision': 0.0, 'recall': 0.0, 'support': 11}, '108': {'f1-score': 0.8235294117647058, 'precision': 0.7, 'recall': 1.0, 'support': 7}, '109': {'f1-score': 0.7000000000000001, 'precision': 0.6363636363636364, 'recall': 0.7777777777777778, 'support': 9}, '11': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 10}, '110': {'f1-score': 0.8235294117647058, 'precision': 0.7368421052631579, 'recall': 0.9333333333333333, 'support': 15}, '111': {'f1-score': 0.8571428571428571, 'precision': 1.0, 'recall': 0.75, 'support': 8}, '112': {'f1-score': 0.5714285714285715, 'precision': 0.6666666666666666, 'recall': 0.5, 'support': 12}, '113': {'f1-score': 0.5, 'precision': 0.6, 'recall': 0.42857142857142855, 'support': 7}, '114': {'f1-score': 0.9090909090909091, 'precision': 0.8333333333333334, 'recall': 1.0, 'support': 10}, '115': {'f1-score': 0.7000000000000001, 'precision': 0.7777777777777778, 'recall': 0.6363636363636364, 'support': 11}, '116': {'f1-score': 0.625, 'precision': 0.5263157894736842, 'recall': 0.7692307692307693, 'support': 13}, '117': {'f1-score': 0.4444444444444444, 'precision': 0.4444444444444444, 'recall': 0.4444444444444444, 'support': 9}, '118': {'f1-score': 0.875, 'precision': 0.875, 'recall': 0.875, 'support': 8}, '119': {'f1-score': 0.588235294117647, 'precision': 0.7142857142857143, 'recall': 0.5, 'support': 10}, '12': {'f1-score': 0.5263157894736842, 'precision': 0.7142857142857143, 'recall': 0.4166666666666667, 'support': 12}, '120': {'f1-score': 0.7777777777777777, 'precision': 0.875, 'recall': 0.7, 'support': 10}, '121': {'f1-score': 0.7999999999999999, 'precision': 0.75, 'recall': 0.8571428571428571, 'support': 7}, '122': {'f1-score': 0.9411764705882353, 'precision': 1.0, 'recall': 0.8888888888888888, 'support': 9}, '123': {'f1-score': 0.6363636363636364, 'precision': 0.7777777777777778, 'recall': 0.5384615384615384, 'support': 13}, '124': {'f1-score': 0.888888888888889, 'precision': 0.9230769230769231, 'recall': 0.8571428571428571, 'support': 14}, '125': {'f1-score': 0.6250000000000001, 'precision': 0.7142857142857143, 'recall': 0.5555555555555556, 'support': 9}, '126': {'f1-score': 0.4444444444444444, 'precision': 0.4444444444444444, 'recall': 0.4444444444444444, 'support': 9}, '127': {'f1-score': 0.75, 'precision': 0.6666666666666666, 'recall': 0.8571428571428571, 'support': 7}, '128': {'f1-score': 0.7826086956521738, 'precision': 0.9, 'recall': 0.6923076923076923, 'support': 13}, '129': {'f1-score': 0.9333333333333333, 'precision': 1.0, 'recall': 0.875, 'support': 8}, '13': {'f1-score': 0.8571428571428572, 'precision': 0.8181818181818182, 'recall': 0.9, 'support': 10}, '130': {'f1-score': 0.6666666666666666, 'precision': 0.7142857142857143, 'recall': 0.625, 'support': 8}, '131': {'f1-score': 0.625, 'precision': 0.8333333333333334, 'recall': 0.5, 'support': 10}, '132': {'f1-score': 0.4761904761904762, 'precision': 0.5555555555555556, 'recall': 0.4166666666666667, 'support': 12}, '133': {'f1-score': 0.7777777777777777, 'precision': 0.875, 'recall': 0.7, 'support': 10}, '134': {'f1-score': 0.88, 'precision': 0.7857142857142857, 'recall': 1.0, 'support': 11}, '135': {'f1-score': 0.12500000000000003, 'precision': 0.09090909090909091, 'recall': 0.2, 'support': 5}, '136': {'f1-score': 0.14285714285714288, 'precision': 0.125, 'recall': 0.16666666666666666, 'support': 6}, '137': {'f1-score': 0.4444444444444444, 'precision': 0.6666666666666666, 'recall': 0.3333333333333333, 'support': 6}, '138': {'f1-score': 0.631578947368421, 'precision': 0.6, 'recall': 0.6666666666666666, 'support': 9}, '139': {'f1-score': 0.5714285714285713, 'precision': 0.6, 'recall': 0.5454545454545454, 'support': 11}, '14': {'f1-score': 0.823529411764706, 'precision': 0.7777777777777778, 'recall': 0.875, 'support': 8}, '140': {'f1-score': 0.7999999999999999, 'precision': 0.8888888888888888, 'recall': 0.7272727272727273, 'support': 11}, '141': {'f1-score': 0.3846153846153846, 'precision': 0.3333333333333333, 'recall': 0.45454545454545453, 'support': 11}, '142': {'f1-score': 0.28571428571428575, 'precision': 0.2, 'recall': 0.5, 'support': 6}, '143': {'f1-score': 0.6666666666666666, 'precision': 1.0, 'recall': 0.5, 'support': 6}, '144': {'f1-score': 0.761904761904762, 'precision': 0.7272727272727273, 'recall': 0.8, 'support': 10}, '145': {'f1-score': 0.22222222222222224, 'precision': 0.25, 'recall': 0.2, 'support': 5}, '146': {'f1-score': 0.35294117647058826, 'precision': 0.3333333333333333, 'recall': 0.375, 'support': 8}, '147': {'f1-score': 0.6363636363636364, 'precision': 0.5384615384615384, 'recall': 0.7777777777777778, 'support': 9}, '148': {'f1-score': 0.4210526315789474, 'precision': 0.36363636363636365, 'recall': 0.5, 'support': 8}, '149': {'f1-score': 0.3333333333333333, 'precision': 0.25, 'recall': 0.5, 'support': 6}, '15': {'f1-score': 0.5945945945945946, 'precision': 0.5238095238095238, 'recall': 0.6875, 'support': 16}, '150': {'f1-score': 0.888888888888889, 'precision': 0.8, 'recall': 1.0, 'support': 12}, '151': {'f1-score': 0.9166666666666666, 'precision': 0.9166666666666666, 'recall': 0.9166666666666666, 'support': 12}, '152': {'f1-score': 0.9473684210526316, 'precision': 0.9, 'recall': 1.0, 'support': 9}, '153': {'f1-score': 0.5882352941176471, 'precision': 1.0, 'recall': 0.4166666666666667, 'support': 12}, '154': {'f1-score': 0.7, 'precision': 0.7, 'recall': 0.7, 'support': 10}, '155': {'f1-score': 0.6875000000000001, 'precision': 0.6111111111111112, 'recall': 0.7857142857142857, 'support': 14}, '156': {'f1-score': 0.8888888888888888, 'precision': 0.8888888888888888, 'recall': 0.8888888888888888, 'support': 9}, '157': {'f1-score': 0.8571428571428571, 'precision': 0.8571428571428571, 'recall': 0.8571428571428571, 'support': 14}, '158': {'f1-score': 0.9333333333333333, 'precision': 1.0, 'recall': 0.875, 'support': 8}, '159': {'f1-score': 0.6956521739130435, 'precision': 0.6153846153846154, 'recall': 0.8, 'support': 10}, '16': {'f1-score': 0.6666666666666667, 'precision': 0.5555555555555556, 'recall': 0.8333333333333334, 'support': 6}, '160': {'f1-score': 0.5333333333333333, 'precision': 0.42105263157894735, 'recall': 0.7272727272727273, 'support': 11}, '161': {'f1-score': 0.8421052631578948, 'precision': 0.8888888888888888, 'recall': 0.8, 'support': 10}, '162': {'f1-score': 0.9411764705882353, 'precision': 1.0, 'recall': 0.8888888888888888, 'support': 9}, '163': {'f1-score': 0.9, 'precision': 0.9, 'recall': 0.9, 'support': 10}, '164': {'f1-score': 0.6666666666666667, 'precision': 0.7857142857142857, 'recall': 0.5789473684210527, 'support': 19}, '165': {'f1-score': 0.28571428571428575, 'precision': 0.25, 'recall': 0.3333333333333333, 'support': 6}, '166': {'f1-score': 0.5454545454545454, 'precision': 0.6, 'recall': 0.5, 'support': 6}, '167': {'f1-score': 0.37037037037037035, 'precision': 0.5, 'recall': 0.29411764705882354, 'support': 17}, '168': {'f1-score': 0.8333333333333333, 'precision': 0.7692307692307693, 'recall': 0.9090909090909091, 'support': 11}, '169': {'f1-score': 0.25, 'precision': 1.0, 'recall': 0.14285714285714285, 'support': 7}, '17': {'f1-score': 0.9411764705882353, 'precision': 1.0, 'recall': 0.8888888888888888, 'support': 9}, '170': {'f1-score': 0.6666666666666665, 'precision': 0.75, 'recall': 0.6, 'support': 10}, '171': {'f1-score': 0.5714285714285714, 'precision': 0.8, 'recall': 0.4444444444444444, 'support': 18}, '172': {'f1-score': 0.8571428571428571, 'precision': 1.0, 'recall': 0.75, 'support': 8}, '173': {'f1-score': 0.631578947368421, 'precision': 0.75, 'recall': 0.5454545454545454, 'support': 11}, '174': {'f1-score': 0.7200000000000001, 'precision': 0.6428571428571429, 'recall': 0.8181818181818182, 'support': 11}, '175': {'f1-score': 0.782608695652174, 'precision': 1.0, 'recall': 0.6428571428571429, 'support': 14}, '176': {'f1-score': 0.7777777777777778, 'precision': 0.6363636363636364, 'recall': 1.0, 'support': 7}, '177': {'f1-score': 0.8235294117647058, 'precision': 1.0, 'recall': 0.7, 'support': 10}, '178': {'f1-score': 0.8666666666666666, 'precision': 0.8125, 'recall': 0.9285714285714286, 'support': 14}, '179': {'f1-score': 0.8461538461538461, 'precision': 0.9166666666666666, 'recall': 0.7857142857142857, 'support': 14}, '18': {'f1-score': 0.6923076923076924, 'precision': 0.6428571428571429, 'recall': 0.75, 'support': 12}, '180': {'f1-score': 0.6666666666666666, 'precision': 1.0, 'recall': 0.5, 'support': 16}, '181': {'f1-score': 0.4761904761904762, 'precision': 0.35714285714285715, 'recall': 0.7142857142857143, 'support': 7}, '182': {'f1-score': 0.9, 'precision': 0.9, 'recall': 0.9, 'support': 10}, '183': {'f1-score': 0.3703703703703704, 'precision': 0.3333333333333333, 'recall': 0.4166666666666667, 'support': 12}, '184': {'f1-score': 0.6153846153846154, 'precision': 0.6153846153846154, 'recall': 0.6153846153846154, 'support': 13}, '185': {'f1-score': 0.3636363636363636, 'precision': 0.4, 'recall': 0.3333333333333333, 'support': 6}, '186': {'f1-score': 0.6896551724137931, 'precision': 0.5882352941176471, 'recall': 0.8333333333333334, 'support': 12}, '187': {'f1-score': 0.8235294117647058, 'precision': 1.0, 'recall': 0.7, 'support': 10}, '188': {'f1-score': 0.7058823529411765, 'precision': 0.6666666666666666, 'recall': 0.75, 'support': 8}, '189': {'f1-score': 0.888888888888889, 'precision': 0.8, 'recall': 1.0, 'support': 4}, '19': {'f1-score': 0.625, 'precision': 0.625, 'recall': 0.625, 'support': 8}, '190': {'f1-score': 0.5263157894736842, 'precision': 0.8333333333333334, 'recall': 0.38461538461538464, 'support': 13}, '191': {'f1-score': 0.8000000000000002, 'precision': 0.8, 'recall': 0.8, 'support': 10}, '192': {'f1-score': 0.8823529411764706, 'precision': 0.8823529411764706, 'recall': 0.8823529411764706, 'support': 17}, '193': {'f1-score': 0.9473684210526316, 'precision': 0.9, 'recall': 1.0, 'support': 9}, '194': {'f1-score': 0.9, 'precision': 0.8181818181818182, 'recall': 1.0, 'support': 9}, '195': {'f1-score': 0.9696969696969697, 'precision': 0.9411764705882353, 'recall': 1.0, 'support': 16}, '196': {'f1-score': 0.6666666666666665, 'precision': 0.8571428571428571, 'recall': 0.5454545454545454, 'support': 11}, '197': {'f1-score': 0.33333333333333326, 'precision': 0.42857142857142855, 'recall': 0.2727272727272727, 'support': 11}, '198': {'f1-score': 0.6250000000000001, 'precision': 0.5555555555555556, 'recall': 0.7142857142857143, 'support': 7}, '199': {'f1-score': 0.5333333333333333, 'precision': 0.4444444444444444, 'recall': 0.6666666666666666, 'support': 6}, '2': {'f1-score': 0.375, 'precision': 0.42857142857142855, 'recall': 0.3333333333333333, 'support': 9}, '20': {'f1-score': 0.9230769230769231, 'precision': 0.9230769230769231, 'recall': 0.9230769230769231, 'support': 13}, '200': {'f1-score': 0.7826086956521738, 'precision': 0.8181818181818182, 'recall': 0.75, 'support': 12}, '201': {'f1-score': 0.9166666666666666, 'precision': 0.9166666666666666, 'recall': 0.9166666666666666, 'support': 12}, '202': {'f1-score': 0.9, 'precision': 0.8181818181818182, 'recall': 1.0, 'support': 9}, '203': {'f1-score': 0.7999999999999999, 'precision': 0.8888888888888888, 'recall': 0.7272727272727273, 'support': 11}, '204': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 3}, '205': {'f1-score': 0.8148148148148148, 'precision': 0.7333333333333333, 'recall': 0.9166666666666666, 'support': 12}, '206': {'f1-score': 0.64, 'precision': 0.6153846153846154, 'recall': 0.6666666666666666, 'support': 12}, '207': {'f1-score': 0.8571428571428571, 'precision': 0.75, 'recall': 1.0, 'support': 3}, '208': {'f1-score': 0.2222222222222222, 'precision': 0.16666666666666666, 'recall': 0.3333333333333333, 'support': 6}, '209': {'f1-score': 0.64, 'precision': 0.5714285714285714, 'recall': 0.7272727272727273, 'support': 11}, '21': {'f1-score': 0.75, 'precision': 0.8571428571428571, 'recall': 0.6666666666666666, 'support': 9}, '210': {'f1-score': 0.6896551724137931, 'precision': 0.5882352941176471, 'recall': 0.8333333333333334, 'support': 12}, '211': {'f1-score': 0.3333333333333333, 'precision': 0.5, 'recall': 0.25, 'support': 4}, '212': {'f1-score': 0.5833333333333334, 'precision': 0.875, 'recall': 0.4375, 'support': 16}, '213': {'f1-score': 0.7999999999999999, 'precision': 0.75, 'recall': 0.8571428571428571, 'support': 7}, '214': {'f1-score': 0.7999999999999999, 'precision': 0.8571428571428571, 'recall': 0.75, 'support': 16}, '215': {'f1-score': 0.5555555555555556, 'precision': 0.7142857142857143, 'recall': 0.45454545454545453, 'support': 11}, '216': {'f1-score': 0.888888888888889, 'precision': 0.9230769230769231, 'recall': 0.8571428571428571, 'support': 14}, '217': {'f1-score': 0.9333333333333333, 'precision': 0.875, 'recall': 1.0, 'support': 7}, '218': {'f1-score': 0.888888888888889, 'precision': 0.9230769230769231, 'recall': 0.8571428571428571, 'support': 14}, '219': {'f1-score': 0.923076923076923, 'precision': 1.0, 'recall': 0.8571428571428571, 'support': 7}, '22': {'f1-score': 0.7333333333333334, 'precision': 0.6470588235294118, 'recall': 0.8461538461538461, 'support': 13}, '220': {'f1-score': 0.7368421052631579, 'precision': 0.5833333333333334, 'recall': 1.0, 'support': 7}, '221': {'f1-score': 0.8695652173913044, 'precision': 1.0, 'recall': 0.7692307692307693, 'support': 13}, '222': {'f1-score': 0.47619047619047616, 'precision': 0.5, 'recall': 0.45454545454545453, 'support': 11}, '223': {'f1-score': 0.8181818181818182, 'precision': 0.9, 'recall': 0.75, 'support': 12}, '224': {'f1-score': 0.9565217391304348, 'precision': 1.0, 'recall': 0.9166666666666666, 'support': 12}, '225': {'f1-score': 0.896551724137931, 'precision': 0.9285714285714286, 'recall': 0.8666666666666667, 'support': 15}, '226': {'f1-score': 0.9411764705882353, 'precision': 1.0, 'recall': 0.8888888888888888, 'support': 9}, '227': {'f1-score': 0.9565217391304348, 'precision': 0.9166666666666666, 'recall': 1.0, 'support': 11}, '228': {'f1-score': 0.7777777777777778, 'precision': 0.7777777777777778, 'recall': 0.7777777777777778, 'support': 9}, '229': {'f1-score': 0.5454545454545454, 'precision': 0.42857142857142855, 'recall': 0.75, 'support': 8}, '23': {'f1-score': 0.6923076923076924, 'precision': 0.6428571428571429, 'recall': 0.75, 'support': 12}, '230': {'f1-score': 0.3157894736842105, 'precision': 0.42857142857142855, 'recall': 0.25, 'support': 12}, '231': {'f1-score': 0.8333333333333333, 'precision': 0.7142857142857143, 'recall': 1.0, 'support': 5}, '232': {'f1-score': 0.8125000000000001, 'precision': 0.7222222222222222, 'recall': 0.9285714285714286, 'support': 14}, '233': {'f1-score': 0.7368421052631579, 'precision': 0.6363636363636364, 'recall': 0.875, 'support': 8}, '234': {'f1-score': 0.6956521739130435, 'precision': 0.6666666666666666, 'recall': 0.7272727272727273, 'support': 11}, '235': {'f1-score': 0.888888888888889, 'precision': 1.0, 'recall': 0.8, 'support': 10}, '236': {'f1-score': 0.6153846153846153, 'precision': 0.6666666666666666, 'recall': 0.5714285714285714, 'support': 7}, '237': {'f1-score': 0.9230769230769231, 'precision': 0.9230769230769231, 'recall': 0.9230769230769231, 'support': 13}, '238': {'f1-score': 0.588235294117647, 'precision': 0.5, 'recall': 0.7142857142857143, 'support': 7}, '239': {'f1-score': 0.8749999999999999, 'precision': 0.8235294117647058, 'recall': 0.9333333333333333, 'support': 15}, '24': {'f1-score': 0.5454545454545454, 'precision': 0.6, 'recall': 0.5, 'support': 12}, '240': {'f1-score': 0.7000000000000001, 'precision': 0.6363636363636364, 'recall': 0.7777777777777778, 'support': 9}, '241': {'f1-score': 0.631578947368421, 'precision': 0.5454545454545454, 'recall': 0.75, 'support': 8}, '242': {'f1-score': 0.923076923076923, 'precision': 0.8571428571428571, 'recall': 1.0, 'support': 6}, '243': {'f1-score': 0.7199999999999999, 'precision': 0.6923076923076923, 'recall': 0.75, 'support': 12}, '244': {'f1-score': 0.8750000000000001, 'precision': 1.0, 'recall': 0.7777777777777778, 'support': 18}, '245': {'f1-score': 0.631578947368421, 'precision': 0.5454545454545454, 'recall': 0.75, 'support': 8}, '246': {'f1-score': 0.923076923076923, 'precision': 1.0, 'recall': 0.8571428571428571, 'support': 7}, '247': {'f1-score': 0.8333333333333333, 'precision': 0.7142857142857143, 'recall': 1.0, 'support': 10}, '248': {'f1-score': 0.588235294117647, 'precision': 0.7142857142857143, 'recall': 0.5, 'support': 10}, '249': {'f1-score': 0.5, 'precision': 0.4444444444444444, 'recall': 0.5714285714285714, 'support': 7}, '25': {'f1-score': 0.3076923076923077, 'precision': 1.0, 'recall': 0.18181818181818182, 'support': 11}, '250': {'f1-score': 0.39999999999999997, 'precision': 0.4444444444444444, 'recall': 0.36363636363636365, 'support': 11}, '251': {'f1-score': 0.7272727272727272, 'precision': 0.6666666666666666, 'recall': 0.8, 'support': 5}, '252': {'f1-score': 0.5882352941176471, 'precision': 0.5555555555555556, 'recall': 0.625, 'support': 8}, '253': {'f1-score': 0.64, 'precision': 0.5714285714285714, 'recall': 0.7272727272727273, 'support': 11}, '254': {'f1-score': 0.8571428571428572, 'precision': 0.9, 'recall': 0.8181818181818182, 'support': 11}, '26': {'f1-score': 0.5714285714285715, 'precision': 0.5, 'recall': 0.6666666666666666, 'support': 6}, '27': {'f1-score': 0.7826086956521738, 'precision': 0.8181818181818182, 'recall': 0.75, 'support': 12}, '28': {'f1-score': 0.42857142857142855, 'precision': 0.5, 'recall': 0.375, 'support': 8}, '29': {'f1-score': 0.5, 'precision': 0.5, 'recall': 0.5, 'support': 4}, '3': {'f1-score': 0.7999999999999999, 'precision': 0.75, 'recall': 0.8571428571428571, 'support': 7}, '30': {'f1-score': 0.7272727272727273, 'precision': 1.0, 'recall': 0.5714285714285714, 'support': 7}, '31': {'f1-score': 0.6086956521739131, 'precision': 0.7777777777777778, 'recall': 0.5, 'support': 14}, '32': {'f1-score': 0.9523809523809523, 'precision': 1.0, 'recall': 0.9090909090909091, 'support': 11}, '33': {'f1-score': 0.64, 'precision': 0.6666666666666666, 'recall': 0.6153846153846154, 'support': 13}, '34': {'f1-score': 0.9600000000000001, 'precision': 0.9230769230769231, 'recall': 1.0, 'support': 12}, '35': {'f1-score': 0.0, 'precision': 0.0, 'recall': 0.0, 'support': 5}, '36': {'f1-score': 0.8181818181818182, 'precision': 0.75, 'recall': 0.9, 'support': 10}, '37': {'f1-score': 0.875, 'precision': 0.875, 'recall': 0.875, 'support': 8}, '38': {'f1-score': 0.4615384615384615, 'precision': 0.42857142857142855, 'recall': 0.5, 'support': 12}, '39': {'f1-score': 0.30303030303030304, 'precision': 0.23809523809523808, 'recall': 0.4166666666666667, 'support': 12}, '4': {'f1-score': 0.7058823529411765, 'precision': 0.75, 'recall': 0.6666666666666666, 'support': 9}, '40': {'f1-score': 0.4615384615384615, 'precision': 0.42857142857142855, 'recall': 0.5, 'support': 6}, '41': {'f1-score': 0.9090909090909091, 'precision': 0.9090909090909091, 'recall': 0.9090909090909091, 'support': 11}, '42': {'f1-score': 0.631578947368421, 'precision': 0.5, 'recall': 0.8571428571428571, 'support': 7}, '43': {'f1-score': 0.7058823529411764, 'precision': 1.0, 'recall': 0.5454545454545454, 'support': 11}, '44': {'f1-score': 0.5882352941176471, 'precision': 0.5555555555555556, 'recall': 0.625, 'support': 8}, '45': {'f1-score': 0.6956521739130435, 'precision': 0.8, 'recall': 0.6153846153846154, 'support': 13}, '46': {'f1-score': 0.72, 'precision': 0.5625, 'recall': 1.0, 'support': 9}, '47': {'f1-score': 0.8000000000000002, 'precision': 0.8, 'recall': 0.8, 'support': 5}, '48': {'f1-score': 0.8235294117647058, 'precision': 1.0, 'recall': 0.7, 'support': 10}, '49': {'f1-score': 0.42105263157894735, 'precision': 0.6666666666666666, 'recall': 0.3076923076923077, 'support': 13}, '5': {'f1-score': 0.4545454545454546, 'precision': 0.38461538461538464, 'recall': 0.5555555555555556, 'support': 9}, '50': {'f1-score': 0.6363636363636364, 'precision': 0.5, 'recall': 0.875, 'support': 8}, '51': {'f1-score': 0.3333333333333333, 'precision': 0.2857142857142857, 'recall': 0.4, 'support': 10}, '52': {'f1-score': 0.6153846153846153, 'precision': 0.5333333333333333, 'recall': 0.7272727272727273, 'support': 11}, '53': {'f1-score': 0.5454545454545455, 'precision': 0.6923076923076923, 'recall': 0.45, 'support': 20}, '54': {'f1-score': 0.7692307692307692, 'precision': 0.8333333333333334, 'recall': 0.7142857142857143, 'support': 7}, '55': {'f1-score': 0.5714285714285714, 'precision': 0.75, 'recall': 0.46153846153846156, 'support': 13}, '56': {'f1-score': 0.6250000000000001, 'precision': 0.5555555555555556, 'recall': 0.7142857142857143, 'support': 7}, '57': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 14}, '58': {'f1-score': 0.36363636363636365, 'precision': 0.6666666666666666, 'recall': 0.25, 'support': 8}, '59': {'f1-score': 0.8421052631578948, 'precision': 0.8, 'recall': 0.8888888888888888, 'support': 9}, '6': {'f1-score': 0.7692307692307693, 'precision': 1.0, 'recall': 0.625, 'support': 8}, '60': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 11}, '61': {'f1-score': 0.5, 'precision': 0.5714285714285714, 'recall': 0.4444444444444444, 'support': 9}, '62': {'f1-score': 0.3333333333333333, 'precision': 0.25, 'recall': 0.5, 'support': 4}, '63': {'f1-score': 0.3636363636363636, 'precision': 0.4, 'recall': 0.3333333333333333, 'support': 6}, '64': {'f1-score': 1.0, 'precision': 1.0, 'recall': 1.0, 'support': 15}, '65': {'f1-score': 0.6250000000000001, 'precision': 0.7142857142857143, 'recall': 0.5555555555555556, 'support': 9}, '66': {'f1-score': 0.27272727272727276, 'precision': 0.2, 'recall': 0.42857142857142855, 'support': 7}, '67': {'f1-score': 0.41666666666666663, 'precision': 0.5, 'recall': 0.35714285714285715, 'support': 14}, '68': {'f1-score': 0.6666666666666666, 'precision': 0.625, 'recall': 0.7142857142857143, 'support': 7}, '69': {'f1-score': 0.631578947368421, 'precision': 0.6666666666666666, 'recall': 0.6, 'support': 10}, '7': {'f1-score': 0.30769230769230765, 'precision': 0.2857142857142857, 'recall': 0.3333333333333333, 'support': 6}, '70': {'f1-score': 0.6666666666666667, 'precision': 0.5882352941176471, 'recall': 0.7692307692307693, 'support': 13}, '71': {'f1-score': 0.6896551724137931, 'precision': 0.7692307692307693, 'recall': 0.625, 'support': 16}, '72': {'f1-score': 0.6153846153846153, 'precision': 1.0, 'recall': 0.4444444444444444, 'support': 9}, '73': {'f1-score': 0.9090909090909091, 'precision': 0.8333333333333334, 'recall': 1.0, 'support': 10}, '74': {'f1-score': 0.9411764705882353, 'precision': 0.9411764705882353, 'recall': 0.9411764705882353, 'support': 17}, '75': {'f1-score': 0.625, 'precision': 0.8333333333333334, 'recall': 0.5, 'support': 10}, '76': {'f1-score': 0.7999999999999999, 'precision': 0.7272727272727273, 'recall': 0.8888888888888888, 'support': 9}, '77': {'f1-score': 0.8333333333333333, 'precision': 1.0, 'recall': 0.7142857142857143, 'support': 7}, '78': {'f1-score': 0.888888888888889, 'precision': 0.8, 'recall': 1.0, 'support': 8}, '79': {'f1-score': 0.7777777777777777, 'precision': 0.875, 'recall': 0.7, 'support': 10}, '8': {'f1-score': 0.5625, 'precision': 0.42857142857142855, 'recall': 0.8181818181818182, 'support': 11}, '80': {'f1-score': 0.5, 'precision': 0.5, 'recall': 0.5, 'support': 4}, '81': {'f1-score': 0.4848484848484849, 'precision': 0.4, 'recall': 0.6153846153846154, 'support': 13}, '82': {'f1-score': 0.7272727272727272, 'precision': 0.6666666666666666, 'recall': 0.8, 'support': 5}, '83': {'f1-score': 0.9, 'precision': 0.9, 'recall': 0.9, 'support': 10}, '84': {'f1-score': 0.5, 'precision': 0.5, 'recall': 0.5, 'support': 10}, '85': {'f1-score': 0.5555555555555556, 'precision': 0.625, 'recall': 0.5, 'support': 10}, '86': {'f1-score': 0.8799999999999999, 'precision': 0.8461538461538461, 'recall': 0.9166666666666666, 'support': 12}, '87': {'f1-score': 0.761904761904762, 'precision': 1.0, 'recall': 0.6153846153846154, 'support': 13}, '88': {'f1-score': 0.9565217391304348, 'precision': 1.0, 'recall': 0.9166666666666666, 'support': 12}, '89': {'f1-score': 0.8000000000000002, 'precision': 0.8, 'recall': 0.8, 'support': 15}, '9': {'f1-score': 0.7272727272727273, 'precision': 0.5714285714285714, 'recall': 1.0, 'support': 8}, '90': {'f1-score': 0.888888888888889, 'precision': 1.0, 'recall': 0.8, 'support': 10}, '91': {'f1-score': 0.45454545454545453, 'precision': 0.5, 'recall': 0.4166666666666667, 'support': 12}, '92': {'f1-score': 0.7000000000000001, 'precision': 0.7777777777777778, 'recall': 0.6363636363636364, 'support': 11}, '93': {'f1-score': 0.64, 'precision': 0.5714285714285714, 'recall': 0.7272727272727273, 'support': 11}, '94': {'f1-score': 0.7000000000000001, 'precision': 0.5384615384615384, 'recall': 1.0, 'support': 7}, '95': {'f1-score': 0.8695652173913044, 'precision': 1.0, 'recall': 0.7692307692307693, 'support': 13}, '96': {'f1-score': 0.5454545454545455, 'precision': 0.6666666666666666, 'recall': 0.46153846153846156, 'support': 13}, '97': {'f1-score': 0.8571428571428572, 'precision': 0.9, 'recall': 0.8181818181818182, 'support': 11}, '98': {'f1-score': 0.7692307692307692, 'precision': 0.8333333333333334, 'recall': 0.7142857142857143, 'support': 7}, '99': {'f1-score': 0.588235294117647, 'precision': 0.5, 'recall': 0.7142857142857143, 'support': 7}, 'accuracy': 0.6964705882352941, 'macro avg': {'f1-score': 0.6807135878926064, 'precision': 0.7063880901806598, 'recall': 0.6898249111215784, 'support': 2550}, 'weighted avg': {'f1-score': 0.6956667409596368, 'precision': 0.7288180840167273, 'recall': 0.6964705882352941, 'support': 2550}}
# Create empty dictionary
class_f1_scores = {}
# Loop through classification report items
for k, v in classification_report_dict.items():
if k == "accuracy": # stop once we get to accuracy key
break
else:
# Append class names and f1-scores to new dictionary
class_f1_scores[classes[int(k)]] = v["f1-score"]
class_f1_scores
{'abiu': 0.5882352941176471, 'acai': 0.5714285714285714, 'acerola': 0.375, 'ackee': 0.7999999999999999, 'alligator apple': 0.7058823529411765, 'ambarella': 0.4545454545454546, 'apple': 0.7692307692307693, 'apricot': 0.30769230769230765, 'araza': 0.5625, 'avocado': 0.7272727272727273, 'bael': 0.6666666666666666, 'banana': 1.0, 'barbadine': 0.5263157894736842, 'barberry': 0.8571428571428572, 'bayberry': 0.823529411764706, 'beach plum': 0.5945945945945946, 'bearberry': 0.6666666666666667, 'bell pepper': 0.9411764705882353, 'betel nut': 0.6923076923076924, 'bignay': 0.625, 'bilimbi': 0.9230769230769231, 'bitter gourd': 0.75, 'black berry': 0.7333333333333334, 'black cherry': 0.6923076923076924, 'black currant': 0.5454545454545454, 'black mullberry': 0.3076923076923077, 'black sapote': 0.5714285714285715, 'blueberry': 0.7826086956521738, 'bolwarra': 0.42857142857142855, 'bottle gourd': 0.5, 'brazil nut': 0.7272727272727273, 'bread fruit': 0.6086956521739131, "buddha's hand": 0.9523809523809523, 'buffaloberry': 0.64, 'burdekin plum': 0.9600000000000001, 'burmese grape': 0.0, 'caimito': 0.8181818181818182, 'camu camu': 0.875, 'canistel': 0.4615384615384615, 'cantaloupe': 0.30303030303030304, 'cape gooseberry': 0.4615384615384615, 'carambola': 0.9090909090909091, 'cardon': 0.631578947368421, 'cashew': 0.7058823529411764, 'cedar bay cherry': 0.5882352941176471, 'cempedak': 0.6956521739130435, 'ceylon gooseberry': 0.72, 'che': 0.8000000000000002, 'chenet': 0.8235294117647058, 'cherimoya': 0.42105263157894735, 'cherry': 0.6363636363636364, 'chico': 0.3333333333333333, 'chokeberry': 0.6153846153846153, 'clementine': 0.5454545454545455, 'cloudberry': 0.7692307692307692, 'cluster fig': 0.5714285714285714, 'cocoa bean': 0.6250000000000001, 'coconut': 1.0, 'coffee': 0.36363636363636365, 'common buckthorn': 0.8421052631578948, 'corn kernel': 1.0, 'cornelian cherry': 0.5, 'crab apple': 0.3333333333333333, 'cranberry': 0.3636363636363636, 'crowberry': 1.0, 'cupuacu': 0.6250000000000001, 'custard apple': 0.27272727272727276, 'damson': 0.41666666666666663, 'date': 0.6666666666666666, 'desert fig': 0.631578947368421, 'desert lime': 0.6666666666666667, 'dewberry': 0.6896551724137931, 'dragonfruit': 0.6153846153846153, 'durian': 0.9090909090909091, 'eggplant': 0.9411764705882353, 'elderberry': 0.625, 'elephant apple': 0.7999999999999999, 'emblic': 0.8333333333333333, 'entawak': 0.888888888888889, 'etrog': 0.7777777777777777, 'feijoa': 0.5, 'fibrous satinash': 0.4848484848484849, 'fig': 0.7272727272727272, 'finger lime': 0.9, 'galia melon': 0.5, 'gandaria': 0.5555555555555556, 'genipap': 0.8799999999999999, 'goji': 0.761904761904762, 'gooseberry': 0.9565217391304348, 'goumi': 0.8000000000000002, 'grape': 0.888888888888889, 'grapefruit': 0.45454545454545453, 'greengage': 0.7000000000000001, 'grenadilla': 0.64, 'guanabana': 0.7000000000000001, 'guarana': 0.8695652173913044, 'guava': 0.5454545454545455, 'guavaberry': 0.8571428571428572, 'hackberry': 0.7692307692307692, 'hard kiwi': 0.588235294117647, 'hawthorn': 0.5714285714285714, 'hog plum': 0.28571428571428575, 'honeyberry': 0.888888888888889, 'honeysuckle': 0.7407407407407408, 'horned melon': 1.0, 'illawarra plum': 0.9285714285714286, 'indian almond': 0.16666666666666666, 'indian strawberry': 0.0, 'ita palm': 0.8235294117647058, 'jaboticaba': 0.7000000000000001, 'jackfruit': 0.8235294117647058, 'jalapeno': 0.8571428571428571, 'jamaica cherry': 0.5714285714285715, 'jambul': 0.5, 'japanese raisin': 0.9090909090909091, 'jasmine': 0.7000000000000001, 'jatoba': 0.625, 'jocote': 0.4444444444444444, 'jostaberry': 0.875, 'jujube': 0.588235294117647, 'juniper berry': 0.7777777777777777, 'kaffir lime': 0.7999999999999999, 'kahikatea': 0.9411764705882353, 'kakadu plum': 0.6363636363636364, 'keppel': 0.888888888888889, 'kiwi': 0.6250000000000001, 'kumquat': 0.4444444444444444, 'kundong': 0.75, 'kutjera': 0.7826086956521738, 'lablab': 0.9333333333333333, 'langsat': 0.6666666666666666, 'lapsi': 0.625, 'lemon': 0.4761904761904762, 'lemon aspen': 0.7777777777777777, 'leucaena': 0.88, 'lillipilli': 0.12500000000000003, 'lime': 0.14285714285714288, 'lingonberry': 0.4444444444444444, 'loganberry': 0.631578947368421, 'longan': 0.5714285714285713, 'loquat': 0.7999999999999999, 'lucuma': 0.3846153846153846, 'lulo': 0.28571428571428575, 'lychee': 0.6666666666666666, 'mabolo': 0.761904761904762, 'macadamia': 0.22222222222222224, 'malay apple': 0.35294117647058826, 'mamey apple': 0.6363636363636364, 'mandarine': 0.4210526315789474, 'mango': 0.3333333333333333, 'mangosteen': 0.888888888888889, 'manila tamarind': 0.9166666666666666, 'marang': 0.9473684210526316, 'mayhaw': 0.5882352941176471, 'maypop': 0.7, 'medlar': 0.6875000000000001, 'melinjo': 0.8888888888888888, 'melon pear': 0.8571428571428571, 'midyim': 0.9333333333333333, 'miracle fruit': 0.6956521739130435, 'mock strawberry': 0.5333333333333333, 'monkfruit': 0.8421052631578948, 'monstera deliciosa': 0.9411764705882353, 'morinda': 0.9, 'mountain papaya': 0.6666666666666667, 'mountain soursop': 0.28571428571428575, 'mundu': 0.5454545454545454, 'muskmelon': 0.37037037037037035, 'myrtle': 0.8333333333333333, 'nance': 0.25, 'nannyberry': 0.6666666666666665, 'naranjilla': 0.5714285714285714, 'native cherry': 0.8571428571428571, 'native gooseberry': 0.631578947368421, 'nectarine': 0.7200000000000001, 'neem': 0.782608695652174, 'nungu': 0.7777777777777778, 'nutmeg': 0.8235294117647058, 'oil palm': 0.8666666666666666, 'old world sycomore': 0.8461538461538461, 'olive': 0.6666666666666666, 'orange': 0.4761904761904762, 'oregon grape': 0.9, 'otaheite apple': 0.3703703703703704, 'papaya': 0.6153846153846154, 'passion fruit': 0.3636363636363636, 'pawpaw': 0.6896551724137931, 'pea': 0.8235294117647058, 'peanut': 0.7058823529411765, 'pear': 0.888888888888889, 'pequi': 0.5263157894736842, 'persimmon': 0.8000000000000002, 'pigeon plum': 0.8823529411764706, 'pili nut': 0.9473684210526316, 'pineapple': 0.9, 'pineberry': 0.9696969696969697, 'pitomba': 0.6666666666666665, 'plumcot': 0.33333333333333326, 'pomegranate': 0.6250000000000001, 'pomelo': 0.5333333333333333, 'prikly pear': 0.7826086956521738, 'pulasan': 0.9166666666666666, 'pumpkin': 0.9, 'pupunha': 0.7999999999999999, 'purple apple berry': 1.0, 'quandong': 0.8148148148148148, 'quince': 0.64, 'rambutan': 0.8571428571428571, 'rangpur': 0.2222222222222222, 'raspberry': 0.64, 'red mulberry': 0.6896551724137931, 'redcurrant': 0.3333333333333333, 'riberry': 0.5833333333333334, 'ridged gourd': 0.7999999999999999, 'rose hip': 0.7999999999999999, 'rose-leaf bramble': 0.5555555555555556, 'saguaro': 0.888888888888889, 'salak': 0.9333333333333333, 'salal': 0.888888888888889, 'salmonberry': 0.923076923076923, 'sandpaper fig': 0.7368421052631579, 'santol': 0.8695652173913044, 'sapodilla': 0.47619047619047616, 'saskatoon': 0.8181818181818182, 'sea buckthorn': 0.9565217391304348, 'sea grape': 0.896551724137931, 'snowberry': 0.9411764705882353, 'soncoya': 0.9565217391304348, 'strawberry': 0.7777777777777778, 'strawberry guava': 0.5454545454545454, 'sugar apple': 0.3157894736842105, 'surinam cherry': 0.8333333333333333, 'sycamore fig': 0.8125000000000001, 'tamarillo': 0.7368421052631579, 'tangelo': 0.6956521739130435, 'taxus baccata': 0.888888888888889, 'tayberry': 0.6153846153846153, 'texas persimmon': 0.9230769230769231, 'thimbleberry': 0.588235294117647, 'tomato': 0.8749999999999999, 'toyon': 0.7000000000000001, 'ugli fruit': 0.631578947368421, 'vanilla': 0.923076923076923, 'velvet tamarind': 0.7199999999999999, 'watermelon': 0.8750000000000001, 'wax gourd': 0.631578947368421, 'white currant': 0.923076923076923, 'white mulberry': 0.8333333333333333, 'white sapote': 0.588235294117647, 'wineberry': 0.5, 'wongi': 0.39999999999999997, 'yali pear': 0.7272727272727272, 'yellow plum': 0.5882352941176471, 'yuzu': 0.64, 'zucchini': 0.8571428571428572}
# Turn f1-scores into dataframe for visualization
f1_scores = pd.DataFrame({"class_name": list(class_f1_scores.keys()),
"f1-score": list(class_f1_scores.values())}).sort_values("f1-score", ascending=False)
f1_scores
class_name | f1-score | |
---|---|---|
64 | crowberry | 1.000000 |
11 | banana | 1.000000 |
104 | horned melon | 1.000000 |
60 | corn kernel | 1.000000 |
57 | coconut | 1.000000 |
... | ... | ... |
106 | indian almond | 0.166667 |
136 | lime | 0.142857 |
135 | lillipilli | 0.125000 |
35 | burmese grape | 0.000000 |
107 | indian strawberry | 0.000000 |
255 rows × 2 columns
F1 scores¶
fig, ax = plt.subplots(figsize=(100, 100))
scores = ax.barh(range(len(f1_scores)), f1_scores["f1-score"].values)
ax.set_yticks(range(len(f1_scores)))
ax.set_yticklabels(list(f1_scores["class_name"]))
ax.set_xlabel("f1-score")
ax.set_title("F1-Scores for 10 Different Classes")
ax.invert_yaxis(); # reverse the order
def autolabel(rects): # Modified version of: https://matplotlib.org/examples/api/barchart_demo.html
"""
Attach a text label above each bar displaying its height (it's value).
"""
for rect in rects:
width = rect.get_width()
ax.text(1.03*width, rect.get_y() + rect.get_height()/1.5,
f"{width:.2f}",
ha='center', va='bottom')
autolabel(scores)
Visualizing the wrong predictions¶
def load_and_prep_image(filename, img_shape=224, scale=True):
"""
Reads in an image from filename, turns it into a tensor and reshapes into
(224, 224, 3).
Parameters
----------
filename (str): string filename of target image
img_shape (int): size to resize target image to, default 224
scale (bool): whether to scale pixel values to range(0, 1), default True
"""
# Read in the image
img = tf.io.read_file(filename)
# Decode it into a tensor
img = tf.io.decode_image(img)
# Resize the image
img = tf.image.resize(img, [img_shape, img_shape])
if scale:
# Rescale the image (get all values between 0 and 1)
return img/255.
else:
return img
# Make preds on a series of random images
plt.figure(figsize=(17, 10))
for i in range(3):
# Choose a random image from a random class
files = pd.unique(test_df["filepaths"])
filepath = random.choice(files)
filepath_s = filepath
filepath_s = filepath_s[19:]
class_name = filepath_s.split("/")[0]
# Load the image and make predictions
img = load_and_prep_image(filepath, scale=False) # don't scale images for EfficientNet predictions
pred_prob = model_load.predict(tf.expand_dims(img, axis=0)) # model accepts tensors of shape [None, 224, 224, 3]
pred_class = classes[pred_prob.argmax()] # find the predicted class
# Plot the image(s)
plt.subplot(1, 3, i+1)
plt.imshow(img/255.)
if class_name == pred_class: # Change the color of text based on whether prediction is right or wrong
title_color = "g"
else:
title_color = "r"
plt.title(f"actual: {class_name}, pred: {pred_class}, prob: {pred_prob.max():.2f}", c=title_color)
plt.axis(False);
# 1. Get the filenames of all of our test data
filepaths = []
for filepath in test_df["filepaths"]:
filepaths.append(filepath)
filepaths[:10]
['/content/Fruit-262/salal/332.jpg', '/content/Fruit-262/black mullberry/845.jpg', '/content/Fruit-262/mountain papaya/542.jpg', '/content/Fruit-262/ugli fruit/732.jpg', '/content/Fruit-262/salal/90.jpg', '/content/Fruit-262/guanabana/989.jpg', '/content/Fruit-262/abiu/1149.jpg', '/content/Fruit-262/pupunha/880.jpg', '/content/Fruit-262/oregon grape/64.jpg', '/content/Fruit-262/jamaica cherry/18.jpg']
# 2. Create a dataframe out of current prediction data for analysis
pred_df = pd.DataFrame({"img_path": filepaths,
"y_true": true,
"y_pred": preds,
"pred_conf": pred_probs.max(axis=1), # get the maximum prediction probability value
"y_true_classname": [classes[i] for i in true],
"y_pred_classname": [classes[i] for i in tf.squeeze(preds).numpy()]})
pred_df.head()
img_path | y_true | y_pred | pred_conf | y_true_classname | y_pred_classname | |
---|---|---|---|---|---|---|
0 | /content/Fruit-262/salal/332.jpg | 218 | 218 | 0.999999 | salal | salal |
1 | /content/Fruit-262/black mullberry/845.jpg | 25 | 210 | 0.496596 | black mullberry | red mulberry |
2 | /content/Fruit-262/mountain papaya/542.jpg | 164 | 164 | 0.993078 | mountain papaya | mountain papaya |
3 | /content/Fruit-262/ugli fruit/732.jpg | 241 | 148 | 0.445772 | ugli fruit | mandarine |
4 | /content/Fruit-262/salal/90.jpg | 218 | 218 | 0.997375 | salal | salal |
# 3. Is the prediction correct?
pred_df["pred_correct"] = pred_df["y_true"] == pred_df["y_pred"]
pred_df.head()
img_path | y_true | y_pred | pred_conf | y_true_classname | y_pred_classname | pred_correct | |
---|---|---|---|---|---|---|---|
0 | /content/Fruit-262/salal/332.jpg | 218 | 218 | 0.999999 | salal | salal | True |
1 | /content/Fruit-262/black mullberry/845.jpg | 25 | 210 | 0.496596 | black mullberry | red mulberry | False |
2 | /content/Fruit-262/mountain papaya/542.jpg | 164 | 164 | 0.993078 | mountain papaya | mountain papaya | True |
3 | /content/Fruit-262/ugli fruit/732.jpg | 241 | 148 | 0.445772 | ugli fruit | mandarine | False |
4 | /content/Fruit-262/salal/90.jpg | 218 | 218 | 0.997375 | salal | salal | True |
# 4. Get the top 100 wrong examples
top_100_wrong = pred_df[pred_df["pred_correct"] == False].sort_values("pred_conf", ascending=False)[:100]
top_100_wrong.head(20)
img_path | y_true | y_pred | pred_conf | y_true_classname | y_pred_classname | pred_correct | |
---|---|---|---|---|---|---|---|
497 | /content/Fruit-262/mabolo/514.jpg | 144 | 202 | 0.999999 | mabolo | pumpkin | False |
134 | /content/Fruit-262/passion fruit/978.jpg | 185 | 154 | 0.999998 | passion fruit | maypop | False |
1327 | /content/Fruit-262/barbadine/506.jpg | 12 | 93 | 0.999994 | barbadine | grenadilla | False |
750 | /content/Fruit-262/lime/524.jpg | 136 | 121 | 0.999991 | lime | kaffir lime | False |
1657 | /content/Fruit-262/pequi/127.jpg | 190 | 176 | 0.999977 | pequi | nungu | False |
1062 | /content/Fruit-262/damson/781.jpg | 67 | 15 | 0.999966 | damson | beach plum | False |
2340 | /content/Fruit-262/pitomba/93.jpg | 196 | 139 | 0.999961 | pitomba | longan | False |
2532 | /content/Fruit-262/lablab/785.jpg | 129 | 134 | 0.999918 | lablab | leucaena | False |
1712 | /content/Fruit-262/rose-leaf bramble/195.jpg | 215 | 238 | 0.999911 | rose-leaf bramble | thimbleberry | False |
197 | /content/Fruit-262/olive/297.jpg | 180 | 205 | 0.999762 | olive | quandong | False |
960 | /content/Fruit-262/muskmelon/523.jpg | 167 | 39 | 0.999739 | muskmelon | cantaloupe | False |
1092 | /content/Fruit-262/barbadine/349.jpg | 12 | 93 | 0.999657 | barbadine | grenadilla | False |
154 | /content/Fruit-262/damson/851.jpg | 67 | 27 | 0.999516 | damson | blueberry | False |
300 | /content/Fruit-262/plumcot/524.jpg | 197 | 51 | 0.999475 | plumcot | chico | False |
1737 | /content/Fruit-262/damson/821.jpg | 67 | 176 | 0.999254 | damson | nungu | False |
1286 | /content/Fruit-262/lucuma/941.jpg | 141 | 38 | 0.999191 | lucuma | canistel | False |
2275 | /content/Fruit-262/hackberry/492.jpg | 98 | 59 | 0.999090 | hackberry | common buckthorn | False |
777 | /content/Fruit-262/muskmelon/160.jpg | 167 | 39 | 0.999036 | muskmelon | cantaloupe | False |
605 | /content/Fruit-262/barbadine/293.jpg | 12 | 93 | 0.998957 | barbadine | grenadilla | False |
2355 | /content/Fruit-262/muskmelon/760.jpg | 167 | 39 | 0.998953 | muskmelon | cantaloupe | False |
# 5. Visualize some of the most wrong examples
images_to_view = 9
start_index = 30 # change the start index to view more
plt.figure(figsize=(15, 10))
for i, row in enumerate(top_100_wrong[start_index:start_index+images_to_view].itertuples()):
plt.subplot(3, 3, i+1)
img = load_and_prep_image(row[1], scale=True)
_, _, _, _, pred_prob, y_true, y_pred, _ = row # only interested in a few parameters of each row
plt.imshow(img)
plt.title(f"actual: {y_true}, pred: {y_pred} \nprob: {pred_prob:.2f}", color="red")
plt.axis(False)