Claudineuwa commited on
Commit
88b7bf6
·
verified ·
1 Parent(s): 50188ec

Upload folder using huggingface_hub

Browse files
Files changed (6) hide show
  1. .gitmodules +0 -0
  2. app.py +168 -0
  3. config.json +33 -0
  4. model.safetensors +3 -0
  5. preprocessor_config.json +31 -0
  6. requirements.txt +8 -0
.gitmodules ADDED
File without changes
app.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ from flask_cors import CORS
3
+ from transformers import AutoImageProcessor, AutoModelForImageClassification
4
+ from PIL import Image
5
+ import torch
6
+ import io
7
+ import os
8
+ from pathlib import Path
9
+ import logging
10
+
11
+ # Set up logging
12
+ logging.basicConfig(level=logging.INFO)
13
+ logger = logging.getLogger(__name__)
14
+
15
+ app = Flask(__name__)
16
+ CORS(app)
17
+
18
+ # Fix the model path - should match your submodule name
19
+ MODEL_PATH = os.path.join(os.path.dirname(__file__), "waste_classifier_Isaac")
20
+
21
+ LABEL2INFO = {
22
+ 0: {
23
+ "label": "biodegradable",
24
+ "description": "Easily breaks down naturally. Good for composting.",
25
+ "recyclable": False,
26
+ "disposal": "Use compost or organic bin",
27
+ "example_items": ["banana peel", "food waste", "paper"],
28
+ "environmental_benefit": "Composting biodegradable waste returns nutrients to the soil, reduces landfill use, and lowers greenhouse gas emissions.",
29
+ "protection_tip": "Compost at home or use municipal organic waste bins. Avoid mixing with plastics or hazardous waste.",
30
+ "poor_disposal_effects": "If disposed of improperly, biodegradable waste can cause methane emissions in landfills and contribute to water pollution and eutrophication."
31
+ },
32
+ 1: {
33
+ "label": "non_biodegradable",
34
+ "description": "Does not break down easily. Should be disposed of carefully.",
35
+ "recyclable": False,
36
+ "disposal": "Use general waste bin or recycling if possible",
37
+ "example_items": ["plastic bag", "styrofoam", "metal can"],
38
+ "environmental_benefit": "Proper disposal and recycling of non-biodegradable waste reduces pollution, conserves resources, and protects wildlife.",
39
+ "protection_tip": "Reduce use, reuse items, and recycle whenever possible. Never burn or dump in nature.",
40
+ "poor_disposal_effects": "Improper disposal leads to soil and water pollution, harms wildlife, and causes long-term environmental damage. Plastics can persist for hundreds of years."
41
+ }
42
+ }
43
+
44
+ # Global variables for model and processor
45
+ model = None
46
+ image_processor = None
47
+
48
+ def load_model():
49
+ """Load the model with proper error handling"""
50
+ global model, image_processor
51
+
52
+ logger.info(f"Attempting to load model from: {MODEL_PATH}")
53
+
54
+ # Check if the model path exists
55
+ if not os.path.exists(MODEL_PATH):
56
+ logger.error(f"Model path does not exist: {MODEL_PATH}")
57
+ # List available directories for debugging
58
+ current_dir = os.path.dirname(__file__)
59
+ available_dirs = [d for d in os.listdir(current_dir) if os.path.isdir(os.path.join(current_dir, d))]
60
+ logger.info(f"Available directories: {available_dirs}")
61
+ raise FileNotFoundError(f"Model path does not exist: {MODEL_PATH}")
62
+
63
+ # Load model and processor with local_files_only=True
64
+ try:
65
+ logger.info("Loading model...")
66
+ # Try different model types based on the actual model
67
+ try:
68
+ model = AutoModelForImageClassification.from_pretrained(
69
+ MODEL_PATH,
70
+ local_files_only=True
71
+ )
72
+ except ValueError as e:
73
+ logger.warning(f"Failed to load as ImageClassification model: {e}")
74
+ # If it's an OPT model, try loading it differently
75
+ from transformers import AutoModel
76
+ model = AutoModel.from_pretrained(
77
+ MODEL_PATH,
78
+ local_files_only=True
79
+ )
80
+
81
+ logger.info("Loading image processor...")
82
+ try:
83
+ image_processor = AutoImageProcessor.from_pretrained(
84
+ MODEL_PATH,
85
+ local_files_only=True
86
+ )
87
+ except Exception as e:
88
+ logger.warning(f"Failed to load AutoImageProcessor: {e}")
89
+ # Try alternative processors
90
+ from transformers import AutoProcessor
91
+ image_processor = AutoProcessor.from_pretrained(
92
+ MODEL_PATH,
93
+ local_files_only=True
94
+ )
95
+ model.eval()
96
+ logger.info("Model and processor loaded successfully!")
97
+ return True
98
+ except Exception as e:
99
+ logger.error(f"Error loading model: {e}")
100
+ return False
101
+
102
+ def predict_image(image_bytes, device="cpu"):
103
+ """Predict image classification"""
104
+ if model is None or image_processor is None:
105
+ raise RuntimeError("Model not loaded properly")
106
+
107
+ try:
108
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
109
+ inputs = image_processor(images=image, return_tensors="pt")
110
+ inputs = {k: v.to(device) for k, v in inputs.items()}
111
+
112
+ with torch.no_grad():
113
+ outputs = model(**inputs)
114
+ probs = torch.softmax(outputs.logits, dim=1)
115
+ conf, pred = torch.max(probs, dim=1)
116
+ label_id = pred.item()
117
+ confidence = conf.item()
118
+
119
+ info = LABEL2INFO[label_id].copy()
120
+ info["confidence"] = round(confidence, 2)
121
+ info["eco_points_earned"] = 10 # Dummy value
122
+ return info
123
+ except Exception as e:
124
+ logger.error(f"Error in prediction: {e}")
125
+ raise
126
+
127
+ @app.route('/', methods=['GET'])
128
+ def health_check():
129
+ """Health check endpoint"""
130
+ return jsonify({"status": "healthy", "model_loaded": model is not None})
131
+
132
+ @app.route('/classify', methods=['POST'])
133
+ def classify():
134
+ """Classification endpoint"""
135
+ if model is None or image_processor is None:
136
+ return jsonify({"error": "Model not loaded"}), 500
137
+
138
+ try:
139
+ results = []
140
+ files = request.files.getlist('images')
141
+
142
+ if not files:
143
+ return jsonify({"error": "No images provided"}), 400
144
+
145
+ for file in files:
146
+ if file.filename == '':
147
+ continue
148
+ image_bytes = file.read()
149
+ result = predict_image(image_bytes)
150
+ results.append(result)
151
+
152
+ return jsonify({"results": results})
153
+ except Exception as e:
154
+ logger.error(f"Error in classify: {e}")
155
+ return jsonify({"error": str(e)}), 500
156
+
157
+ # Initialize the model when the app starts
158
+ logger.info("Starting Flask app...")
159
+ model_loaded = load_model()
160
+
161
+ if not model_loaded:
162
+ logger.warning("App starting without model - some features may not work")
163
+
164
+ if __name__ == '__main__':
165
+ # Use environment PORT for deployment, fallback to 5000 for local
166
+ port = int(os.environ.get("PORT", 5000))
167
+ # Bind to 0.0.0.0 for deployment, disable debug in production
168
+ app.run(host="0.0.0.0", port=port, debug=False)
config.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ViTForImageClassification"
4
+ ],
5
+ "attention_probs_dropout_prob": 0.0,
6
+ "encoder_stride": 16,
7
+ "hidden_act": "gelu",
8
+ "hidden_dropout_prob": 0.0,
9
+ "hidden_size": 768,
10
+ "id2label": {
11
+ "0": "biodegradable",
12
+ "1": "non_biodegradable"
13
+ },
14
+ "image_size": 224,
15
+ "initializer_range": 0.02,
16
+ "intermediate_size": 3072,
17
+ "label2id": {
18
+ "biodegradable": 0,
19
+ "non_biodegradable": 1
20
+ },
21
+ "layer_norm_eps": 1e-12,
22
+ "model_type": "vit",
23
+ "num_attention_heads": 12,
24
+ "num_channels": 3,
25
+ "num_hidden_layers": 12,
26
+ "patch_size": 16,
27
+ "pooler_act": "tanh",
28
+ "pooler_output_size": 768,
29
+ "problem_type": "single_label_classification",
30
+ "qkv_bias": true,
31
+ "torch_dtype": "float32",
32
+ "transformers_version": "4.53.2"
33
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:af8a93025faf3e4fd053b12c9825a286a22ec22f64a50a8f27728a73cd5c078b
3
+ size 343223968
preprocessor_config.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "crop_size": null,
3
+ "data_format": "channels_first",
4
+ "default_to_square": true,
5
+ "device": null,
6
+ "disable_grouping": null,
7
+ "do_center_crop": null,
8
+ "do_convert_rgb": null,
9
+ "do_normalize": true,
10
+ "do_rescale": true,
11
+ "do_resize": true,
12
+ "image_mean": [
13
+ 0.5,
14
+ 0.5,
15
+ 0.5
16
+ ],
17
+ "image_processor_type": "ViTImageProcessorFast",
18
+ "image_std": [
19
+ 0.5,
20
+ 0.5,
21
+ 0.5
22
+ ],
23
+ "input_data_format": null,
24
+ "resample": 2,
25
+ "rescale_factor": 0.00392156862745098,
26
+ "return_tensors": null,
27
+ "size": {
28
+ "height": 224,
29
+ "width": 224
30
+ }
31
+ }
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ torchvision>=0.15.0
3
+ transformers>=4.30.0
4
+ datasets>=2.10.0
5
+ scikit-learn>=1.0.0
6
+ flask>=2.0.0
7
+ flask-cors>=3.0.10
8
+ pillow>=9.0.0