Garvitj commited on
Commit
0b8902f
Β·
verified Β·
1 Parent(s): 48c1789

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -32
app.py CHANGED
@@ -9,9 +9,9 @@ import torch
9
  from transformers import BertTokenizer, BertModel
10
  import torch.nn.functional as F
11
 
12
- # Load pre-trained BERT model and tokenizer
13
  tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
14
- model = BertModel.from_pretrained('bert-base-uncased')
15
  sentence_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
16
 
17
  # Initialize Groq client
@@ -23,14 +23,11 @@ system_prompt = {
23
  "content": "You are a useful assistant. You reply with efficient answers."
24
  }
25
 
26
- # Function to interact with Groq for generating response
27
  async def chat_groq(message, history):
28
  messages = [system_prompt]
29
-
30
  for msg in history:
31
  messages.append({"role": "user", "content": str(msg[0])})
32
  messages.append({"role": "assistant", "content": str(msg[1])})
33
-
34
  messages.append({"role": "user", "content": str(message)})
35
 
36
  response_content = ''
@@ -49,13 +46,11 @@ async def chat_groq(message, history):
49
  response_content += chunk.choices[0].delta.content
50
  yield response_content
51
 
52
- # Extract text from an image using Tesseract
53
  def extract_text_from_image(filepath: str, languages: List[str]):
54
  image = Image.open(filepath)
55
- lang_str = '+'.join(languages) # Join languages for Tesseract
56
  return pytesseract.image_to_string(image=image, lang=lang_str)
57
 
58
- # Assign badges based on the grade
59
  def assign_badge(grade):
60
  if grade == 5:
61
  return "Gold Badge 🌟"
@@ -66,7 +61,6 @@ def assign_badge(grade):
66
  else:
67
  return "Keep Improving Badge πŸ’ͺ"
68
 
69
- # Categorize feedback into clarity, completeness, and accuracy
70
  def detailed_feedback(similarity_score):
71
  if similarity_score >= 0.9:
72
  return {"Clarity": "Excellent", "Completeness": "Complete", "Accuracy": "Accurate"}
@@ -77,7 +71,6 @@ def detailed_feedback(similarity_score):
77
  else:
78
  return {"Clarity": "Needs Improvement", "Completeness": "Incomplete", "Accuracy": "Inaccurate"}
79
 
80
- # Assign grades based on similarity score
81
  def get_grade(similarity_score):
82
  if similarity_score >= 0.9:
83
  return 5
@@ -90,59 +83,50 @@ def get_grade(similarity_score):
90
  else:
91
  return 1
92
 
93
- # Function to get BERT embeddings
94
  def get_bert_embedding(text):
95
  inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True)
96
  with torch.no_grad():
97
- outputs = model(**inputs)
98
  embeddings = outputs.last_hidden_state.mean(dim=1)
99
  return embeddings
100
 
101
- # Function to calculate cosine similarity
102
  def calculate_cosine_similarity(embedding1, embedding2):
103
  similarity = F.cosine_similarity(embedding1, embedding2)
104
  return similarity.item()
105
 
106
- # Function to calculate sentence embedding similarity
107
  def calculate_sentence_similarity(text1, text2):
108
  embedding1 = sentence_model.encode(text1, convert_to_tensor=True)
109
  embedding2 = sentence_model.encode(text2, convert_to_tensor=True)
110
  return util.pytorch_cos_sim(embedding1, embedding2).item()
111
 
112
- # Function to compare logic of student and teacher answers
113
  def compare_answers(student_answer, teacher_answer):
114
  bert_similarity = calculate_cosine_similarity(get_bert_embedding(student_answer), get_bert_embedding(teacher_answer))
115
-
116
- # Emphasize the importance of BERT similarity
117
  sentence_similarity = calculate_sentence_similarity(student_answer, teacher_answer)
118
-
119
  # Use a higher weight for BERT similarity
120
- final_similarity = (0.8 * bert_similarity + 0.2 * sentence_similarity)
121
  return final_similarity
122
 
123
- # Function to extract keywords from the model answer
124
  def extract_keywords(text):
125
  return set(text.lower().split())
126
 
127
- # Adjust grading based on key terms present in student answer
128
  def check_keywords(student_answer, model_answer):
129
  student_keywords = extract_keywords(student_answer)
130
  teacher_keywords = extract_keywords(model_answer)
131
  keyword_overlap = len(student_keywords.intersection(teacher_keywords))
132
- return keyword_overlap / (len(teacher_keywords) if len(teacher_keywords) > 0 else 1) # Ratio of matching keywords
133
 
134
- # Function to evaluate student's answer by comparing it to a model answer
135
  def evaluate_answer(image, languages, model_answer):
136
  student_answer = extract_text_from_image(image, languages)
137
 
138
- # Calculate semantic similarity primarily with BERT
139
  semantic_similarity = compare_answers(student_answer, model_answer)
140
 
141
- # Include keyword similarity
142
  keyword_similarity = check_keywords(student_answer, model_answer)
143
 
144
- # Combine semantic similarity with keyword presence check, emphasizing semantic similarity
145
- combined_similarity = (semantic_similarity + (0.5 * keyword_similarity)) / 1.5
146
  grade = get_grade(combined_similarity)
147
  feedback = f"Student's answer: {student_answer}\nTeacher's answer: {model_answer}"
148
  badge = assign_badge(grade)
@@ -150,18 +134,15 @@ def evaluate_answer(image, languages, model_answer):
150
  prompt = f"The student got grade: {grade} when the student's answer is: {student_answer} and the teacher's answer is: {model_answer}. Justify the grade given to the student."
151
  return grade, combined_similarity * 100, feedback, badge, detailed_feedback_msg, prompt
152
 
153
- # Main interface function for Gradio
154
  async def gradio_interface(image, languages: List[str], model_answer="The process of photosynthesis helps plants produce glucose using sunlight.", prompt="", history=[]):
155
  grade, similarity_score, feedback, badge, detailed_feedback_msg, prompt = evaluate_answer(image, languages, model_answer)
156
  response = ""
157
  async for result in chat_groq(prompt, history):
158
- response = result # Get the Groq response
159
  return grade, similarity_score, feedback, badge, detailed_feedback_msg, response
160
 
161
- # Get available Tesseract languages
162
  language_choices = pytesseract.get_languages()
163
 
164
- # Define Gradio interface
165
  interface = gr.Interface(
166
  fn=gradio_interface,
167
  inputs=[
@@ -174,7 +155,6 @@ interface = gr.Interface(
174
  gr.Text(label="Grade"),
175
  gr.Number(label="Similarity Score (%)"),
176
  gr.Text(label="Feedback"),
177
- # gr.HTML(label="Visual Feedback"),
178
  gr.Text(label="Badge"),
179
  gr.JSON(label="Detailed Feedback"),
180
  gr.Text(label="Generated Response")
 
9
  from transformers import BertTokenizer, BertModel
10
  import torch.nn.functional as F
11
 
12
+ # Load pre-trained models
13
  tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
14
+ bert_model = BertModel.from_pretrained('bert-base-uncased')
15
  sentence_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
16
 
17
  # Initialize Groq client
 
23
  "content": "You are a useful assistant. You reply with efficient answers."
24
  }
25
 
 
26
  async def chat_groq(message, history):
27
  messages = [system_prompt]
 
28
  for msg in history:
29
  messages.append({"role": "user", "content": str(msg[0])})
30
  messages.append({"role": "assistant", "content": str(msg[1])})
 
31
  messages.append({"role": "user", "content": str(message)})
32
 
33
  response_content = ''
 
46
  response_content += chunk.choices[0].delta.content
47
  yield response_content
48
 
 
49
  def extract_text_from_image(filepath: str, languages: List[str]):
50
  image = Image.open(filepath)
51
+ lang_str = '+'.join(languages)
52
  return pytesseract.image_to_string(image=image, lang=lang_str)
53
 
 
54
  def assign_badge(grade):
55
  if grade == 5:
56
  return "Gold Badge 🌟"
 
61
  else:
62
  return "Keep Improving Badge πŸ’ͺ"
63
 
 
64
  def detailed_feedback(similarity_score):
65
  if similarity_score >= 0.9:
66
  return {"Clarity": "Excellent", "Completeness": "Complete", "Accuracy": "Accurate"}
 
71
  else:
72
  return {"Clarity": "Needs Improvement", "Completeness": "Incomplete", "Accuracy": "Inaccurate"}
73
 
 
74
  def get_grade(similarity_score):
75
  if similarity_score >= 0.9:
76
  return 5
 
83
  else:
84
  return 1
85
 
 
86
  def get_bert_embedding(text):
87
  inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True)
88
  with torch.no_grad():
89
+ outputs = bert_model(**inputs)
90
  embeddings = outputs.last_hidden_state.mean(dim=1)
91
  return embeddings
92
 
 
93
  def calculate_cosine_similarity(embedding1, embedding2):
94
  similarity = F.cosine_similarity(embedding1, embedding2)
95
  return similarity.item()
96
 
 
97
  def calculate_sentence_similarity(text1, text2):
98
  embedding1 = sentence_model.encode(text1, convert_to_tensor=True)
99
  embedding2 = sentence_model.encode(text2, convert_to_tensor=True)
100
  return util.pytorch_cos_sim(embedding1, embedding2).item()
101
 
 
102
  def compare_answers(student_answer, teacher_answer):
103
  bert_similarity = calculate_cosine_similarity(get_bert_embedding(student_answer), get_bert_embedding(teacher_answer))
 
 
104
  sentence_similarity = calculate_sentence_similarity(student_answer, teacher_answer)
105
+
106
  # Use a higher weight for BERT similarity
107
+ final_similarity = (0.75 * bert_similarity + 0.25 * sentence_similarity)
108
  return final_similarity
109
 
 
110
  def extract_keywords(text):
111
  return set(text.lower().split())
112
 
 
113
  def check_keywords(student_answer, model_answer):
114
  student_keywords = extract_keywords(student_answer)
115
  teacher_keywords = extract_keywords(model_answer)
116
  keyword_overlap = len(student_keywords.intersection(teacher_keywords))
117
+ return keyword_overlap / (len(teacher_keywords) if len(teacher_keywords) > 0 else 1)
118
 
 
119
  def evaluate_answer(image, languages, model_answer):
120
  student_answer = extract_text_from_image(image, languages)
121
 
122
+ # Calculate semantic similarity
123
  semantic_similarity = compare_answers(student_answer, model_answer)
124
 
125
+ # Calculate keyword similarity
126
  keyword_similarity = check_keywords(student_answer, model_answer)
127
 
128
+ # Adjust the weight of keyword similarity
129
+ combined_similarity = (0.9 * semantic_similarity + 0.1 * keyword_similarity)
130
  grade = get_grade(combined_similarity)
131
  feedback = f"Student's answer: {student_answer}\nTeacher's answer: {model_answer}"
132
  badge = assign_badge(grade)
 
134
  prompt = f"The student got grade: {grade} when the student's answer is: {student_answer} and the teacher's answer is: {model_answer}. Justify the grade given to the student."
135
  return grade, combined_similarity * 100, feedback, badge, detailed_feedback_msg, prompt
136
 
 
137
  async def gradio_interface(image, languages: List[str], model_answer="The process of photosynthesis helps plants produce glucose using sunlight.", prompt="", history=[]):
138
  grade, similarity_score, feedback, badge, detailed_feedback_msg, prompt = evaluate_answer(image, languages, model_answer)
139
  response = ""
140
  async for result in chat_groq(prompt, history):
141
+ response = result
142
  return grade, similarity_score, feedback, badge, detailed_feedback_msg, response
143
 
 
144
  language_choices = pytesseract.get_languages()
145
 
 
146
  interface = gr.Interface(
147
  fn=gradio_interface,
148
  inputs=[
 
155
  gr.Text(label="Grade"),
156
  gr.Number(label="Similarity Score (%)"),
157
  gr.Text(label="Feedback"),
 
158
  gr.Text(label="Badge"),
159
  gr.JSON(label="Detailed Feedback"),
160
  gr.Text(label="Generated Response")