DSCmatter commited on
Commit
018173a
·
1 Parent(s): 012eb51

adding files

Browse files
Files changed (4) hide show
  1. README.md +93 -9
  2. app.py +56 -0
  3. requirements.txt +4 -0
  4. resnet50_dryfruits.h5 +3 -0
README.md CHANGED
@@ -1,12 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: Deployment Model
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dry Fruit Grade Classification
2
+
3
+ This project uses a deep learning model to classify images of dry fruits (like almonds and cashews) into different quality grades (e.g., Grade A, Grade B).
4
+
5
+ The model is built using TensorFlow/Keras and employs transfer learning with the **ResNet50** architecture.
6
+
7
+ ---
8
+
9
+ ## Results
10
+
11
+ * **Training:** The final fine-tuned model achieved a peak **validation accuracy of ~99.7%** during training.
12
+ * **Inference:** Real-world testing on individual images shows strong performance, with confidence scores often exceeding **99%**. Some images may yield lower confidence (e.g., ~75%) depending on quality and similarity to the training data.
13
+
14
  ---
15
+
16
+ ## Dataset
17
+
18
+ * **Source:** 850 original 720x720 images of various dry fruits.
19
+ * **Augmentation:** The dataset was expanded "offline" (on-disk) to 42,600 images, including rotations, brightness/contrast changes, and noise.
20
+ * **Classes:** The folder structure `DryFruits_Dataset/Fruit/Grade/` was reorganized into a flat structure (`dataset_flat/Fruit_Grade/`) for training.
21
+
 
22
  ---
23
 
24
+ ## Model and Training
25
+
26
+ The model is a pre-trained ResNet50 base with a new classification head (Global Average Pooling, a 128-node Dense layer, and a final Softmax output).
27
+
28
+ The training was performed in a Google Colab notebook using a T4 GPU, following a crucial **two-stage process**:
29
+
30
+ 1. **Stage 1: Feature Extraction**
31
+ * The ResNet50 base was frozen.
32
+ * Only the new classification head was trained for 10 epochs. This quickly "warms up" the new layers.
33
+ * **Result:** ~99.4% validation accuracy.
34
+
35
+ 2. **Stage 2: Fine-Tuning**
36
+ * The entire model (including the ResNet50 base) was unfrozen.
37
+ * The model was re-compiled with a **very low learning rate** (`1e-5`) to prevent destroying the pre-trained weights.
38
+ * Training continued until `EarlyStopping` (monitoring `val_loss`) stopped the process.
39
+ * **Final Result:** ~99.7% validation accuracy.
40
+
41
+ ---
42
+
43
+ ## How to Use
44
+
45
+ ### 1. Training the Model
46
+
47
+ 1. **Setup:**
48
+ * Upload the project notebook to Google Colab.
49
+ * Upload your dataset (e.g., `dryfruitsDataset.rar`) to Google Drive.
50
+
51
+ 2. **Run the Training Cells:**
52
+ * **Cell 1 (Setup):** Mounts your Google Drive and un-RARs the dataset.
53
+ * **Cell 2 (Reorganize):** Runs a script to convert the nested folder structure `(Almond/Grade_A)` into the flat structure `(Almond_Grade_A)` required by Keras.
54
+ * **Cell 3 (Data Generators):** Loads the 42.6k images using `ImageDataGenerator`. It applies the mandatory ResNet50 preprocessing.
55
+ * **Cell 4 (Stage 1 Training):** Trains the frozen model head.
56
+ * **Cell 5 (Stage 2 Training):** Unfreezes and fine-tunes the full model, saving the best version as `resnet50_dryfruits_best.keras`.
57
+
58
+ ### 2. Running Inference (Predicting New Images)
59
+
60
+ 1. **Load Model:** In a new cell (ideally in the same notebook), load the saved model.
61
+ ```python
62
+ from tensorflow.keras.models import load_model
63
+
64
+ model = load_model('resnet50_dryfruits_best.keras')
65
+
66
+ # Get the class mapping from the training generator
67
+ # (This requires 'train_generator' to still be in memory)
68
+ class_indices = train_generator.class_indices
69
+ class_names = {v: k for k, v in class_indices.items()}
70
+ ```
71
+
72
+ 2. **Upload and Predict:** Use the provided inference code to upload a single image, preprocess it, and see the model's prediction.
73
+ ```python
74
+ from google.colab import files
75
+ from tensorflow.keras.preprocessing import image
76
+ from tensorflow.keras.applications.resnet50 import preprocess_input
77
+ import numpy as np
78
+
79
+ # Upload an image
80
+ uploaded = files.upload()
81
+ test_image_path = list(uploaded.keys())[0]
82
+
83
+ # Load and preprocess the image
84
+ img = image.load_img(test_image_path, target_size=(224, 224))
85
+ img_array = image.img_to_array(img)
86
+ img_batch = np.expand_dims(img_array, axis=0)
87
+ img_preprocessed = preprocess_input(img_batch)
88
+
89
+ # Make prediction
90
+ prediction = model.predict(img_preprocessed)
91
+ predicted_index = np.argmax(prediction[0])
92
+ predicted_class_name = class_names[predicted_index]
93
+ confidence = np.max(prediction[0])
94
+
95
+ print(f"Prediction: {predicted_class_name} | Confidence: {confidence*100:.2f}%")
96
+ ```
app.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import tensorflow as tf
3
+ from tensorflow.keras.models import load_model
4
+ from tensorflow.keras.preprocessing import image
5
+ from tensorflow.keras.applications.resnet50 import preprocess_input
6
+ import numpy as np
7
+ from PIL import Image
8
+
9
+ # --- Load Your Model and Class Names ---
10
+ # Use st.cache_resource to load the model only once
11
+ @st.cache_resource
12
+ def load_my_model():
13
+ # Make sure this file name matches your model file
14
+ model = load_model('resnet50_dryfruits.h5')
15
+ return model
16
+
17
+ # --- This is the updated dictionary based on your list ---
18
+ class_names = {
19
+ 0: 'AlmondGrade_A',
20
+ 1: 'CashewGrade_B',
21
+ 2: 'RaisinGrade_A',
22
+ 3: 'CashewGrade_A',
23
+ 4: 'AlmondGrade_B',
24
+ 5: 'PistachioGrade_A',
25
+ 6: 'RaisinGrade_B',
26
+ 7: 'WalnutGrade_A',
27
+ 8: 'CashewGrade_C'
28
+ }
29
+ # --------------------------------------------------------
30
+
31
+ model = load_my_model()
32
+
33
+ # --- App Interface ---
34
+ st.title("Dry Fruit Quality Grader")
35
+ st.write("Upload an image of a dry fruit, and the model will predict its grade.")
36
+
37
+ uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
38
+
39
+ if uploaded_file is not None:
40
+ # 1. Preprocess the image
41
+ img = Image.open(uploaded_file).convert('RGB') # Ensure 3 channels
42
+ img = img.resize((224, 224))
43
+ img_array = image.img_to_array(img)
44
+ img_batch = np.expand_dims(img_array, axis=0)
45
+ img_preprocessed = preprocess_input(img_batch)
46
+
47
+ # 2. Make prediction
48
+ prediction = model.predict(img_preprocessed)
49
+ predicted_index = np.argmax(prediction[0])
50
+ predicted_class_name = class_names[predicted_index]
51
+ confidence = np.max(prediction[0])
52
+
53
+ # 3. Display results
54
+ st.image(img, caption="Uploaded Image", use_column_width=True)
55
+ st.markdown(f"## Prediction: **{predicted_class_name}**")
56
+ st.markdown(f"### Confidence: **{confidence * 100:.2f}%**")
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ tensorflow
2
+ streamlit
3
+ Pillow
4
+ numpy
resnet50_dryfruits.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a4d1c65a486780cb6e1c33c9bda9eae34edb0c658ea450ca8cab12f064787d0e
3
+ size 286585880