Spaces:
Configuration error
Configuration error
GitHub Action commited on
Commit Β·
27dc85b
1
Parent(s): a2f28ed
sync: ci: trigger initial deploy to Hugging Face
Browse files- .env +0 -3
- .gitattributes +0 -96
- README.md +0 -11
- app.py +0 -0
- scripts/data_prep/count_dataset.py +42 -42
- scripts/data_prep/fix_dataset.py +27 -27
- scripts/data_prep/organize_dataset.py +90 -90
- scripts/testing/test_upload.html +61 -61
- scripts/training/evaluate_model.py +56 -56
.env
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
OLLAMA_URL="http://localhost:11434"
|
| 2 |
-
OLLAMA_API_KEY="87b344ea09c540848abd777349d64466.PeZFbKB2Y03ddFyD4YXW0TpT"
|
| 3 |
-
OLLAMA_MODEL="llava-llama3"
|
|
|
|
|
|
|
|
|
|
|
|
.gitattributes
DELETED
|
@@ -1,96 +0,0 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz 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 |
-
venv/images/imagehash.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
-
venv/Lib/site-packages/__pycache__/typing_extensions.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 38 |
-
venv/Lib/site-packages/absl/testing/__pycache__/absltest.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 39 |
-
venv/Lib/site-packages/aiohttp/_http_parser.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 40 |
-
venv/Lib/site-packages/aiohttp/_websocket/reader_c.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 41 |
-
venv/Lib/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 42 |
-
venv/Lib/site-packages/attr/__pycache__/_make.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 43 |
-
venv/Lib/site-packages/charset_normalizer/md__mypyc.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 44 |
-
venv/Lib/site-packages/clang/__pycache__/cindex.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 45 |
-
venv/Lib/site-packages/clang/native/libclang.dll filter=lfs diff=lfs merge=lfs -text
|
| 46 |
-
venv/Lib/site-packages/click/__pycache__/core.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 47 |
-
venv/Lib/site-packages/contourpy/_contourpy.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 48 |
-
venv/Lib/site-packages/cv2/cv2.pyd filter=lfs diff=lfs merge=lfs -text
|
| 49 |
-
venv/Lib/site-packages/cv2/opencv_videoio_ffmpeg4130_64.dll filter=lfs diff=lfs merge=lfs -text
|
| 50 |
-
venv/Lib/site-packages/datasets/__pycache__/arrow_dataset.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 51 |
-
venv/Lib/site-packages/datasets/__pycache__/builder.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 52 |
-
venv/Lib/site-packages/datasets/__pycache__/dataset_dict.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 53 |
-
venv/Lib/site-packages/datasets/__pycache__/iterable_dataset.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 54 |
-
venv/Lib/site-packages/datasets/__pycache__/table.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 55 |
-
venv/Lib/site-packages/datasets/features/__pycache__/features.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 56 |
-
venv/Lib/site-packages/dill/__pycache__/_dill.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 57 |
-
venv/Lib/site-packages/fontTools/__pycache__/agl.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 58 |
-
venv/Lib/site-packages/fontTools/cffLib/__pycache__/__init__.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 59 |
-
venv/Lib/site-packages/fontTools/designspaceLib/__pycache__/__init__.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 60 |
-
venv/Lib/site-packages/fontTools/feaLib/__pycache__/ast.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 61 |
-
venv/Lib/site-packages/fontTools/feaLib/__pycache__/parser.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 62 |
-
venv/Lib/site-packages/fontTools/feaLib/lexer.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 63 |
-
venv/Lib/site-packages/fontTools/misc/bezierTools.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 64 |
-
venv/Lib/site-packages/fontTools/otlLib/__pycache__/builder.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 65 |
-
venv/Lib/site-packages/fontTools/qu2cu/qu2cu.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 66 |
-
venv/Lib/site-packages/fontTools/subset/__pycache__/__init__.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 67 |
-
venv/Lib/site-packages/fontTools/ttLib/tables/__pycache__/_g_l_y_f.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 68 |
-
venv/Lib/site-packages/fontTools/ttLib/tables/__pycache__/otConverters.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 69 |
-
venv/Lib/site-packages/fontTools/ttLib/tables/__pycache__/otTables.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 70 |
-
venv/Lib/site-packages/fontTools/ufoLib/__pycache__/__init__.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 71 |
-
venv/Lib/site-packages/fontTools/varLib/iup.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 72 |
-
venv/Lib/site-packages/fsspec/__pycache__/spec.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 73 |
-
venv/Lib/site-packages/google/_upb/_message.pyd filter=lfs diff=lfs merge=lfs -text
|
| 74 |
-
venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 75 |
-
venv/Lib/site-packages/grpc/__pycache__/_channel.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 76 |
-
venv/Lib/site-packages/grpc/_cython/cygrpc.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 77 |
-
venv/Lib/site-packages/h5py/_conv.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 78 |
-
venv/Lib/site-packages/h5py/_objects.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 79 |
-
venv/Lib/site-packages/h5py/_selector.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 80 |
-
venv/Lib/site-packages/h5py/defs.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 81 |
-
venv/Lib/site-packages/h5py/h5a.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 82 |
-
venv/Lib/site-packages/h5py/h5d.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 83 |
-
venv/Lib/site-packages/h5py/h5f.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 84 |
-
venv/Lib/site-packages/h5py/h5fd.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 85 |
-
venv/Lib/site-packages/h5py/h5g.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 86 |
-
venv/Lib/site-packages/h5py/h5o.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 87 |
-
venv/Lib/site-packages/h5py/h5p.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 88 |
-
venv/Lib/site-packages/h5py/h5s.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 89 |
-
venv/Lib/site-packages/h5py/h5t.cp311-win_amd64.pyd filter=lfs diff=lfs merge=lfs -text
|
| 90 |
-
venv/Lib/site-packages/h5py/hdf5.dll filter=lfs diff=lfs merge=lfs -text
|
| 91 |
-
venv/Lib/site-packages/h5py/hdf5_hl.dll filter=lfs diff=lfs merge=lfs -text
|
| 92 |
-
venv/Lib/site-packages/h5py/tests/__pycache__/test_dataset.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 93 |
-
venv/Lib/site-packages/hf_xet/hf_xet.pyd filter=lfs diff=lfs merge=lfs -text
|
| 94 |
-
venv/Lib/site-packages/huggingface_hub/__pycache__/hf_api.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 95 |
-
venv/Lib/site-packages/huggingface_hub/inference/__pycache__/_client.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
| 96 |
-
venv/Lib/site-packages/huggingface_hub/inference/_generated/__pycache__/_async_client.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
---
|
| 2 |
-
title: Mission17 Ai
|
| 3 |
-
emoji: π»
|
| 4 |
-
colorFrom: pink
|
| 5 |
-
colorTo: purple
|
| 6 |
-
sdk: docker
|
| 7 |
-
pinned: false
|
| 8 |
-
short_description: ai verify image
|
| 9 |
-
---
|
| 10 |
-
|
| 11 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
|
Binary files a/app.py and b/app.py differ
|
|
|
scripts/data_prep/count_dataset.py
CHANGED
|
@@ -1,43 +1,43 @@
|
|
| 1 |
-
import os
|
| 2 |
-
|
| 3 |
-
def count_images():
|
| 4 |
-
# Define the path to the dataset
|
| 5 |
-
# Based on your other scripts, it is in ../dataset/mission_dataset
|
| 6 |
-
base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 7 |
-
dataset_dir = os.path.join(base_dir, '..', '..', '..', 'dataset', 'mission_dataset')
|
| 8 |
-
|
| 9 |
-
print(f"π Checking dataset at: {os.path.abspath(dataset_dir)}\n")
|
| 10 |
-
|
| 11 |
-
if not os.path.exists(dataset_dir):
|
| 12 |
-
print(f"β Error: Folder not found. Have you run 'organize_dataset.py'?")
|
| 13 |
-
return
|
| 14 |
-
|
| 15 |
-
total_images = 0
|
| 16 |
-
|
| 17 |
-
# Get all subfolders (classes)
|
| 18 |
-
try:
|
| 19 |
-
classes = [d for d in os.listdir(dataset_dir) if os.path.isdir(os.path.join(dataset_dir, d))]
|
| 20 |
-
classes.sort()
|
| 21 |
-
except Exception as e:
|
| 22 |
-
print(f"β Error reading directory: {e}")
|
| 23 |
-
return
|
| 24 |
-
|
| 25 |
-
print(f"{'CLASS NAME':<35} | {'COUNT':<10} | {'STATUS'}")
|
| 26 |
-
print("-" * 50)
|
| 27 |
-
|
| 28 |
-
for class_name in classes:
|
| 29 |
-
class_path = os.path.join(dataset_dir, class_name)
|
| 30 |
-
# Count files that look like images
|
| 31 |
-
images = [f for f in os.listdir(class_path) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.webp', '.bmp'))]
|
| 32 |
-
count = len(images)
|
| 33 |
-
|
| 34 |
-
status = "β
Ready" if count >= 100 else "β οΈ Low Data" if count > 0 else "β Empty"
|
| 35 |
-
|
| 36 |
-
print(f"{class_name:<35} | {count:<10} | {status}")
|
| 37 |
-
total_images += count
|
| 38 |
-
|
| 39 |
-
print("-" * 50)
|
| 40 |
-
print(f"β
TOTAL IMAGES: {total_images}")
|
| 41 |
-
|
| 42 |
-
if __name__ == "__main__":
|
| 43 |
count_images()
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
+
def count_images():
|
| 4 |
+
# Define the path to the dataset
|
| 5 |
+
# Based on your other scripts, it is in ../dataset/mission_dataset
|
| 6 |
+
base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 7 |
+
dataset_dir = os.path.join(base_dir, '..', '..', '..', 'dataset', 'mission_dataset')
|
| 8 |
+
|
| 9 |
+
print(f"π Checking dataset at: {os.path.abspath(dataset_dir)}\n")
|
| 10 |
+
|
| 11 |
+
if not os.path.exists(dataset_dir):
|
| 12 |
+
print(f"β Error: Folder not found. Have you run 'organize_dataset.py'?")
|
| 13 |
+
return
|
| 14 |
+
|
| 15 |
+
total_images = 0
|
| 16 |
+
|
| 17 |
+
# Get all subfolders (classes)
|
| 18 |
+
try:
|
| 19 |
+
classes = [d for d in os.listdir(dataset_dir) if os.path.isdir(os.path.join(dataset_dir, d))]
|
| 20 |
+
classes.sort()
|
| 21 |
+
except Exception as e:
|
| 22 |
+
print(f"β Error reading directory: {e}")
|
| 23 |
+
return
|
| 24 |
+
|
| 25 |
+
print(f"{'CLASS NAME':<35} | {'COUNT':<10} | {'STATUS'}")
|
| 26 |
+
print("-" * 50)
|
| 27 |
+
|
| 28 |
+
for class_name in classes:
|
| 29 |
+
class_path = os.path.join(dataset_dir, class_name)
|
| 30 |
+
# Count files that look like images
|
| 31 |
+
images = [f for f in os.listdir(class_path) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.webp', '.bmp'))]
|
| 32 |
+
count = len(images)
|
| 33 |
+
|
| 34 |
+
status = "β
Ready" if count >= 100 else "β οΈ Low Data" if count > 0 else "β Empty"
|
| 35 |
+
|
| 36 |
+
print(f"{class_name:<35} | {count:<10} | {status}")
|
| 37 |
+
total_images += count
|
| 38 |
+
|
| 39 |
+
print("-" * 50)
|
| 40 |
+
print(f"β
TOTAL IMAGES: {total_images}")
|
| 41 |
+
|
| 42 |
+
if __name__ == "__main__":
|
| 43 |
count_images()
|
scripts/data_prep/fix_dataset.py
CHANGED
|
@@ -1,28 +1,28 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import shutil
|
| 3 |
-
|
| 4 |
-
# Define paths
|
| 5 |
-
import os
|
| 6 |
-
base_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', 'dataset', 'garbage_classification')
|
| 7 |
-
old_planting = os.path.join(base_dir, "planting")
|
| 8 |
-
new_planting = os.path.join(base_dir, "SDG13_15_Planting")
|
| 9 |
-
|
| 10 |
-
# Create new folder if it doesn't exist
|
| 11 |
-
if not os.path.exists(new_planting):
|
| 12 |
-
os.makedirs(new_planting)
|
| 13 |
-
|
| 14 |
-
# Move files from Old -> New
|
| 15 |
-
if os.path.exists(old_planting):
|
| 16 |
-
print(f"π Moving files from '{old_planting}' to '{new_planting}'...")
|
| 17 |
-
files = os.listdir(old_planting)
|
| 18 |
-
for file in files:
|
| 19 |
-
old_path = os.path.join(old_planting, file)
|
| 20 |
-
new_path = os.path.join(new_planting, f"old_{file}") # Rename to avoid conflicts
|
| 21 |
-
shutil.move(old_path, new_path)
|
| 22 |
-
|
| 23 |
-
# Delete the empty old folder
|
| 24 |
-
os.rmdir(old_planting)
|
| 25 |
-
print("β
Successfully merged folders!")
|
| 26 |
-
print("ποΈ Deleted old 'planting' folder.")
|
| 27 |
-
else:
|
| 28 |
print("β οΈ Old 'planting' folder not found. Already merged?")
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import shutil
|
| 3 |
+
|
| 4 |
+
# Define paths
|
| 5 |
+
import os
|
| 6 |
+
base_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', 'dataset', 'garbage_classification')
|
| 7 |
+
old_planting = os.path.join(base_dir, "planting")
|
| 8 |
+
new_planting = os.path.join(base_dir, "SDG13_15_Planting")
|
| 9 |
+
|
| 10 |
+
# Create new folder if it doesn't exist
|
| 11 |
+
if not os.path.exists(new_planting):
|
| 12 |
+
os.makedirs(new_planting)
|
| 13 |
+
|
| 14 |
+
# Move files from Old -> New
|
| 15 |
+
if os.path.exists(old_planting):
|
| 16 |
+
print(f"π Moving files from '{old_planting}' to '{new_planting}'...")
|
| 17 |
+
files = os.listdir(old_planting)
|
| 18 |
+
for file in files:
|
| 19 |
+
old_path = os.path.join(old_planting, file)
|
| 20 |
+
new_path = os.path.join(new_planting, f"old_{file}") # Rename to avoid conflicts
|
| 21 |
+
shutil.move(old_path, new_path)
|
| 22 |
+
|
| 23 |
+
# Delete the empty old folder
|
| 24 |
+
os.rmdir(old_planting)
|
| 25 |
+
print("β
Successfully merged folders!")
|
| 26 |
+
print("ποΈ Deleted old 'planting' folder.")
|
| 27 |
+
else:
|
| 28 |
print("β οΈ Old 'planting' folder not found. Already merged?")
|
scripts/data_prep/organize_dataset.py
CHANGED
|
@@ -1,91 +1,91 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import shutil
|
| 3 |
-
|
| 4 |
-
# π CONFIGURATION
|
| 5 |
-
# Current script directory
|
| 6 |
-
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 7 |
-
# The main project dataset folder (../dataset)
|
| 8 |
-
BASE_DIR = os.path.join(CURRENT_DIR, '..', '..', '..', 'dataset')
|
| 9 |
-
|
| 10 |
-
# 1. The "Correct" Destination
|
| 11 |
-
FINAL_DEST = os.path.join(BASE_DIR, "mission_dataset")
|
| 12 |
-
|
| 13 |
-
# 2. The "Old" Kaggle Dataset
|
| 14 |
-
OLD_GARBAGE_DIR = os.path.join(BASE_DIR, "garbage_classification")
|
| 15 |
-
|
| 16 |
-
# 3. The "Misplaced" Downloads (if any) inside mission17-ai/dataset
|
| 17 |
-
MISPLACED_DIR = os.path.join(CURRENT_DIR, '..', '..', "dataset", "mission_dataset")
|
| 18 |
-
|
| 19 |
-
# Map OLD folders to NEW SDG destinations
|
| 20 |
-
# We are putting ALL waste items into SDG12 (Responsible Consumption & Production)
|
| 21 |
-
MOVES = {
|
| 22 |
-
"SDG12_Recycling": [
|
| 23 |
-
"battery", "brown-glass", "cardboard",
|
| 24 |
-
"clothes", "green-glass", "metal", "paper",
|
| 25 |
-
"plastic", "shoes", "white-glass"
|
| 26 |
-
],
|
| 27 |
-
"Non_SDG_Invalid": [
|
| 28 |
-
"trash", "biological"
|
| 29 |
-
]
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
def organize_files():
|
| 33 |
-
print(f"π¦ Organizing dataset...")
|
| 34 |
-
|
| 35 |
-
# Ensure destination exists
|
| 36 |
-
if not os.path.exists(FINAL_DEST):
|
| 37 |
-
os.makedirs(FINAL_DEST)
|
| 38 |
-
print(f" β
Created '{FINAL_DEST}'")
|
| 39 |
-
|
| 40 |
-
# --- STEP 1: Merge Kaggle Data ---
|
| 41 |
-
if os.path.exists(OLD_GARBAGE_DIR):
|
| 42 |
-
print(f" π Merging 'garbage_classification'...")
|
| 43 |
-
for dest_folder, source_folders in MOVES.items():
|
| 44 |
-
dest_path = os.path.join(FINAL_DEST, dest_folder)
|
| 45 |
-
if not os.path.exists(dest_path): os.makedirs(dest_path)
|
| 46 |
-
|
| 47 |
-
for folder in source_folders:
|
| 48 |
-
src_path = os.path.join(OLD_GARBAGE_DIR, folder)
|
| 49 |
-
if os.path.exists(src_path):
|
| 50 |
-
# Move files
|
| 51 |
-
for file in os.listdir(src_path):
|
| 52 |
-
try:
|
| 53 |
-
shutil.move(os.path.join(src_path, file), os.path.join(dest_path, f"{folder}_{file}"))
|
| 54 |
-
except Exception: pass
|
| 55 |
-
# Remove empty folder
|
| 56 |
-
try:
|
| 57 |
-
os.rmdir(src_path)
|
| 58 |
-
except: pass
|
| 59 |
-
|
| 60 |
-
# Try to remove root garbage dir
|
| 61 |
-
try: os.rmdir(OLD_GARBAGE_DIR)
|
| 62 |
-
except: pass
|
| 63 |
-
print(" β
Kaggle data merged.")
|
| 64 |
-
|
| 65 |
-
# --- STEP 2: Fix Misplaced Downloads ---
|
| 66 |
-
if os.path.exists(MISPLACED_DIR):
|
| 67 |
-
print(f" β οΈ Found misplaced images in '{MISPLACED_DIR}'. Moving them...")
|
| 68 |
-
for category in os.listdir(MISPLACED_DIR):
|
| 69 |
-
src = os.path.join(MISPLACED_DIR, category)
|
| 70 |
-
dest = os.path.join(FINAL_DEST, category)
|
| 71 |
-
|
| 72 |
-
if os.path.isdir(src):
|
| 73 |
-
if not os.path.exists(dest): os.makedirs(dest)
|
| 74 |
-
for file in os.listdir(src):
|
| 75 |
-
try:
|
| 76 |
-
shutil.move(os.path.join(src, file), os.path.join(dest, file))
|
| 77 |
-
except: pass
|
| 78 |
-
try: os.rmdir(src)
|
| 79 |
-
except: pass
|
| 80 |
-
|
| 81 |
-
# Cleanup parent 'dataset' in mission17-ai if empty
|
| 82 |
-
try:
|
| 83 |
-
os.rmdir(MISPLACED_DIR)
|
| 84 |
-
os.rmdir(os.path.join(CURRENT_DIR, '..', '..', "dataset"))
|
| 85 |
-
except: pass
|
| 86 |
-
print(" β
Misplaced images moved to correct folder.")
|
| 87 |
-
|
| 88 |
-
print(f"\n⨠SUCCESS! Dataset is ready at: {FINAL_DEST}")
|
| 89 |
-
|
| 90 |
-
if __name__ == "__main__":
|
| 91 |
organize_files()
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import shutil
|
| 3 |
+
|
| 4 |
+
# π CONFIGURATION
|
| 5 |
+
# Current script directory
|
| 6 |
+
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 7 |
+
# The main project dataset folder (../dataset)
|
| 8 |
+
BASE_DIR = os.path.join(CURRENT_DIR, '..', '..', '..', 'dataset')
|
| 9 |
+
|
| 10 |
+
# 1. The "Correct" Destination
|
| 11 |
+
FINAL_DEST = os.path.join(BASE_DIR, "mission_dataset")
|
| 12 |
+
|
| 13 |
+
# 2. The "Old" Kaggle Dataset
|
| 14 |
+
OLD_GARBAGE_DIR = os.path.join(BASE_DIR, "garbage_classification")
|
| 15 |
+
|
| 16 |
+
# 3. The "Misplaced" Downloads (if any) inside mission17-ai/dataset
|
| 17 |
+
MISPLACED_DIR = os.path.join(CURRENT_DIR, '..', '..', "dataset", "mission_dataset")
|
| 18 |
+
|
| 19 |
+
# Map OLD folders to NEW SDG destinations
|
| 20 |
+
# We are putting ALL waste items into SDG12 (Responsible Consumption & Production)
|
| 21 |
+
MOVES = {
|
| 22 |
+
"SDG12_Recycling": [
|
| 23 |
+
"battery", "brown-glass", "cardboard",
|
| 24 |
+
"clothes", "green-glass", "metal", "paper",
|
| 25 |
+
"plastic", "shoes", "white-glass"
|
| 26 |
+
],
|
| 27 |
+
"Non_SDG_Invalid": [
|
| 28 |
+
"trash", "biological"
|
| 29 |
+
]
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
def organize_files():
|
| 33 |
+
print(f"π¦ Organizing dataset...")
|
| 34 |
+
|
| 35 |
+
# Ensure destination exists
|
| 36 |
+
if not os.path.exists(FINAL_DEST):
|
| 37 |
+
os.makedirs(FINAL_DEST)
|
| 38 |
+
print(f" β
Created '{FINAL_DEST}'")
|
| 39 |
+
|
| 40 |
+
# --- STEP 1: Merge Kaggle Data ---
|
| 41 |
+
if os.path.exists(OLD_GARBAGE_DIR):
|
| 42 |
+
print(f" π Merging 'garbage_classification'...")
|
| 43 |
+
for dest_folder, source_folders in MOVES.items():
|
| 44 |
+
dest_path = os.path.join(FINAL_DEST, dest_folder)
|
| 45 |
+
if not os.path.exists(dest_path): os.makedirs(dest_path)
|
| 46 |
+
|
| 47 |
+
for folder in source_folders:
|
| 48 |
+
src_path = os.path.join(OLD_GARBAGE_DIR, folder)
|
| 49 |
+
if os.path.exists(src_path):
|
| 50 |
+
# Move files
|
| 51 |
+
for file in os.listdir(src_path):
|
| 52 |
+
try:
|
| 53 |
+
shutil.move(os.path.join(src_path, file), os.path.join(dest_path, f"{folder}_{file}"))
|
| 54 |
+
except Exception: pass
|
| 55 |
+
# Remove empty folder
|
| 56 |
+
try:
|
| 57 |
+
os.rmdir(src_path)
|
| 58 |
+
except: pass
|
| 59 |
+
|
| 60 |
+
# Try to remove root garbage dir
|
| 61 |
+
try: os.rmdir(OLD_GARBAGE_DIR)
|
| 62 |
+
except: pass
|
| 63 |
+
print(" β
Kaggle data merged.")
|
| 64 |
+
|
| 65 |
+
# --- STEP 2: Fix Misplaced Downloads ---
|
| 66 |
+
if os.path.exists(MISPLACED_DIR):
|
| 67 |
+
print(f" β οΈ Found misplaced images in '{MISPLACED_DIR}'. Moving them...")
|
| 68 |
+
for category in os.listdir(MISPLACED_DIR):
|
| 69 |
+
src = os.path.join(MISPLACED_DIR, category)
|
| 70 |
+
dest = os.path.join(FINAL_DEST, category)
|
| 71 |
+
|
| 72 |
+
if os.path.isdir(src):
|
| 73 |
+
if not os.path.exists(dest): os.makedirs(dest)
|
| 74 |
+
for file in os.listdir(src):
|
| 75 |
+
try:
|
| 76 |
+
shutil.move(os.path.join(src, file), os.path.join(dest, file))
|
| 77 |
+
except: pass
|
| 78 |
+
try: os.rmdir(src)
|
| 79 |
+
except: pass
|
| 80 |
+
|
| 81 |
+
# Cleanup parent 'dataset' in mission17-ai if empty
|
| 82 |
+
try:
|
| 83 |
+
os.rmdir(MISPLACED_DIR)
|
| 84 |
+
os.rmdir(os.path.join(CURRENT_DIR, '..', '..', "dataset"))
|
| 85 |
+
except: pass
|
| 86 |
+
print(" β
Misplaced images moved to correct folder.")
|
| 87 |
+
|
| 88 |
+
print(f"\n⨠SUCCESS! Dataset is ready at: {FINAL_DEST}")
|
| 89 |
+
|
| 90 |
+
if __name__ == "__main__":
|
| 91 |
organize_files()
|
scripts/testing/test_upload.html
CHANGED
|
@@ -1,61 +1,61 @@
|
|
| 1 |
-
<!DOCTYPE html>
|
| 2 |
-
<html lang="en">
|
| 3 |
-
<head>
|
| 4 |
-
<meta charset="UTF-8">
|
| 5 |
-
<title>Mission 17 AI Scanner</title>
|
| 6 |
-
<style>
|
| 7 |
-
body { font-family: 'Segoe UI', sans-serif; text-align: center; padding: 50px; background-color: #f4f4f9; }
|
| 8 |
-
.card { background: white; padding: 40px; border-radius: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); display: inline-block; max-width: 400px; }
|
| 9 |
-
button { background: #007bff; color: white; border: none; padding: 12px 24px; border-radius: 5px; cursor: pointer; font-size: 16px; margin-top: 15px; }
|
| 10 |
-
button:hover { background: #0056b3; }
|
| 11 |
-
#result { margin-top: 25px; font-weight: bold; }
|
| 12 |
-
.verified { color: #28a745; background: #e6fffa; padding: 15px; border-radius: 8px; border: 1px solid #28a745; }
|
| 13 |
-
.rejected { color: #dc3545; background: #fff5f5; padding: 15px; border-radius: 8px; border: 1px solid #dc3545; }
|
| 14 |
-
</style>
|
| 15 |
-
</head>
|
| 16 |
-
<body>
|
| 17 |
-
<div class="card">
|
| 18 |
-
<h2>π€ Mission 17 AI Scanner</h2>
|
| 19 |
-
<p>Upload a photo to verify your mission!</p>
|
| 20 |
-
|
| 21 |
-
<input type="file" id="fileInput" accept="image/*">
|
| 22 |
-
<br>
|
| 23 |
-
<button onclick="scanImage()">π Scan Mission</button>
|
| 24 |
-
|
| 25 |
-
<div id="result"></div>
|
| 26 |
-
</div>
|
| 27 |
-
|
| 28 |
-
<script>
|
| 29 |
-
async function scanImage() {
|
| 30 |
-
const fileInput = document.getElementById('fileInput');
|
| 31 |
-
const resultDiv = document.getElementById('result');
|
| 32 |
-
|
| 33 |
-
if (!fileInput.files[0]) {
|
| 34 |
-
alert("Please select an image first!");
|
| 35 |
-
return;
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
resultDiv.innerHTML = "β³ Scanning...";
|
| 39 |
-
|
| 40 |
-
const formData = new FormData();
|
| 41 |
-
formData.append("file", fileInput.files[0]);
|
| 42 |
-
|
| 43 |
-
try {
|
| 44 |
-
const response = await fetch("http://127.0.0.1:5000/predict", { method: "POST", body: formData });
|
| 45 |
-
const data = await response.json();
|
| 46 |
-
|
| 47 |
-
const colorClass = data.verdict === "VERIFIED" ? "verified" : "rejected";
|
| 48 |
-
resultDiv.innerHTML = `
|
| 49 |
-
<div class="${colorClass}">
|
| 50 |
-
<h3>${data.message}</h3>
|
| 51 |
-
<p><strong>π· Type:</strong> ${data.source_check}</p>
|
| 52 |
-
<p><strong>π― Accuracy:</strong> ${data.confidence}</p>
|
| 53 |
-
<p><strong>π SDG:</strong> ${data.sdg}</p>
|
| 54 |
-
</div>`;
|
| 55 |
-
} catch (error) {
|
| 56 |
-
resultDiv.innerHTML = "β Error connecting to server. Is app.py running?";
|
| 57 |
-
}
|
| 58 |
-
}
|
| 59 |
-
</script>
|
| 60 |
-
</body>
|
| 61 |
-
</html>
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>Mission 17 AI Scanner</title>
|
| 6 |
+
<style>
|
| 7 |
+
body { font-family: 'Segoe UI', sans-serif; text-align: center; padding: 50px; background-color: #f4f4f9; }
|
| 8 |
+
.card { background: white; padding: 40px; border-radius: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); display: inline-block; max-width: 400px; }
|
| 9 |
+
button { background: #007bff; color: white; border: none; padding: 12px 24px; border-radius: 5px; cursor: pointer; font-size: 16px; margin-top: 15px; }
|
| 10 |
+
button:hover { background: #0056b3; }
|
| 11 |
+
#result { margin-top: 25px; font-weight: bold; }
|
| 12 |
+
.verified { color: #28a745; background: #e6fffa; padding: 15px; border-radius: 8px; border: 1px solid #28a745; }
|
| 13 |
+
.rejected { color: #dc3545; background: #fff5f5; padding: 15px; border-radius: 8px; border: 1px solid #dc3545; }
|
| 14 |
+
</style>
|
| 15 |
+
</head>
|
| 16 |
+
<body>
|
| 17 |
+
<div class="card">
|
| 18 |
+
<h2>π€ Mission 17 AI Scanner</h2>
|
| 19 |
+
<p>Upload a photo to verify your mission!</p>
|
| 20 |
+
|
| 21 |
+
<input type="file" id="fileInput" accept="image/*">
|
| 22 |
+
<br>
|
| 23 |
+
<button onclick="scanImage()">π Scan Mission</button>
|
| 24 |
+
|
| 25 |
+
<div id="result"></div>
|
| 26 |
+
</div>
|
| 27 |
+
|
| 28 |
+
<script>
|
| 29 |
+
async function scanImage() {
|
| 30 |
+
const fileInput = document.getElementById('fileInput');
|
| 31 |
+
const resultDiv = document.getElementById('result');
|
| 32 |
+
|
| 33 |
+
if (!fileInput.files[0]) {
|
| 34 |
+
alert("Please select an image first!");
|
| 35 |
+
return;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
resultDiv.innerHTML = "β³ Scanning...";
|
| 39 |
+
|
| 40 |
+
const formData = new FormData();
|
| 41 |
+
formData.append("file", fileInput.files[0]);
|
| 42 |
+
|
| 43 |
+
try {
|
| 44 |
+
const response = await fetch("http://127.0.0.1:5000/predict", { method: "POST", body: formData });
|
| 45 |
+
const data = await response.json();
|
| 46 |
+
|
| 47 |
+
const colorClass = data.verdict === "VERIFIED" ? "verified" : "rejected";
|
| 48 |
+
resultDiv.innerHTML = `
|
| 49 |
+
<div class="${colorClass}">
|
| 50 |
+
<h3>${data.message}</h3>
|
| 51 |
+
<p><strong>π· Type:</strong> ${data.source_check}</p>
|
| 52 |
+
<p><strong>π― Accuracy:</strong> ${data.confidence}</p>
|
| 53 |
+
<p><strong>π SDG:</strong> ${data.sdg}</p>
|
| 54 |
+
</div>`;
|
| 55 |
+
} catch (error) {
|
| 56 |
+
resultDiv.innerHTML = "β Error connecting to server. Is app.py running?";
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
</script>
|
| 60 |
+
</body>
|
| 61 |
+
</html>
|
scripts/training/evaluate_model.py
CHANGED
|
@@ -1,57 +1,57 @@
|
|
| 1 |
-
import numpy as np
|
| 2 |
-
import tensorflow as tf
|
| 3 |
-
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
| 4 |
-
from tensorflow.keras.applications.efficientnet import preprocess_input
|
| 5 |
-
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
|
| 6 |
-
import matplotlib.pyplot as plt
|
| 7 |
-
import seaborn as sns
|
| 8 |
-
import os
|
| 9 |
-
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 10 |
-
|
| 11 |
-
print("β³ Loading AI Model...")
|
| 12 |
-
# π Ensure this is your correct model name!
|
| 13 |
-
model = tf.keras.models.load_model(os.path.join(BASE_DIR, '..', '..', 'mission_model.h5'))
|
| 14 |
-
|
| 15 |
-
print("π Loading Test Dataset...")
|
| 16 |
-
# π Pointing to the new TEST split folder
|
| 17 |
-
test_dir = os.path.join(BASE_DIR, '..', '..', '..', 'dataset', 'mission_dataset_split', 'test')
|
| 18 |
-
|
| 19 |
-
test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
|
| 20 |
-
test_generator = test_datagen.flow_from_directory(
|
| 21 |
-
test_dir,
|
| 22 |
-
target_size=(224, 224),
|
| 23 |
-
batch_size=32,
|
| 24 |
-
class_mode='categorical',
|
| 25 |
-
shuffle=False
|
| 26 |
-
)
|
| 27 |
-
|
| 28 |
-
print("π€ Running Predictions (This may take a minute)...")
|
| 29 |
-
Y_pred = model.predict(test_generator)
|
| 30 |
-
y_pred_classes = np.argmax(Y_pred, axis=1) # π FIXED: Grabs the top prediction per image
|
| 31 |
-
y_true = test_generator.classes
|
| 32 |
-
|
| 33 |
-
print("\n" + "="*50)
|
| 34 |
-
print("π CAPSTONE AI PERFORMANCE METRICS π")
|
| 35 |
-
print("="*50)
|
| 36 |
-
|
| 37 |
-
# π FIXED: Added average='weighted' to handle all 10 classes correctly
|
| 38 |
-
accuracy = accuracy_score(y_true, y_pred_classes)
|
| 39 |
-
precision = precision_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 40 |
-
recall = recall_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 41 |
-
f1 = f1_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 42 |
-
|
| 43 |
-
print(f"β
Accuracy: {accuracy * 100:.2f}%")
|
| 44 |
-
print(f"π― Precision: {precision * 100:.2f}%")
|
| 45 |
-
print(f"π Recall: {recall * 100:.2f}%")
|
| 46 |
-
print(f"βοΈ F1-Score: {f1 * 100:.2f}%")
|
| 47 |
-
print("="*50)
|
| 48 |
-
|
| 49 |
-
# Make the confusion matrix chart larger to fit 10 classes
|
| 50 |
-
cm = confusion_matrix(y_true, y_pred_classes)
|
| 51 |
-
plt.figure(figsize=(10, 8))
|
| 52 |
-
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
|
| 53 |
-
plt.title('AI Confusion Matrix (10 Classes)')
|
| 54 |
-
plt.ylabel('Actual Image Class')
|
| 55 |
-
plt.xlabel('AI Prediction')
|
| 56 |
-
plt.savefig(os.path.join(BASE_DIR, '..', '..', 'outputs', 'confusion_matrix.png'))
|
| 57 |
print("\nπ Saved 'confusion_matrix.png' to your outputs folder. Put this in your presentation!")
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import tensorflow as tf
|
| 3 |
+
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
| 4 |
+
from tensorflow.keras.applications.efficientnet import preprocess_input
|
| 5 |
+
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
|
| 6 |
+
import matplotlib.pyplot as plt
|
| 7 |
+
import seaborn as sns
|
| 8 |
+
import os
|
| 9 |
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 10 |
+
|
| 11 |
+
print("β³ Loading AI Model...")
|
| 12 |
+
# π Ensure this is your correct model name!
|
| 13 |
+
model = tf.keras.models.load_model(os.path.join(BASE_DIR, '..', '..', 'mission_model.h5'))
|
| 14 |
+
|
| 15 |
+
print("π Loading Test Dataset...")
|
| 16 |
+
# π Pointing to the new TEST split folder
|
| 17 |
+
test_dir = os.path.join(BASE_DIR, '..', '..', '..', 'dataset', 'mission_dataset_split', 'test')
|
| 18 |
+
|
| 19 |
+
test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
|
| 20 |
+
test_generator = test_datagen.flow_from_directory(
|
| 21 |
+
test_dir,
|
| 22 |
+
target_size=(224, 224),
|
| 23 |
+
batch_size=32,
|
| 24 |
+
class_mode='categorical',
|
| 25 |
+
shuffle=False
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
print("π€ Running Predictions (This may take a minute)...")
|
| 29 |
+
Y_pred = model.predict(test_generator)
|
| 30 |
+
y_pred_classes = np.argmax(Y_pred, axis=1) # π FIXED: Grabs the top prediction per image
|
| 31 |
+
y_true = test_generator.classes
|
| 32 |
+
|
| 33 |
+
print("\n" + "="*50)
|
| 34 |
+
print("π CAPSTONE AI PERFORMANCE METRICS π")
|
| 35 |
+
print("="*50)
|
| 36 |
+
|
| 37 |
+
# π FIXED: Added average='weighted' to handle all 10 classes correctly
|
| 38 |
+
accuracy = accuracy_score(y_true, y_pred_classes)
|
| 39 |
+
precision = precision_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 40 |
+
recall = recall_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 41 |
+
f1 = f1_score(y_true, y_pred_classes, average='weighted', zero_division=0)
|
| 42 |
+
|
| 43 |
+
print(f"β
Accuracy: {accuracy * 100:.2f}%")
|
| 44 |
+
print(f"π― Precision: {precision * 100:.2f}%")
|
| 45 |
+
print(f"π Recall: {recall * 100:.2f}%")
|
| 46 |
+
print(f"βοΈ F1-Score: {f1 * 100:.2f}%")
|
| 47 |
+
print("="*50)
|
| 48 |
+
|
| 49 |
+
# Make the confusion matrix chart larger to fit 10 classes
|
| 50 |
+
cm = confusion_matrix(y_true, y_pred_classes)
|
| 51 |
+
plt.figure(figsize=(10, 8))
|
| 52 |
+
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
|
| 53 |
+
plt.title('AI Confusion Matrix (10 Classes)')
|
| 54 |
+
plt.ylabel('Actual Image Class')
|
| 55 |
+
plt.xlabel('AI Prediction')
|
| 56 |
+
plt.savefig(os.path.join(BASE_DIR, '..', '..', 'outputs', 'confusion_matrix.png'))
|
| 57 |
print("\nπ Saved 'confusion_matrix.png' to your outputs folder. Put this in your presentation!")
|