mcamargo00 commited on
Commit
2f64eb3
·
verified ·
1 Parent(s): 7b3feac

Upload 2 files

Browse files
Files changed (2) hide show
  1. README.md +26 -2
  2. app.py +75 -70
README.md CHANGED
@@ -1,8 +1,32 @@
 
 
1
  title: Math Solution Classifier
2
  emoji: 🧮
3
  colorFrom: blue
4
  colorTo: purple
5
  sdk: gradio
6
- sdk_version: 4.7.1
7
  app_file: app.py
8
- pinned: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # README.md for your Hugging Face Space
2
+ ---
3
  title: Math Solution Classifier
4
  emoji: 🧮
5
  colorFrom: blue
6
  colorTo: purple
7
  sdk: gradio
8
+ sdk_version: 4.44.0
9
  app_file: app.py
10
+ pinned: false
11
+ ---
12
+
13
+ # Math Solution Classifier
14
+
15
+ This application classifies math solutions into three categories:
16
+ - **Correct**: Solution is mathematically sound
17
+ - **Conceptually Flawed**: Wrong approach or understanding
18
+ - **Computationally Flawed**: Right approach, calculation errors
19
+
20
+ ## Usage
21
+
22
+ 1. Enter a math question
23
+ 2. Enter the proposed solution
24
+ 3. Click "Classify Solution"
25
+ 4. Get instant feedback on the solution quality
26
+
27
+ Built with Gradio and your custom trained model.
28
+
29
+ # requirements.txt
30
+ gradio==4.44.0
31
+ torch==2.1.0
32
+ transformers==4.35.0
app.py CHANGED
@@ -1,10 +1,6 @@
1
- # app.py - FastAPI backend for Math Solution Classifier
2
 
3
- from fastapi import FastAPI, HTTPException
4
- from fastapi.middleware.cors import CORSMiddleware
5
- from fastapi.staticfiles import StaticFiles
6
- from fastapi.responses import FileResponse
7
- from pydantic import BaseModel
8
  import torch
9
  from transformers import AutoTokenizer, AutoModelForSequenceClassification
10
  import logging
@@ -13,29 +9,10 @@ import logging
13
  logging.basicConfig(level=logging.INFO)
14
  logger = logging.getLogger(__name__)
15
 
16
- app = FastAPI(title="Math Solution Classifier API")
17
-
18
- # Add CORS middleware
19
- app.add_middleware(
20
- CORSMiddleware,
21
- allow_origins=["*"],
22
- allow_credentials=True,
23
- allow_methods=["*"],
24
- allow_headers=["*"],
25
- )
26
-
27
  # Global variables for model and tokenizer
28
  model = None
29
  tokenizer = None
30
- label_mapping = {0: "correct", 1: "conceptually-flawed", 2: "computationally-flawed"}
31
-
32
- class ClassificationRequest(BaseModel):
33
- question: str
34
- solution: str
35
-
36
- class ClassificationResponse(BaseModel):
37
- classification: str
38
- confidence: float
39
 
40
  def load_model():
41
  """Load your trained model here"""
@@ -64,16 +41,23 @@ def load_model():
64
  )
65
 
66
  logger.info("Model loaded successfully")
 
67
 
68
  except Exception as e:
69
  logger.error(f"Error loading model: {e}")
70
- raise
71
 
72
- def classify_solution(question: str, solution: str) -> tuple:
73
  """
74
  Classify the math solution
75
- Returns: (classification_label, confidence_score)
76
  """
 
 
 
 
 
 
77
  try:
78
  # Combine question and solution for input
79
  text_input = f"Question: {question}\nSolution: {solution}"
@@ -96,53 +80,74 @@ def classify_solution(question: str, solution: str) -> tuple:
96
 
97
  classification = label_mapping[predicted_class]
98
 
99
- return classification, confidence
 
 
 
 
 
 
 
 
 
100
 
101
  except Exception as e:
102
  logger.error(f"Error during classification: {e}")
103
- raise HTTPException(status_code=500, detail=f"Classification error: {str(e)}")
104
 
105
- @app.on_event("startup")
106
- async def startup_event():
107
- """Load model on startup"""
108
- logger.info("Loading model...")
109
- load_model()
110
 
111
- @app.post("/classify", response_model=ClassificationResponse)
112
- async def classify_math_solution(request: ClassificationRequest):
113
- """
114
- Classify a math solution as correct, conceptually flawed, or computationally flawed
115
- """
116
- if not model or not tokenizer:
117
- raise HTTPException(status_code=503, detail="Model not loaded")
118
-
119
- if not request.question.strip() or not request.solution.strip():
120
- raise HTTPException(status_code=400, detail="Both question and solution are required")
121
 
122
- try:
123
- classification, confidence = classify_solution(request.question, request.solution)
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
- return ClassificationResponse(
126
- classification=classification,
127
- confidence=confidence
128
- )
129
-
130
- except Exception as e:
131
- logger.error(f"Classification failed: {e}")
132
- raise HTTPException(status_code=500, detail="Classification failed")
133
-
134
- @app.get("/health")
135
- async def health_check():
136
- """Health check endpoint"""
137
- return {"status": "healthy", "model_loaded": model is not None}
138
-
139
- # Serve the frontend (for Hugging Face Spaces)
140
- app.mount("/static", StaticFiles(directory="static"), name="static")
141
-
142
- @app.get("/")
143
- async def serve_frontend():
144
- return FileResponse("static/index.html")
 
 
 
 
 
 
 
 
 
145
 
146
  if __name__ == "__main__":
147
- import uvicorn
148
- uvicorn.run(app, host="0.0.0.0", port=7860) # Port 7860 is standard for HF Spaces
 
1
+ # app.py - Gradio version (much simpler for HF Spaces)
2
 
3
+ import gradio as gr
 
 
 
 
4
  import torch
5
  from transformers import AutoTokenizer, AutoModelForSequenceClassification
6
  import logging
 
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
 
 
 
 
 
 
 
 
 
 
 
12
  # Global variables for model and tokenizer
13
  model = None
14
  tokenizer = None
15
+ label_mapping = {0: "✅ Correct", 1: "🤔 Conceptually Flawed", 2: "🔢 Computationally Flawed"}
 
 
 
 
 
 
 
 
16
 
17
  def load_model():
18
  """Load your trained model here"""
 
41
  )
42
 
43
  logger.info("Model loaded successfully")
44
+ return "Model loaded successfully!"
45
 
46
  except Exception as e:
47
  logger.error(f"Error loading model: {e}")
48
+ return f"Error loading model: {e}"
49
 
50
+ def classify_solution(question: str, solution: str):
51
  """
52
  Classify the math solution
53
+ Returns: (classification_label, confidence_score, explanation)
54
  """
55
+ if not question.strip() or not solution.strip():
56
+ return "Please fill in both fields", 0.0, ""
57
+
58
+ if not model or not tokenizer:
59
+ return "Model not loaded", 0.0, ""
60
+
61
  try:
62
  # Combine question and solution for input
63
  text_input = f"Question: {question}\nSolution: {solution}"
 
80
 
81
  classification = label_mapping[predicted_class]
82
 
83
+ # Create explanation based on classification
84
+ explanations = {
85
+ 0: "The mathematical approach and calculations are both sound.",
86
+ 1: "The approach or understanding has fundamental issues.",
87
+ 2: "The approach is correct, but there are calculation errors."
88
+ }
89
+
90
+ explanation = explanations[predicted_class]
91
+
92
+ return classification, f"{confidence:.2%}", explanation
93
 
94
  except Exception as e:
95
  logger.error(f"Error during classification: {e}")
96
+ return f"Classification error: {str(e)}", "0%", ""
97
 
98
+ # Load model on startup
99
+ load_model()
 
 
 
100
 
101
+ # Create Gradio interface
102
+ with gr.Blocks(title="Math Solution Classifier", theme=gr.themes.Soft()) as app:
103
+ gr.Markdown("# 🧮 Math Solution Classifier")
104
+ gr.Markdown("Classify math solutions as correct, conceptually flawed, or computationally flawed.")
 
 
 
 
 
 
105
 
106
+ with gr.Row():
107
+ with gr.Column():
108
+ question_input = gr.Textbox(
109
+ label="Math Question",
110
+ placeholder="e.g., Solve for x: 2x + 5 = 13",
111
+ lines=3
112
+ )
113
+
114
+ solution_input = gr.Textbox(
115
+ label="Proposed Solution",
116
+ placeholder="e.g., 2x + 5 = 13\n2x = 13 - 5\n2x = 8\nx = 4",
117
+ lines=5
118
+ )
119
+
120
+ classify_btn = gr.Button("Classify Solution", variant="primary")
121
 
122
+ with gr.Column():
123
+ classification_output = gr.Textbox(label="Classification", interactive=False)
124
+ confidence_output = gr.Textbox(label="Confidence", interactive=False)
125
+ explanation_output = gr.Textbox(label="Explanation", interactive=False, lines=3)
126
+
127
+ # Examples
128
+ gr.Examples(
129
+ examples=[
130
+ [
131
+ "Solve for x: 2x + 5 = 13",
132
+ "2x + 5 = 13\n2x = 13 - 5\n2x = 8\nx = 4"
133
+ ],
134
+ [
135
+ "Find the derivative of f(x) = x²",
136
+ "f'(x) = 2x + 1" # This should be computationally flawed
137
+ ],
138
+ [
139
+ "What is 15% of 200?",
140
+ "15% = 15/100 = 0.15\n0.15 × 200 = 30"
141
+ ]
142
+ ],
143
+ inputs=[question_input, solution_input]
144
+ )
145
+
146
+ classify_btn.click(
147
+ fn=classify_solution,
148
+ inputs=[question_input, solution_input],
149
+ outputs=[classification_output, confidence_output, explanation_output]
150
+ )
151
 
152
  if __name__ == "__main__":
153
+ app.launch()