daffarinali commited on
Commit
2dfbde4
ยท
verified ยท
1 Parent(s): 293c5ad

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile.txt +48 -0
  2. app.py +54 -0
  3. prepare.py +30 -0
  4. requirements.txt +5 -0
Dockerfile.txt ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # === Stage 1: Build Dependencies ===
2
+ FROM python:3.9-slim AS builder
3
+
4
+ # Set environment variables
5
+ ENV PYTHONUNBUFFERED=1 \
6
+ PIP_NO_CACHE_DIR=1 \
7
+ PIP_DISABLE_PIP_VERSION_CHECK=1 \
8
+ PATH="/root/.local/bin:$PATH"
9
+
10
+ # Install only necessary system dependencies
11
+ RUN apt-get update && apt-get install -y --no-install-recommends \
12
+ libgl1-mesa-glx \
13
+ libglib2.0-0 \
14
+ && rm -rf /var/lib/apt/lists/*
15
+
16
+ # Install Python dependencies
17
+ WORKDIR /app
18
+ COPY requirements.txt .
19
+ RUN pip install --user --no-cache-dir -r requirements.txt
20
+
21
+ # Copy model preparation script and run it
22
+ COPY prepare.py .
23
+ RUN python3 prepare.py
24
+
25
+ # === Stage 2: Minimal Runtime Image ===
26
+ FROM python:3.9-slim
27
+
28
+ # Set environment variables
29
+ ENV PATH="/root/.local/bin:$PATH"
30
+
31
+ # Copy only required dependencies from builder
32
+ COPY --from=builder /root/.local /root/.local
33
+
34
+ # Set work directory
35
+ WORKDIR /app
36
+
37
+ # Copy the model and class mapping
38
+ COPY --from=builder /app/model.h5 /app/model.h5
39
+ COPY --from=builder /app/class.json /app/class.json
40
+
41
+ # Copy only necessary application files
42
+ COPY app.py .
43
+
44
+ # Expose Streamlit port
45
+ EXPOSE 7860
46
+
47
+ # Run Streamlit app
48
+ CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.address=0.0.0.0"]
app.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import tensorflow as tf
3
+ import numpy as np
4
+ from PIL import Image
5
+ import json
6
+
7
+ # Load the trained CNN model
8
+ @st.cache_resource
9
+ def load_model():
10
+ return tf.keras.models.load_model("model.h5")
11
+
12
+ model = load_model()
13
+
14
+ # Function to preprocess a single image
15
+ def preprocess_single_image(pil_img):
16
+ """
17
+ Preprocesses a Pillow image for model inference.
18
+
19
+ Args:
20
+ pil_img (PIL.Image.Image): A Pillow image object.
21
+
22
+ Returns:
23
+ preprocessed_img (tf.Tensor): Preprocessed image tensor.
24
+ """
25
+ img = pil_img.convert("RGB") # Convert to RGB
26
+ img = img.resize((224, 224)) # Resize
27
+ img = np.array(img) # Convert to NumPy array
28
+ img = tf.keras.applications.efficientnet.preprocess_input(img) # Apply EfficientNet preprocessing
29
+ img = tf.expand_dims(img, axis=0) # Add batch dimension
30
+ return img
31
+
32
+ # Load class labels
33
+ CLASS_NAMES = json.load(open("class.json", "r"))
34
+
35
+ st.title("๐Ÿƒ Card Classification with CNN")
36
+ st.write("Upload an image to classify and visualize the top predictions.")
37
+
38
+ # Upload image
39
+ uploaded_file = st.file_uploader("๐Ÿ“‚ Choose an image...", type=["jpg", "png", "jpeg"])
40
+
41
+ if uploaded_file is not None:
42
+ image = Image.open(uploaded_file)
43
+ st.image(image, caption="๐Ÿ–ผ Uploaded Image", use_container_width=True)
44
+
45
+ # Preprocess image
46
+ img = preprocess_single_image(image)
47
+
48
+ # Predict
49
+ predictions = model.predict(img)
50
+ predicted_class_index = np.argmax(predictions) # Get highest probability index
51
+ predicted_class = CLASS_NAMES[str(predicted_class_index)] # Get class label
52
+
53
+ # Display predictions
54
+ st.write(f"Predictions Card : { predicted_class }")
prepare.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import hf_hub_download
2
+ import shutil
3
+ import os
4
+
5
+ # Hugging Face model details
6
+ REPO_ID = "xcurv/kcv-vanguard-day3-cnn-card-classification"
7
+ MODEL_FILENAME = "model.h5"
8
+ LABEL_JSON = "class.json"
9
+
10
+ def download_file(repo_id, filename, dest_filename):
11
+ file_path = hf_hub_download(repo_id=repo_id, filename=filename)
12
+
13
+ # Get the absolute path of the actual file (resolves symlinks)
14
+ real_file_path = os.path.realpath(file_path)
15
+
16
+ # Ensure the resolved file exists before copying
17
+ if not os.path.exists(real_file_path):
18
+ raise FileNotFoundError(f"Resolved file path does not exist: {real_file_path}")
19
+
20
+ # Copy the actual file to the destination
21
+ shutil.copy2(real_file_path, dest_filename)
22
+ os.remove(real_file_path)
23
+
24
+ # Download model if not present
25
+ if not os.path.exists(MODEL_FILENAME):
26
+ download_file(REPO_ID, MODEL_FILENAME, MODEL_FILENAME)
27
+
28
+ # Download label JSON if not present
29
+ if not os.path.exists(LABEL_JSON):
30
+ download_file(REPO_ID, LABEL_JSON, LABEL_JSON)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ streamlit
2
+ tensorflow
3
+ numpy
4
+ pillow
5
+ huggingface_hub