Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Project Addition]: Butterfly Classification using DL - with Web App #570

Closed
106 changes: 106 additions & 0 deletions Butterfly Species Classification using DL/Dataset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Dataset
The dataset contains individual folder for 100 species of butterfly, the species are :
1. ADONIS
2. AFRICAN GIANT SWALLOWTAIL
3. AMERICAN SNOOT
4. AN 88
5. APPOLLO
6. ARCIGERA FLOWER MOTH
7. ATALA
8. ATLAS MOTH
9. BANDED ORANGE HELICONIAN
10. BANDED PEACOCK
11. BANDED TIGER MOTH
12. BECKERS WHITE
13. BIRD CHERRY ERMINE MOTH
14. BLACK HAIRSTREAK
15. BLUE MORPHO
16. BLUE SPOTTED CROW
17. BROOKES BIRDWING
18. BROWN ARGUS
19. BROWN SIPROETA
20. CABBAGE WHITE
21. CAIRNS BIRDWING
22. CHALK HILL BLUE
23. CHECQUERED SKIPPER
24. CHESTNUT
25. CINNABAR MOTH
26. CLEARWING MOTH
27. CLEOPATRA
28. CLODIUS PARNASSIAN
29. CLOUDED SULPHUR
30. COMET MOTH
31. COMMON BANDED AWL
32. COMMON WOOD-NYMPH
33. COPPER TAIL
34. CRECENT
35. CRIMSON PATCH
36. DANAID EGGFLY
37. EASTERN COMA
38. EASTERN DAPPLE WHITE
39. EASTERN PINE ELFIN
40. ELBOWED PIERROT
41. EMPEROR GUM MOTH
42. GARDEN TIGER MOTH
43. GIANT LEOPARD MOTH
44. GLITTERING SAPPHIRE
45. GOLD BANDED
46. GREAT EGGFLY
47. GREAT JAY
48. GREEN CELLED CATTLEHEART
49. GREEN HAIRSTREAK
50. GREY HAIRSTREAK
51. HERCULES MOTH
52. HUMMING BIRD HAWK MOTH
53. INDRA SWALLOW
54. IO MOTH
55. Iphiclus sister
56. JULIA
57. LARGE MARBLE
58. LUNA MOTH
59. MADAGASCAN SUNSET MOTH
60. MALACHITE
61. MANGROVE SKIPPER
62. MESTRA
63. METALMARK
64. MILBERTS TORTOISESHELL
65. MONARCH
66. MOURNING CLOAK
67. OLEANDER HAWK MOTH
68. ORANGE OAKLEAF
69. ORANGE TIP
70. ORCHARD SWALLOW
71. PAINTED LADY
72. PAPER KITE
73. PEACOCK
74. PINE WHITE
75. PIPEVINE SWALLOW
76. POLYPHEMUS MOTH
77. POPINJAY
78. PURPLE HAIRSTREAK
79. PURPLISH COPPER
80. QUESTION MARK
81. RED ADMIRAL
82. RED CRACKER
83. RED POSTMAN
84. RED SPOTTED PURPLE
85. ROSY MAPLE MOTH
86. SCARCE SWALLOW
87. SILVER SPOT SKIPPER
88. SIXSPOT BURNET MOTH
89. SLEEPY ORANGE
90. SOOTYWING
91. SOUTHERN DOGFACE
92. STRAITED QUEEN
93. TROPICAL LEAFWING
94. TWO BARRED FLASHER
95. ULYSES
96. VICEROY
97. WHITE LINED SPHINX MOTH
98. WOOD SATYR
99. YELLOW SWALLOW TAIL
100. ZEBRA LONG WING


Link to dataset : https://www.kaggle.com/datasets/gpiosenka/butterfly-images40-species

63 changes: 63 additions & 0 deletions Butterfly Species Classification using DL/Model/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
training_set = train_datagen.flow_from_directory('dataset/train',
target_size = (64, 64),
batch_size = 30,
class_mode = 'categorical')
test_datagen = ImageDataGenerator(rescale = 1./255)
test_set = test_datagen.flow_from_directory('dataset/test',
target_size = (64, 64),
batch_size = 30,
class_mode = 'categorical')
# LeNet-5 architecture
lenet = tf.keras.models.Sequential()

# Layer 1: Convolutional layer with 6 filters, kernel size 5x5, and ReLU activation
lenet.add(tf.keras.layers.Conv2D(filters=6, kernel_size=5, activation='relu', input_shape=[64, 64, 3]))

# Layer 2: Average pooling layer with pool size 2x2 and strides 2
lenet.add(tf.keras.layers.AveragePooling2D(pool_size=2, strides=2))

# Layer 3: Convolutional layer with 16 filters, kernel size 5x5, and ReLU activation
lenet.add(tf.keras.layers.Conv2D(filters=16, kernel_size=5, activation='relu'))

# Layer 4: Average pooling layer with pool size 2x2 and strides 2
lenet.add(tf.keras.layers.AveragePooling2D(pool_size=2, strides=2))

# Layer 5: Flatten layer
lenet.add(tf.keras.layers.Flatten())

# Layer 6: Fully connected layer with 120 units and ReLU activation
lenet.add(tf.keras.layers.Dense(units=120, activation='relu'))

# Layer 7: Fully connected layer with 84 units and ReLU activation
lenet.add(tf.keras.layers.Dense(units=84, activation='relu'))

# Layer 8: Output layer with 46 units (assuming it's the number of classes) and softmax activation
lenet.add(tf.keras.layers.Dense(units=100, activation='softmax'))

# Compile the model with Adam optimizer and categorical crossentropy loss
lenet.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

lenet.fit(x = training_set, validation_data = test_set, epochs = 15)

# Part 4 - Making a single prediction
print(training_set.class_indices)
import numpy as np
from keras.preprocessing import image
if uploaded_file is not None:
try:
class_indices = {'ADONIS': 0, 'AFRICAN GIANT SWALLOWTAIL': 1, 'AMERICAN SNOOT': 2, 'AN 88': 3, 'APPOLLO': 4, 'ARCIGERA FLOWER MOTH': 5, 'ATALA': 6, 'ATLAS MOTH': 7, 'BANDED ORANGE HELICONIAN': 8, 'BANDED PEACOCK': 9, 'BANDED TIGER MOTH': 10, 'BECKERS WHITE': 11, 'BIRD CHERRY ERMINE MOTH': 12, 'BLACK HAIRSTREAK': 13, 'BLUE MORPHO': 14, 'BLUE SPOTTED CROW': 15, 'BROOKES BIRDWING': 16, 'BROWN ARGUS': 17, 'BROWN SIPROETA': 18, 'CABBAGE WHITE': 19, 'CAIRNS BIRDWING': 20, 'CHALK HILL BLUE': 21, 'CHECQUERED SKIPPER': 22, 'CHESTNUT': 23, 'CINNABAR MOTH': 24, 'CLEARWING MOTH': 25, 'CLEOPATRA': 26, 'CLODIUS PARNASSIAN': 27, 'CLOUDED SULPHUR': 28, 'COMET MOTH': 29, 'COMMON BANDED AWL': 30, 'COMMON WOOD-NYMPH': 31, 'COPPER TAIL': 32, 'CRECENT': 33, 'CRIMSON PATCH': 34, 'DANAID EGGFLY': 35, 'EASTERN COMA': 36, 'EASTERN DAPPLE WHITE': 37, 'EASTERN PINE ELFIN': 38, 'ELBOWED PIERROT': 39, 'EMPEROR GUM MOTH': 40, 'GARDEN TIGER MOTH': 41, 'GIANT LEOPARD MOTH': 42, 'GLITTERING SAPPHIRE': 43, 'GOLD BANDED': 44, 'GREAT EGGFLY': 45, 'GREAT JAY': 46, 'GREEN CELLED CATTLEHEART': 47, 'GREEN HAIRSTREAK': 48, 'GREY HAIRSTREAK': 49, 'HERCULES MOTH': 50, 'HUMMING BIRD HAWK MOTH': 51, 'INDRA SWALLOW': 52, 'IO MOTH': 53, 'Iphiclus sister': 54, 'JULIA': 55, 'LARGE MARBLE': 56, 'LUNA MOTH': 57, 'MADAGASCAN SUNSET MOTH': 58, 'MALACHITE': 59, 'MANGROVE SKIPPER': 60, 'MESTRA': 61, 'METALMARK': 62, 'MILBERTS TORTOISESHELL': 63, 'MONARCH': 64, 'MOURNING CLOAK': 65, 'OLEANDER HAWK MOTH': 66, 'ORANGE OAKLEAF': 67, 'ORANGE TIP': 68, 'ORCHARD SWALLOW': 69, 'PAINTED LADY': 70, 'PAPER KITE': 71, 'PEACOCK': 72, 'PINE WHITE': 73, 'PIPEVINE SWALLOW': 74, 'POLYPHEMUS MOTH': 75, 'POPINJAY': 76, 'PURPLE HAIRSTREAK': 77, 'PURPLISH COPPER': 78, 'QUESTION MARK': 79, 'RED ADMIRAL': 80, 'RED CRACKER': 81, 'RED POSTMAN': 82, 'RED SPOTTED PURPLE': 83, 'ROSY MAPLE MOTH': 84, 'SCARCE SWALLOW': 85, 'SILVER SPOT SKIPPER': 86, 'SIXSPOT BURNET MOTH': 87, 'SLEEPY ORANGE': 88, 'SOOTYWING': 89, 'SOUTHERN DOGFACE': 90, 'STRAITED QUEEN': 91, 'TROPICAL LEAFWING': 92, 'TWO BARRED FLASHER': 93, 'ULYSES': 94, 'VICEROY': 95, 'WHITE LINED SPHINX MOTH': 96, 'WOOD SATYR': 97, 'YELLOW SWALLOW TAIL': 98, 'ZEBRA LONG WING': 99}
test_image = image.load_img(uploaded_file, target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = lenet.predict(test_image)
prediction = lenet.predict(test_image)
predicted_class_index = np.argmax(prediction)
predicted_class_name = [key for key, value in class_indices.items() if value == predicted_class_index][0]

print(predicted_class_index)
40 changes: 40 additions & 0 deletions Butterfly Species Classification using DL/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Hindi Letter Classification

## Introduction

Butterfly diversity is essential for ecosystem health and stability. However, manual classification of butterfly species can be time-consuming and prone to errors. An automated system using deep learning can expedite this process, providing a valuable tool for researchers, conservationists, and butterfly enthusiasts.

![Alt text](https://i.pinimg.com/736x/b9/d6/83/b9d683dd495a0aaeb80d5b3ab7c156f0.jpg "Butterfly Species")

## Web Application

Butterfly species classification is a challenging task due to the diverse appearances and intricate patterns of butterflies. Accurate classification aids in biodiversity studies, conservation efforts, and ecological research. This project proposes a Convolutional Neural Network (CNN) approach utilizing the LeNet-5 architecture for automated butterfly species classification. The model demonstrates promising accuracy in distinguishing among 100 different butterfly species, facilitating researchers and enthusiasts in identifying and studying butterflies.

## Libraries used

1. Numpy
2. Keras
3. Tensorflow
4. Streamlit

# Dataset

Link : https://www.kaggle.com/datasets/gpiosenka/butterfly-images40-species

# How to run locally

Install the necessary libraries using pip then
open the project folder and
run following command :

```python

streamlit run file_name.py

```

# Snapshots

![Alt text](https://i.postimg.cc/mrPdbPyH/Screenshot-2024-05-15-175311.png "Snapshot 1")
![Alt text](https://i.postimg.cc/q7Ht7Y8x/Screenshot-2024-05-15-175340.png "Snapshot 2")
![Alt text](https://i.postimg.cc/CLZdsY74/Screenshot-2024-05-15-175356.png "Snapshot 3")
95 changes: 95 additions & 0 deletions Butterfly Species Classification using DL/Web app/web_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import streamlit as st

st.title("Butterfly Species classification 🦋")
st.divider()
st.image("https://i.postimg.cc/T1YP6Nr7/s-l1200.jpg")
st.subheader("More about Butterflies")
st.write('''
Butterflies 🦋 are nature's delicate dancers, fluttering gracefully through sunlit meadows and vibrant gardens. With their kaleidoscope of colors and gentle wings, they bring joy and wonder wherever they go. Their metamorphosis from tiny caterpillars to exquisite winged beauties symbolizes transformation and growth 🌱. Watching them flit from flower to flower is a reminder to embrace change and find beauty in every stage of life. 🌸✨''')
st.divider()
st.subheader("Introduction")
st.write('''
The web app is created using streamlit framework. It contains a heading, small introduction and then a image uploader.
After the user uploads image, the image goes to backend and respected class is predicted by the CNN model and then
the uploaded image along with prediction is showed. We can play with prediciton time and accuracy by changing batch_size,
number of epochs and using a different CNN architecture.

''')
st.divider()
uploaded_file = st.file_uploader("Enter image to Predict", type=['png', 'jpg'])
submit = st.button("Submit")
st.write("It may take 2-3 minutes to predict the image")
if submit:
if uploaded_file is not None:

import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
training_set = train_datagen.flow_from_directory('dataset/train',
target_size = (64, 64),
batch_size = 30,
class_mode = 'categorical')
test_datagen = ImageDataGenerator(rescale = 1./255)
test_set = test_datagen.flow_from_directory('dataset/test',
target_size = (64, 64),
batch_size = 30,
class_mode = 'categorical')
# LeNet-5 architecture
lenet = tf.keras.models.Sequential()

# Layer 1: Convolutional layer with 6 filters, kernel size 5x5, and ReLU activation
lenet.add(tf.keras.layers.Conv2D(filters=6, kernel_size=5, activation='relu', input_shape=[64, 64, 3]))

# Layer 2: Average pooling layer with pool size 2x2 and strides 2
lenet.add(tf.keras.layers.AveragePooling2D(pool_size=2, strides=2))

# Layer 3: Convolutional layer with 16 filters, kernel size 5x5, and ReLU activation
lenet.add(tf.keras.layers.Conv2D(filters=16, kernel_size=5, activation='relu'))

# Layer 4: Average pooling layer with pool size 2x2 and strides 2
lenet.add(tf.keras.layers.AveragePooling2D(pool_size=2, strides=2))

# Layer 5: Flatten layer
lenet.add(tf.keras.layers.Flatten())

# Layer 6: Fully connected layer with 120 units and ReLU activation
lenet.add(tf.keras.layers.Dense(units=120, activation='relu'))

# Layer 7: Fully connected layer with 84 units and ReLU activation
lenet.add(tf.keras.layers.Dense(units=84, activation='relu'))

# Layer 8: Output layer with 46 units (assuming it's the number of classes) and softmax activation
lenet.add(tf.keras.layers.Dense(units=100, activation='softmax'))

# Compile the model with Adam optimizer and categorical crossentropy loss
lenet.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

lenet.fit(x = training_set, validation_data = test_set, epochs = 15)

# Part 4 - Making a single prediction
print(training_set.class_indices)
import numpy as np
from keras.preprocessing import image
if uploaded_file is not None:
try:
class_indices = {'ADONIS': 0, 'AFRICAN GIANT SWALLOWTAIL': 1, 'AMERICAN SNOOT': 2, 'AN 88': 3, 'APPOLLO': 4, 'ARCIGERA FLOWER MOTH': 5, 'ATALA': 6, 'ATLAS MOTH': 7, 'BANDED ORANGE HELICONIAN': 8, 'BANDED PEACOCK': 9, 'BANDED TIGER MOTH': 10, 'BECKERS WHITE': 11, 'BIRD CHERRY ERMINE MOTH': 12, 'BLACK HAIRSTREAK': 13, 'BLUE MORPHO': 14, 'BLUE SPOTTED CROW': 15, 'BROOKES BIRDWING': 16, 'BROWN ARGUS': 17, 'BROWN SIPROETA': 18, 'CABBAGE WHITE': 19, 'CAIRNS BIRDWING': 20, 'CHALK HILL BLUE': 21, 'CHECQUERED SKIPPER': 22, 'CHESTNUT': 23, 'CINNABAR MOTH': 24, 'CLEARWING MOTH': 25, 'CLEOPATRA': 26, 'CLODIUS PARNASSIAN': 27, 'CLOUDED SULPHUR': 28, 'COMET MOTH': 29, 'COMMON BANDED AWL': 30, 'COMMON WOOD-NYMPH': 31, 'COPPER TAIL': 32, 'CRECENT': 33, 'CRIMSON PATCH': 34, 'DANAID EGGFLY': 35, 'EASTERN COMA': 36, 'EASTERN DAPPLE WHITE': 37, 'EASTERN PINE ELFIN': 38, 'ELBOWED PIERROT': 39, 'EMPEROR GUM MOTH': 40, 'GARDEN TIGER MOTH': 41, 'GIANT LEOPARD MOTH': 42, 'GLITTERING SAPPHIRE': 43, 'GOLD BANDED': 44, 'GREAT EGGFLY': 45, 'GREAT JAY': 46, 'GREEN CELLED CATTLEHEART': 47, 'GREEN HAIRSTREAK': 48, 'GREY HAIRSTREAK': 49, 'HERCULES MOTH': 50, 'HUMMING BIRD HAWK MOTH': 51, 'INDRA SWALLOW': 52, 'IO MOTH': 53, 'Iphiclus sister': 54, 'JULIA': 55, 'LARGE MARBLE': 56, 'LUNA MOTH': 57, 'MADAGASCAN SUNSET MOTH': 58, 'MALACHITE': 59, 'MANGROVE SKIPPER': 60, 'MESTRA': 61, 'METALMARK': 62, 'MILBERTS TORTOISESHELL': 63, 'MONARCH': 64, 'MOURNING CLOAK': 65, 'OLEANDER HAWK MOTH': 66, 'ORANGE OAKLEAF': 67, 'ORANGE TIP': 68, 'ORCHARD SWALLOW': 69, 'PAINTED LADY': 70, 'PAPER KITE': 71, 'PEACOCK': 72, 'PINE WHITE': 73, 'PIPEVINE SWALLOW': 74, 'POLYPHEMUS MOTH': 75, 'POPINJAY': 76, 'PURPLE HAIRSTREAK': 77, 'PURPLISH COPPER': 78, 'QUESTION MARK': 79, 'RED ADMIRAL': 80, 'RED CRACKER': 81, 'RED POSTMAN': 82, 'RED SPOTTED PURPLE': 83, 'ROSY MAPLE MOTH': 84, 'SCARCE SWALLOW': 85, 'SILVER SPOT SKIPPER': 86, 'SIXSPOT BURNET MOTH': 87, 'SLEEPY ORANGE': 88, 'SOOTYWING': 89, 'SOUTHERN DOGFACE': 90, 'STRAITED QUEEN': 91, 'TROPICAL LEAFWING': 92, 'TWO BARRED FLASHER': 93, 'ULYSES': 94, 'VICEROY': 95, 'WHITE LINED SPHINX MOTH': 96, 'WOOD SATYR': 97, 'YELLOW SWALLOW TAIL': 98, 'ZEBRA LONG WING': 99}
test_image = image.load_img(uploaded_file, target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = lenet.predict(test_image)
prediction = lenet.predict(test_image)
predicted_class_index = np.argmax(prediction)
predicted_class_name = [key for key, value in class_indices.items() if value == predicted_class_index][0]
st.image(uploaded_file)
st.write(predicted_class_name)
print(predicted_class_index)


except:
st.write("There is error in file provided")

elif uploaded_file is None:
st.markdown(":red[Please enter a image]")
6 changes: 6 additions & 0 deletions Butterfly Species Classification using DL/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
streamlit
numpy
pandas
matplotlib
tensorflow>=2.7.0
keras>=2.6.0