Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import tensorflow as tf | |
| import keras | |
| import numpy as np | |
| import pickle | |
| from tensorflow.keras.preprocessing.sequence import pad_sequences | |
| import re | |
| import os | |
| # Define and register the custom Perplexity metric | |
| class Perplexity(keras.metrics.Metric): | |
| def __init__(self, name='perplexity', dtype=None, **kwargs): | |
| super().__init__(name=name, dtype=dtype, **kwargs) | |
| self.cross_entropy = keras.metrics.Mean(name='cross_entropy') | |
| def update_state(self, y_true, y_pred, sample_weight=None): | |
| # Calculate cross-entropy | |
| cross_entropy_values = tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred) | |
| # Update the internal mean metric | |
| self.cross_entropy.update_state(cross_entropy_values, sample_weight) | |
| def result(self): | |
| # Perplexity is the exponential of the cross-entropy | |
| return tf.exp(self.cross_entropy.result()) | |
| def reset_state(self): | |
| self.cross_entropy.reset_state() | |
| def get_config(self): | |
| config = super().get_config() | |
| return config | |
| # Text cleaning function | |
| def clean_text(text): | |
| text = re.sub(r'[^\w\s.,!?]', '', text) | |
| text = re.sub(r'\b\d+\b', '', text) | |
| text = text.replace('co2', 'carbon dioxide') | |
| text = text.lower() | |
| text = ' '.join(text.split()) | |
| return text | |
| # Load models and tokenizers | |
| def load_models(): | |
| print("Loading models and tokenizers...") | |
| # Load models with custom objects for Perplexity | |
| custom_objects = {'Perplexity': Perplexity} | |
| try: | |
| with keras.saving.custom_object_scope(custom_objects): | |
| classifier_model = keras.models.load_model('classifier_model.keras') | |
| textgen_model = keras.models.load_model('textgen_model.keras') | |
| print("Models loaded successfully with custom objects") | |
| except Exception as e: | |
| print(f"Error loading models with custom objects: {e}") | |
| raise | |
| # Load tokenizers | |
| try: | |
| with open('classifier_tokenizer.pkl', 'rb') as handle: | |
| classifier_tokenizer = pickle.load(handle) | |
| with open('textgen_tokenizer.pkl', 'rb') as handle: | |
| textgen_tokenizer = pickle.load(handle) | |
| print("Tokenizers loaded successfully") | |
| except Exception as e: | |
| print(f"Error loading tokenizers: {e}") | |
| raise | |
| return classifier_model, classifier_tokenizer, textgen_model, textgen_tokenizer | |
| # Classification function | |
| def classify_text(text, model, tokenizer): | |
| cleaned_text = clean_text(text) | |
| sequence = tokenizer.texts_to_sequences([cleaned_text]) | |
| padded = pad_sequences(sequence, maxlen=255, padding='pre') | |
| prediction = model.predict(padded)[0] | |
| # Get the highest probability class | |
| class_idx = np.argmax(prediction) | |
| classes = ['Science', 'Maths', 'History'] | |
| confidence = prediction[class_idx] * 100 | |
| return classes[class_idx], confidence | |
| # Text generation function | |
| def generate_text(prompt, model, tokenizer, max_length=50, temperature=0.7): | |
| cleaned_prompt = clean_text(prompt) | |
| input_text = cleaned_prompt | |
| for _ in range(max_length): | |
| token_list = tokenizer.texts_to_sequences([input_text])[0] | |
| token_list = pad_sequences([token_list], maxlen=255, padding='pre') | |
| predicted = model.predict(token_list, verbose=0)[0] | |
| # Apply temperature | |
| predicted = np.log(predicted) / temperature | |
| exp_preds = np.exp(predicted) | |
| predicted = exp_preds / np.sum(exp_preds) | |
| # Sample from the distribution | |
| predicted_index = np.random.choice(len(predicted), p=predicted) | |
| output_word = "" | |
| for word, index in tokenizer.word_index.items(): | |
| if index == predicted_index: | |
| output_word = word | |
| break | |
| if output_word == "": | |
| break | |
| input_text += " " + output_word | |
| return input_text | |
| # Print environment info for debugging | |
| print(f"TensorFlow version: {tf.__version__}") | |
| print(f"Keras version: {tf.keras.__version__}") | |
| print(f"Current directory contents: {os.listdir('.')}") | |
| # Load models with error handling | |
| try: | |
| print("Starting model loading process...") | |
| classifier_model, classifier_tokenizer, textgen_model, textgen_tokenizer = load_models() | |
| print("Models and tokenizers loaded successfully") | |
| except Exception as e: | |
| print(f"Error in model loading process: {e}") | |
| raise | |
| # Create Gradio interface functions | |
| def classify_interface(text): | |
| subject, confidence = classify_text(text, classifier_model, classifier_tokenizer) | |
| return f"Subject: {subject} (Confidence: {confidence:.2f}%)" | |
| def generate_interface(prompt, length=50, temp=0.7): | |
| return generate_text(prompt, textgen_model, textgen_tokenizer, max_length=int(length), temperature=float(temp)) | |
| # Create Gradio interface | |
| with gr.Blocks(title="Science Text Analyzer") as demo: | |
| gr.Markdown("# Science Text Analyzer") | |
| with gr.Tab("Classify Text"): | |
| gr.Markdown("### Classify Academic Text") | |
| gr.Markdown( | |
| "This tool automatically classifies a given passage into one of the following academic categories: " | |
| "**Science**, **Mathematics**, or **History**. Simply enter your text below to see the predicted subject." | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| text_input = gr.Textbox(label="Enter Text", lines=5, placeholder="Paste a sentence or paragraph here...") | |
| classify_button = gr.Button("Classify") | |
| with gr.Column(): | |
| output = gr.Textbox(label="Classification Result", placeholder="The predicted subject and confidence will appear here.") | |
| classify_button.click(fn=classify_interface, inputs=text_input, outputs=output) | |
| with gr.Tab("Generate Text"): | |
| gr.Markdown("### Generate Academic Text") | |
| gr.Markdown( | |
| "Use this tool to generate educational text based on a given prompt. " | |
| "You can control the output length and creativity using the sliders below." | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| prompt_input = gr.Textbox(label="Enter a Prompt", lines=3, placeholder="Type an introductory sentence or concept...") | |
| length_slider = gr.Slider(minimum=10, maximum=200, value=50, step=10, label="Maximum Length (words)") | |
| temp_slider = gr.Slider(minimum=0.1, maximum=1.5, value=0.7, step=0.1, label="Temperature (Creativity Level)") | |
| generate_button = gr.Button("Generate") | |
| with gr.Column(): | |
| generated_output = gr.Textbox(label="Generated Text", lines=8, placeholder="The generated text will appear here.") | |
| generate_button.click(fn=generate_interface, inputs=[prompt_input, length_slider, temp_slider], outputs=generated_output) | |
| gr.Markdown("### About This App") | |
| gr.Markdown( | |
| "The Science Text Analyzer uses deep learning models trained on academic corpora to classify and generate content " | |
| "relevant to disciplines such as Science, Mathematics, and History. It combines a classifier with a sequence-based language model " | |
| "to support educational research and content creation." | |
| ) | |
| # Launch the app | |
| demo.launch() | |