|
import os |
|
from groq import Groq |
|
import gradio as gr |
|
import pytesseract |
|
from sentence_transformers import SentenceTransformer, util |
|
from PIL import Image |
|
from typing import List |
|
import torch |
|
from transformers import BertTokenizer, BertModel |
|
import torch.nn.functional as F |
|
|
|
|
|
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') |
|
model = BertModel.from_pretrained('bert-base-uncased') |
|
sentence_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2') |
|
|
|
|
|
client = Groq(api_key=os.environ.get("GROQ_API_KEY")) |
|
|
|
|
|
def get_bert_embedding(text): |
|
inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True) |
|
with torch.no_grad(): |
|
outputs = model(**inputs) |
|
embeddings = outputs.last_hidden_state.mean(dim=1) |
|
return embeddings |
|
|
|
|
|
def calculate_cosine_similarity(embedding1, embedding2): |
|
similarity = F.cosine_similarity(embedding1, embedding2) |
|
return similarity.item() |
|
|
|
|
|
def calculate_sentence_similarity(text1, text2): |
|
embedding1 = sentence_model.encode(text1, convert_to_tensor=True) |
|
embedding2 = sentence_model.encode(text2, convert_to_tensor=True) |
|
return util.pytorch_cos_sim(embedding1, embedding2).item() |
|
|
|
|
|
def compare_answers(student_answer, teacher_answer): |
|
bert_similarity = calculate_cosine_similarity(get_bert_embedding(student_answer), get_bert_embedding(teacher_answer)) |
|
sentence_similarity = calculate_sentence_similarity(student_answer, teacher_answer) |
|
|
|
final_similarity = (0.5 * bert_similarity + 0.5 * sentence_similarity) |
|
return final_similarity |
|
|
|
|
|
def extract_keywords(text): |
|
|
|
return set(text.lower().split()) |
|
|
|
|
|
def check_keywords(student_answer, model_answer): |
|
student_keywords = extract_keywords(student_answer) |
|
teacher_keywords = extract_keywords(model_answer) |
|
keyword_overlap = len(student_keywords.intersection(teacher_keywords)) |
|
return keyword_overlap / len(teacher_keywords) |
|
|
|
|
|
def evaluate_answer(image, languages, model_answer): |
|
student_answer = extract_text_from_image(image, languages) |
|
semantic_similarity = compare_answers(student_answer, model_answer) |
|
keyword_similarity = check_keywords(student_answer, model_answer) |
|
|
|
|
|
combined_similarity = (semantic_similarity + keyword_similarity) / 2 |
|
grade = get_grade(combined_similarity) |
|
feedback = f"Student's answer: {student_answer}\nTeacher's answer: {model_answer}" |
|
badge = assign_badge(grade) |
|
detailed_feedback_msg = detailed_feedback(combined_similarity) |
|
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." |
|
return grade, combined_similarity * 100, feedback, badge, detailed_feedback_msg, prompt |
|
|
|
|
|
|
|
|
|
|
|
async def gradio_interface(image, languages: List[str], model_answer="The process of photosynthesis helps plants produce glucose using sunlight.", prompt="", history=[]): |
|
grade, similarity_score, feedback, badge, detailed_feedback_msg, prompt = evaluate_answer(image, languages, model_answer) |
|
response = "" |
|
async for result in chat_groq(prompt, history): |
|
response = result |
|
return grade, similarity_score, feedback, badge, detailed_feedback_msg, response |
|
|
|
|
|
language_choices = pytesseract.get_languages() |
|
|
|
|
|
interface = gr.Interface( |
|
fn=gradio_interface, |
|
inputs=[ |
|
gr.Image(type="filepath", label="Input"), |
|
gr.CheckboxGroup(language_choices, type="value", value=['eng'], label='Language'), |
|
gr.Textbox(lines=2, placeholder="Enter your model answer here", label="Model Answer"), |
|
gr.Textbox(lines=2, placeholder="Enter your prompt here", label="Prompt") |
|
], |
|
outputs=[ |
|
gr.Text(label="Grade"), |
|
gr.Number(label="Similarity Score (%)"), |
|
gr.Text(label="Feedback"), |
|
|
|
gr.Text(label="Badge"), |
|
gr.JSON(label="Detailed Feedback"), |
|
gr.Text(label="Generated Response") |
|
], |
|
title="Enhanced Automated Grading System", |
|
description="Upload an image of your answer sheet to get a grade from 1 to 5, similarity score, visual feedback, badge, and detailed feedback based on the model answer.", |
|
live=True |
|
) |
|
|
|
if __name__ == "__main__": |
|
interface.queue() |
|
interface.launch() |
|
|