initial upload commit
Browse filesupload 7 files including app, prediction script, eda script, keras model, image resources, and requirements.
- .gitattributes +2 -0
- app.py +10 -0
- cnn_model.keras +0 -0
- eda.py +31 -0
- output_eda_train.png +3 -0
- output_eda_valid.png +3 -0
- prediction.py +82 -0
- requirements.txt +9 -0
.gitattributes
CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
output_eda_train.png filter=lfs diff=lfs merge=lfs -text
|
37 |
+
output_eda_valid.png filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import eda
|
3 |
+
import prediction
|
4 |
+
|
5 |
+
navigation = st.sidebar.selectbox('Move me to this page:', ['Exploratory Data Analysis', 'Model Prediction'])
|
6 |
+
|
7 |
+
if navigation == 'Exploratory Data Analysis':
|
8 |
+
eda.run()
|
9 |
+
else:
|
10 |
+
prediction.run()
|
cnn_model.keras
ADDED
Binary file (83.6 kB). View file
|
|
eda.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
def run():
|
4 |
+
st.image('https://static.vecteezy.com/system/resources/thumbnails/025/868/984/small/freshy-various-fruits-for-summer-background-summer-festive-time-concept-generative-ai-free-photo.jpeg', use_column_width=True)
|
5 |
+
st.markdown('# Fruit Classification Using Artificial Neural Network Modeling')
|
6 |
+
st.markdown('This is a fun project to create a model that lets the computer predict a given image and classify it into any predetermined class upon this model development.')
|
7 |
+
st.markdown('This model allows you to upload and predict images into any of these classes:\n- Apple\n- Banana\n- Grape\n- Mango\n- Strawberry')
|
8 |
+
st.markdown('Image credit: Vecteezy')
|
9 |
+
st.markdown('---')
|
10 |
+
|
11 |
+
st.markdown('# Exploratory Data Analysis')
|
12 |
+
st.markdown('This section provides a brief introduction to the dataset used for model construction in the background process.')
|
13 |
+
st.markdown('---')
|
14 |
+
st.markdown('## Link to the Main Dataset')
|
15 |
+
st.markdown('You can obtain the dataset via this [link](https://www.kaggle.com/datasets/utkarshsaxenadn/fruits-classification/download?datasetVersionNumber=1)')
|
16 |
+
st.markdown('---')
|
17 |
+
st.markdown('## Sample Images from Train-set')
|
18 |
+
st.markdown('Here are several images used for model training:')
|
19 |
+
st.image('output_eda_train.png')
|
20 |
+
st.markdown('Description: The training dataset includes three types of images:\n- Straightforward images focusing on a single fruit\n- Fruits with relevant backgrounds\n- Fruits with context and zoomed-out backgrounds, showing a wider environment')
|
21 |
+
st.markdown('---')
|
22 |
+
st.markdown('## Sample Images from Validation-set')
|
23 |
+
st.markdown('Here are several images used for model validation:')
|
24 |
+
st.image('output_eda_valid.png')
|
25 |
+
st.markdown('Description: The validation dataset includes three types of images, similar to those in the training set. Images in the validation set inherit characteristics from the training set.')
|
26 |
+
|
27 |
+
st.markdown('---')
|
28 |
+
st.markdown('Managed by: Nicku R. Perdana | [LinkedIn](https://www.linkedin.com/in/nickurendyperdana/) | [Github](https://github.com/nickuperdana)')
|
29 |
+
|
30 |
+
if __name__ == '__main__':
|
31 |
+
run()
|
output_eda_train.png
ADDED
![]() |
Git LFS Details
|
output_eda_valid.png
ADDED
![]() |
Git LFS Details
|
prediction.py
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import requests
|
3 |
+
import numpy as np
|
4 |
+
import cv2
|
5 |
+
import tensorflow as tf
|
6 |
+
|
7 |
+
model = tf.keras.models.load_model('cnn_model.keras')
|
8 |
+
|
9 |
+
def run():
|
10 |
+
st.image('https://static.vecteezy.com/system/resources/thumbnails/025/868/984/small/freshy-various-fruits-for-summer-background-summer-festive-time-concept-generative-ai-free-photo.jpeg', use_column_width=True)
|
11 |
+
st.markdown('# Fruit Classification Using Artificial Neural Network Modeling')
|
12 |
+
st.markdown('This is a fun project to create a model that lets the computer predict a given image and classify it into any predetermined class upon this model development.')
|
13 |
+
st.markdown('This model allows you to upload and predict images into any of these classes:\n- Apple\n- Banana\n- Grape\n- Mango\n- Strawberry')
|
14 |
+
st.markdown('Image credit: Vecteezy')
|
15 |
+
st.markdown('---')
|
16 |
+
|
17 |
+
st.markdown("# Let's Predict An Image!")
|
18 |
+
|
19 |
+
st.markdown('### Upload an Image.')
|
20 |
+
uploadMethod = st.selectbox('Before we predict an image, choose an upload method first', ['Upload image', 'Send image URL'], index=None, placeholder='Select method...')
|
21 |
+
|
22 |
+
try:
|
23 |
+
with st.form('MyForm'):
|
24 |
+
if uploadMethod == 'Upload image':
|
25 |
+
imgUpload = st.file_uploader('Upload your file here', type=['png', 'jpg', 'webp', 'jpeg'], accept_multiple_files=False)
|
26 |
+
submit = st.form_submit_button('Start Predicting')
|
27 |
+
elif uploadMethod == 'Send image URL':
|
28 |
+
imgUrl = st.text_input('Enter URL', value=None, placeholder='URL...')
|
29 |
+
# if inputUrl != None:
|
30 |
+
# st.markdown('Theploaded image:')
|
31 |
+
# st.image(inputUrl)
|
32 |
+
submit = st.form_submit_button('Start Predicting')
|
33 |
+
|
34 |
+
class_list = ['Apple', 'Banana', 'Grape', 'Melon', 'Strawberry']
|
35 |
+
|
36 |
+
st.markdown('## Prediction Result:')
|
37 |
+
if submit:
|
38 |
+
if uploadMethod == 'Upload image':
|
39 |
+
inf_img = cv2.imdecode(np.fromstring(imgUpload.read(), np.uint8), 1)
|
40 |
+
inf_img_col = cv2.cvtColor(inf_img, cv2.COLOR_BGR2RGB)
|
41 |
+
inf_prep_img = cv2.resize(inf_img_col, (400,400))
|
42 |
+
inf_scal_img = inf_prep_img / 255.0
|
43 |
+
inf_reshape = np.reshape(inf_scal_img, [1,400,400,3])
|
44 |
+
class_img = model.predict(inf_reshape, verbose=0)
|
45 |
+
confident_index = np.argmax(class_img)
|
46 |
+
class_label = class_list[confident_index]
|
47 |
+
listproba = list(class_img[0])
|
48 |
+
st.markdown('You uploaded this image:')
|
49 |
+
st.image(imgUpload, use_column_width=True)
|
50 |
+
st.markdown(f'The model predicted the image given as a class of {class_label} with a probability of {listproba[confident_index]}.')
|
51 |
+
st.markdown('Due to the current state of prediction accuracy, a significant occurence of misidentification is expected.')
|
52 |
+
elif uploadMethod == 'Send image URL':
|
53 |
+
if imgUrl == "":
|
54 |
+
pass
|
55 |
+
else:
|
56 |
+
try:
|
57 |
+
response = requests.get(imgUrl)
|
58 |
+
if response.status_code == 200:
|
59 |
+
inf_url_img = cv2.imdecode(np.frombuffer(response.content, np.uint8), 1)
|
60 |
+
inf_img_url_col = cv2.cvtColor(inf_url_img, cv2.COLOR_RGB2BGR)
|
61 |
+
inf_prep_url_img = cv2.resize(inf_img_url_col, (400,400))
|
62 |
+
inf_scal_url_img = inf_prep_url_img / 255.0
|
63 |
+
inf_url_reshape = np.reshape(inf_scal_url_img, [1,400,400,3])
|
64 |
+
class_url_img = model.predict(inf_url_reshape, verbose=0)
|
65 |
+
confident_index_url = np.argmax(class_url_img)
|
66 |
+
class_url_label = class_list[confident_index_url]
|
67 |
+
listproba_url = list(class_url_img[0])
|
68 |
+
st.markdown('You uploaded this image:')
|
69 |
+
st.image(inf_img_url_col, use_column_width=True)
|
70 |
+
st.markdown(f'The model predicted the image given as a class of {class_url_label} with a probability of {listproba_url[confident_index_url]}.')
|
71 |
+
st.markdown('Due to the current state of prediction accuracy, a significant occurence of misidentification is expected.')
|
72 |
+
|
73 |
+
else:
|
74 |
+
st.markdown("Unable to fetch image from the given URL. Please try again")
|
75 |
+
pass
|
76 |
+
except:
|
77 |
+
pass
|
78 |
+
except:
|
79 |
+
pass
|
80 |
+
|
81 |
+
if __name__ == '__main__':
|
82 |
+
run()
|
requirements.txt
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tensorflow==2.15.0
|
2 |
+
streamlit
|
3 |
+
requests
|
4 |
+
numpy
|
5 |
+
cv2
|
6 |
+
matplotlib
|
7 |
+
pandas
|
8 |
+
seaborn
|
9 |
+
keras
|