Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
import gradio as gr
|
4 |
+
import re
|
5 |
+
|
6 |
+
# ---------- Dictionaries of words for each "layer" ----------
|
7 |
+
# Layer 1: basic positive/negative detection
|
8 |
+
positive_words = {"love", "great", "good", "amazing", "awesome", "happy"}
|
9 |
+
negative_words = {"hate", "terrible", "awful", "bad", "horrible", "sad"}
|
10 |
+
|
11 |
+
# Layer 2: sarcasm or contradictory cues
|
12 |
+
sarcasm_cues = {"not!", "jk", "/s"} # e.g. "The food was great, not!"
|
13 |
+
|
14 |
+
# Layer 3: intensifiers
|
15 |
+
intensifiers = {"very", "extremely", "so", "super", "really"}
|
16 |
+
|
17 |
+
# ----------------------------------------------------------------
|
18 |
+
# 1) Classification Layers
|
19 |
+
# ----------------------------------------------------------------
|
20 |
+
|
21 |
+
def layer_1_basic(text):
|
22 |
+
"""
|
23 |
+
Layer 1:
|
24 |
+
- Count how many known positive words vs. negative words.
|
25 |
+
- If pos >= neg, label = "Positive", else "Negative"
|
26 |
+
"""
|
27 |
+
words = re.findall(r"[a-zA-Z]+", text.lower())
|
28 |
+
pos_count = sum(1 for w in words if w in positive_words)
|
29 |
+
neg_count = sum(1 for w in words if w in negative_words)
|
30 |
+
|
31 |
+
label = "Positive" if pos_count >= neg_count else "Negative"
|
32 |
+
return label, pos_count, neg_count
|
33 |
+
|
34 |
+
def layer_2_sarcasm_or_flip(text, prev_label):
|
35 |
+
"""
|
36 |
+
Layer 2:
|
37 |
+
- Check for sarcasm cues (like "not!", "jk", "/s").
|
38 |
+
- If found, flip the classification from Layer 1.
|
39 |
+
"""
|
40 |
+
text_lower = text.lower()
|
41 |
+
if any(cue in text_lower for cue in sarcasm_cues):
|
42 |
+
flipped = "Positive" if prev_label == "Negative" else "Negative"
|
43 |
+
return flipped + " (sarcasm-corrected)"
|
44 |
+
else:
|
45 |
+
return prev_label
|
46 |
+
|
47 |
+
def layer_3_intensifiers(text, prev_label):
|
48 |
+
"""
|
49 |
+
Layer 3:
|
50 |
+
- If there's an intensifier ("very", "extremely", "so", "super", "really"),
|
51 |
+
we add "(HIGH CONFIDENCE)" to the label.
|
52 |
+
"""
|
53 |
+
text_lower = text.lower()
|
54 |
+
if any(i in text_lower for i in intensifiers):
|
55 |
+
return prev_label + " (HIGH CONFIDENCE)"
|
56 |
+
else:
|
57 |
+
return prev_label
|
58 |
+
|
59 |
+
def deep_classify(text):
|
60 |
+
"""
|
61 |
+
Pass text through 3 layers, returning a final classification
|
62 |
+
plus details about each layer.
|
63 |
+
"""
|
64 |
+
# LAYER 1
|
65 |
+
layer1_label, pos_count, neg_count = layer_1_basic(text)
|
66 |
+
|
67 |
+
# LAYER 2
|
68 |
+
layer2_label = layer_2_sarcasm_or_flip(text, layer1_label)
|
69 |
+
|
70 |
+
# LAYER 3
|
71 |
+
final_label = layer_3_intensifiers(text, layer2_label)
|
72 |
+
|
73 |
+
return layer1_label, layer2_label, final_label, pos_count, neg_count
|
74 |
+
|
75 |
+
# ----------------------------------------------------------------
|
76 |
+
# 2) Gradio Demo
|
77 |
+
# ----------------------------------------------------------------
|
78 |
+
|
79 |
+
# Some sample statements from your original dropdown
|
80 |
+
sample_statements = [
|
81 |
+
"I love this movie!",
|
82 |
+
"This place is awful.",
|
83 |
+
"The food was amazing, not!",
|
84 |
+
"I'm so happy right now.",
|
85 |
+
"Everything was terrible... JK!",
|
86 |
+
"I really hate slow service.",
|
87 |
+
"This is so good, I'm super impressed.",
|
88 |
+
]
|
89 |
+
|
90 |
+
def simulate_layers(sample_choice, custom_text):
|
91 |
+
"""
|
92 |
+
1) If the user typed something in 'custom_text', use that.
|
93 |
+
2) Otherwise, use the selected 'sample_choice'.
|
94 |
+
3) Run the text through the 3-layer classification.
|
95 |
+
4) Return an HTML block describing each layer's result.
|
96 |
+
"""
|
97 |
+
text_to_classify = ""
|
98 |
+
if custom_text.strip():
|
99 |
+
text_to_classify = custom_text.strip()
|
100 |
+
elif sample_choice:
|
101 |
+
text_to_classify = sample_choice
|
102 |
+
else:
|
103 |
+
return "<p style='color:red;'>Please provide a sentence.</p>"
|
104 |
+
|
105 |
+
layer1_label, layer2_label, final_label, pos_count, neg_count = deep_classify(text_to_classify)
|
106 |
+
|
107 |
+
# Build HTML explanation
|
108 |
+
html_output = f"""
|
109 |
+
<h3>Deep Learning Simulation</h3>
|
110 |
+
<p><b>Input Text:</b> {text_to_classify}</p>
|
111 |
+
|
112 |
+
<ol>
|
113 |
+
<li><b>Layer 1</b> checks positive vs. negative words (simple count).
|
114 |
+
<br>Positive words found: {pos_count}, Negative words found: {neg_count}
|
115 |
+
<br>Layer 1 Classification: <i>{layer1_label}</i>
|
116 |
+
</li>
|
117 |
+
<li><b>Layer 2</b> checks for sarcasm cues (like "not!", "jk", "/s").
|
118 |
+
<br>Result after sarcasm check: <i>{layer2_label}</i>
|
119 |
+
</li>
|
120 |
+
<li><b>Layer 3</b> looks for intensifiers ("very", "extremely", "so", "super", "really").
|
121 |
+
<br>Final Classification: <span style="color:blue; font-weight:bold;">{final_label}</span>
|
122 |
+
</li>
|
123 |
+
</ol>
|
124 |
+
|
125 |
+
<h4>How this relates to Deep Learning</h4>
|
126 |
+
<ul>
|
127 |
+
<li>In actual deep learning, each layer learns more complex
|
128 |
+
<i>features</i> automatically from data, rather than
|
129 |
+
using manually defined checks.</li>
|
130 |
+
<li>However, the <b>concept</b> of passing through multiple
|
131 |
+
layers to refine the result <i>is</i> how neural networks work.</li>
|
132 |
+
</ul>
|
133 |
+
|
134 |
+
<p><b>Observation:</b> This layered approach can handle nuances
|
135 |
+
like sarcasm or intensifiers better than a single rule or single-layer model.</p>
|
136 |
+
"""
|
137 |
+
return html_output
|
138 |
+
|
139 |
+
with gr.Blocks() as demo:
|
140 |
+
gr.Markdown("##Deep Learning (Layered Approach) Simulation")
|
141 |
+
gr.Markdown("Pick a sample statement **or** type your own, then click **Simulate**.")
|
142 |
+
|
143 |
+
with gr.Row():
|
144 |
+
sample_choice = gr.Dropdown(
|
145 |
+
label="Sample Statement",
|
146 |
+
choices=["(None)"] + sample_statements,
|
147 |
+
value="(None)",
|
148 |
+
)
|
149 |
+
custom_text = gr.Textbox(
|
150 |
+
label="Custom Text",
|
151 |
+
placeholder="Type your own statement here..."
|
152 |
+
)
|
153 |
+
simulate_button = gr.Button("Simulate Layers")
|
154 |
+
output = gr.HTML()
|
155 |
+
|
156 |
+
def simulate_wrapper(smpl, cstm):
|
157 |
+
# If the user picks "(None)", interpret that as an empty choice
|
158 |
+
if smpl == "(None)":
|
159 |
+
smpl = ""
|
160 |
+
return simulate_layers(smpl, cstm)
|
161 |
+
|
162 |
+
simulate_button.click(
|
163 |
+
fn=simulate_wrapper,
|
164 |
+
inputs=[sample_choice, custom_text],
|
165 |
+
outputs=[output]
|
166 |
+
)
|
167 |
+
|
168 |
+
demo.launch()
|