Commit
·
3a18ad0
1
Parent(s):
29cb57b
Upload Model
Browse files
app.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import eda
|
3 |
+
import prediction
|
4 |
+
|
5 |
+
|
6 |
+
navigation = st.sidebar.selectbox('Pilih Halaman', ('EDA', 'Predict'))
|
7 |
+
|
8 |
+
|
9 |
+
if navigation == 'EDA':
|
10 |
+
eda.run()
|
11 |
+
else:
|
12 |
+
prediction.run()
|
eda.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
import numpy as np
|
4 |
+
import pandas as pd
|
5 |
+
import seaborn as sns
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import plotly.express as px
|
8 |
+
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
9 |
+
from tensorflow.keras.preprocessing import image
|
10 |
+
|
11 |
+
st.set_page_config(page_title='Fast Food Classification Dataset Analysis', layout='wide', initial_sidebar_state='expanded')
|
12 |
+
|
13 |
+
def run():
|
14 |
+
|
15 |
+
# Buat Title
|
16 |
+
st.title('EDA on Fast Food Classification')
|
17 |
+
|
18 |
+
# Buat Deskripsi
|
19 |
+
st.subheader('Written by Franciscus Andrew Sunanda, FTDS-RMT-018')
|
20 |
+
|
21 |
+
st.markdown('---')
|
22 |
+
|
23 |
+
|
24 |
+
st.write('Dataset : Fast Food Classification')
|
25 |
+
|
26 |
+
st.write('Objective : To create a model that can predict the type of a fast food based on image')
|
27 |
+
|
28 |
+
|
29 |
+
st.markdown('---')
|
30 |
+
main_path= 'D:\\tugas_andrew_DS\\phase_2\\m2\\food'
|
31 |
+
|
32 |
+
# Define batch size and image size
|
33 |
+
batch_size = 256
|
34 |
+
img_size = (64, 64)
|
35 |
+
# Define paths to the data folders
|
36 |
+
train_path = os.path.join(main_path, 'Train')
|
37 |
+
valid_path = os.path.join(main_path, 'Valid')
|
38 |
+
test_path = os.path.join(main_path, 'Test')
|
39 |
+
# Create data generators for training, validation, and testing
|
40 |
+
train_datagen = ImageDataGenerator(
|
41 |
+
rescale=1./255,
|
42 |
+
horizontal_flip=True
|
43 |
+
)
|
44 |
+
|
45 |
+
valid_datagen = ImageDataGenerator(
|
46 |
+
rescale=1./255
|
47 |
+
)
|
48 |
+
test_datagen = ImageDataGenerator(
|
49 |
+
rescale=1./255
|
50 |
+
)
|
51 |
+
|
52 |
+
train_generator = train_datagen.flow_from_directory(
|
53 |
+
train_path,
|
54 |
+
target_size=img_size,
|
55 |
+
batch_size=batch_size,
|
56 |
+
class_mode='categorical'
|
57 |
+
)
|
58 |
+
|
59 |
+
valid_generator = valid_datagen.flow_from_directory(
|
60 |
+
valid_path,
|
61 |
+
target_size=img_size,
|
62 |
+
batch_size=batch_size,
|
63 |
+
class_mode='categorical'
|
64 |
+
)
|
65 |
+
|
66 |
+
test_generator = test_datagen.flow_from_directory(
|
67 |
+
test_path,
|
68 |
+
target_size=img_size,
|
69 |
+
batch_size=batch_size,
|
70 |
+
class_mode='categorical'
|
71 |
+
)
|
72 |
+
|
73 |
+
st.write('## Showing Random Samples')
|
74 |
+
class_names = list(train_generator.class_indices.keys())
|
75 |
+
train_classes = pd.Series(train_generator.classes)
|
76 |
+
test_classes = pd.Series(test_generator.classes)
|
77 |
+
valid_classes = pd.Series(valid_generator.classes)
|
78 |
+
# Plot some samples from each class
|
79 |
+
fig, ax = plt.subplots(nrows=2, ncols=5, figsize=(10, 6), subplot_kw={'xticks': [], 'yticks': []})
|
80 |
+
for i, axi in enumerate(ax.flat):
|
81 |
+
img = plt.imread(f'{train_path}/{class_names[i]}/{os.listdir(train_path+"/"+class_names[i])[0]}')
|
82 |
+
axi.imshow(img)
|
83 |
+
axi.set_title(class_names[i])
|
84 |
+
plt.tight_layout()
|
85 |
+
st.pyplot(fig)
|
86 |
+
|
87 |
+
|
88 |
+
st.markdown('---')
|
89 |
+
|
90 |
+
st.write('## Balance Classification')
|
91 |
+
|
92 |
+
# Create a pandas dataframe to show the distribution of classes in train, test, and validation data
|
93 |
+
df = pd.concat([train_classes.value_counts(), test_classes.value_counts(), valid_classes.value_counts()], axis=1)
|
94 |
+
df.columns = ['Training Data', 'Test Data', 'Validation Data']
|
95 |
+
df.index = class_names
|
96 |
+
|
97 |
+
fig, ax = plt.subplots(figsize=(12, 6))
|
98 |
+
df.plot(kind='bar', stacked=False, ax=ax, width=0.8)
|
99 |
+
plt.xlabel('Class')
|
100 |
+
plt.ylabel('Data Distribution')
|
101 |
+
plt.title('Data Distribution for each class')
|
102 |
+
plt.xticks(rotation=45, ha='right')
|
103 |
+
st.pyplot(fig)
|
104 |
+
|
105 |
+
|
106 |
+
st.markdown('---')
|
107 |
+
|
108 |
+
st.write('## Mean Pixel Value')
|
109 |
+
|
110 |
+
# Plot the mean of pixel mean of each channel for each class (unstacked bar chart)
|
111 |
+
means = []
|
112 |
+
for i in range(len(class_names)):
|
113 |
+
class_name = class_names[i]
|
114 |
+
img_path = os.path.join(train_path, class_name, os.listdir(os.path.join(train_path, class_name))[0])
|
115 |
+
img = image.load_img(img_path, target_size=img_size)
|
116 |
+
img_array = image.img_to_array(img)
|
117 |
+
means.append(np.mean(img_array, axis=(0, 1)))
|
118 |
+
means_df = pd.DataFrame(means, columns=['Red', 'Green', 'Blue'])
|
119 |
+
means_df.index = class_names
|
120 |
+
fig, ax = plt.subplots(figsize=(12, 6))
|
121 |
+
means_df.plot(kind='bar', stacked=False, ax=ax, width=0.8)
|
122 |
+
plt.xlabel('Class')
|
123 |
+
plt.ylabel('Mean pixel value')
|
124 |
+
plt.title('Mean pixel value of each channel for each class')
|
125 |
+
plt.xticks(rotation=45, ha='right')
|
126 |
+
st.pyplot(fig)
|
127 |
+
|
128 |
+
st.markdown('---')
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
if __name__ == '__main__':
|
134 |
+
run()
|
model.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:914ea06afe62dda6b724ec2eb65a6ce9881c6686d7983f4aefbb3694245228b9
|
3 |
+
size 4719152
|
prediction.py
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
from PIL import Image
|
5 |
+
import os
|
6 |
+
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
7 |
+
from tensorflow.keras.models import load_model
|
8 |
+
|
9 |
+
|
10 |
+
# Load the Models
|
11 |
+
|
12 |
+
model = load_model('model.h5')
|
13 |
+
img_size = (64, 64)
|
14 |
+
# Define a function to preprocess the input image
|
15 |
+
def preprocess_input_image(img_path):
|
16 |
+
img = image.load_img(img_path, target_size=img_size)
|
17 |
+
img1 = image.load_img(img_path)
|
18 |
+
x = image.img_to_array(img)
|
19 |
+
x = np.expand_dims(x, axis=0)
|
20 |
+
x /= 255.
|
21 |
+
return x, img1
|
22 |
+
|
23 |
+
main_path= 'D:\\tugas_andrew_DS\\phase_2\\m2\\food'
|
24 |
+
|
25 |
+
# Define batch size and image size
|
26 |
+
batch_size = 256
|
27 |
+
img_size = (64, 64)
|
28 |
+
# Define paths to the data folders
|
29 |
+
train_path = os.path.join(main_path, 'Train')
|
30 |
+
valid_path = os.path.join(main_path, 'Valid')
|
31 |
+
test_path = os.path.join(main_path, 'Test')
|
32 |
+
|
33 |
+
# Create data generators for training, validation, and testing
|
34 |
+
train_datagen = ImageDataGenerator(
|
35 |
+
rescale=1./255,
|
36 |
+
horizontal_flip=True
|
37 |
+
)
|
38 |
+
|
39 |
+
valid_datagen = ImageDataGenerator(
|
40 |
+
rescale=1./255
|
41 |
+
)
|
42 |
+
test_datagen = ImageDataGenerator(
|
43 |
+
rescale=1./255
|
44 |
+
)
|
45 |
+
|
46 |
+
train_generator = train_datagen.flow_from_directory(
|
47 |
+
train_path,
|
48 |
+
target_size=img_size,
|
49 |
+
batch_size=batch_size,
|
50 |
+
class_mode='categorical'
|
51 |
+
)
|
52 |
+
|
53 |
+
valid_generator = valid_datagen.flow_from_directory(
|
54 |
+
valid_path,
|
55 |
+
target_size=img_size,
|
56 |
+
batch_size=batch_size,
|
57 |
+
class_mode='categorical'
|
58 |
+
)
|
59 |
+
|
60 |
+
test_generator = test_datagen.flow_from_directory(
|
61 |
+
test_path,
|
62 |
+
target_size=img_size,
|
63 |
+
batch_size=batch_size,
|
64 |
+
class_mode='categorical'
|
65 |
+
)
|
66 |
+
|
67 |
+
|
68 |
+
class_names = list(train_generator.class_indices.keys())
|
69 |
+
train_classes = pd.Series(train_generator.classes)
|
70 |
+
test_classes = pd.Series(test_generator.classes)
|
71 |
+
valid_classes = pd.Series(valid_generator.classes)
|
72 |
+
|
73 |
+
def run():
|
74 |
+
|
75 |
+
st.title('Fast Food Image Prediction')
|
76 |
+
|
77 |
+
|
78 |
+
with st.form(key='form_food'):
|
79 |
+
uploaded_file = st.file_uploader("Choose an image file", type=["jpg", "jpeg", "png"])
|
80 |
+
|
81 |
+
submitted = st.form_submit_button('Predict')
|
82 |
+
|
83 |
+
|
84 |
+
|
85 |
+
if submitted:
|
86 |
+
# Transform Inference-Set
|
87 |
+
if uploaded_file is not None:
|
88 |
+
# Preprocess the input image
|
89 |
+
img = Image.open(uploaded_file)
|
90 |
+
x = np.array(img.resize(img_size))/255.
|
91 |
+
x = np.expand_dims(x, axis=0)
|
92 |
+
|
93 |
+
# Make predictions on the input image
|
94 |
+
preds = model.predict(x, verbose=0)
|
95 |
+
pred_class = np.argmax(preds)
|
96 |
+
pred_class_name = class_names[pred_class]
|
97 |
+
|
98 |
+
# Display the input image and prediction result
|
99 |
+
st.image(img, caption=f"Predicted Class: {pred_class_name}", use_column_width=True)
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
if __name__ == '__main__':
|
104 |
+
run()
|