NickolayFM commited on
Commit
1eb9ee2
·
verified ·
1 Parent(s): 4b3a0e4

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +101 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,103 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ import torch
3
+ import numpy as np
4
+ from huggingface_hub import hf_hub_download
5
+ import pickle
6
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
7
+
8
+ st.set_page_config(
9
+ page_title="Anime Genre Classifier",
10
+ )
11
+
12
+ bert_model = "NickolayFM/ml2_hw_anime_space"
13
+
14
+ @st.cache_resource
15
+ def load_model():
16
+ tokenizer = AutoTokenizer.from_pretrained(bert_model)
17
+ model = AutoModelForSequenceClassification.from_pretrained(bert_model)
18
+ model.eval()
19
+
20
+ mlb_path = hf_hub_download(repo_id=bert_model, filename="mlb.pkl")
21
+ with open(mlb_path, "rb") as f:
22
+ mlb = pickle.load(f)
23
+
24
+ return tokenizer, model, mlb
25
+
26
+
27
+ def predict_genres(synopsis, tokenizer, model, mlb):
28
+ encoding = tokenizer(
29
+ synopsis,
30
+ truncation=True,
31
+ max_length=256,
32
+ padding="max_length",
33
+ return_tensors="pt"
34
+ )
35
+
36
+ with torch.no_grad():
37
+ outputs = model(
38
+ input_ids=encoding["input_ids"],
39
+ attention_mask=encoding["attention_mask"]
40
+ )
41
+
42
+ probs = torch.sigmoid(outputs.logits).cpu().numpy()[0]
43
+ total = probs.sum()
44
+ if total == 0:
45
+ return []
46
+ probs_norm = probs / total
47
+ sorted_idx = np.argsort(probs_norm)[::-1]
48
+ result = []
49
+ cumsum = 0.0
50
+ for idx in sorted_idx:
51
+ result.append((mlb.classes_[idx], float(probs[idx])))
52
+ cumsum += probs_norm[idx]
53
+ if cumsum >= 0.95:
54
+ break
55
+
56
+ return result
57
+
58
+
59
+ st.title("Anime Genre Classifier")
60
+ st.write("Введи описание аниме — модель предскажет жанры.")
61
+
62
+ synopsis = st.text_area(
63
+ label="Описание аниме (на АНГЛИЙСКОМ)",
64
+ placeholder="Примерчик: Determined to put his life back on track, Keyaru decided to unleash a powerful.",
65
+ height=100
66
+ )
67
+
68
+ predict_button = st.button("Показать жанры", type="primary")
69
+
70
+ if predict_button:
71
+ if not synopsis.strip():
72
+ st.warning("Ошибочка: пустое описание")
73
+ elif len(synopsis.strip().split()) < 5:
74
+ st.warning("Напиши хоть пару предложений")
75
+ else:
76
+ with st.spinner("Работаем"):
77
+ tokenizer, model, mlb = load_model()
78
+ genres = predict_genres(synopsis, tokenizer, model, mlb)
79
+ if not genres:
80
+ st.error("Ошибочка: не удалось определить жанры")
81
+ else:
82
+ st.subheader("Предсказанные жанры:")
83
+ for genre, prob in genres:
84
+ st.write(f"**{genre}**")
85
+ st.progress(float(prob))
86
+ st.caption(f"Вероятность: {prob:.4%}")
87
+
88
+ st.divider()
89
+ st.subheader("Примеры для теста:")
90
+
91
+
92
+ for title, text in {"Dragon Ball": "Goku is a young boy with a monkey tail and incredible strength. He embarks on a journey to collect the seven Dragon Balls, meeting friends and fighting powerful enemies along the way.", "Spirited Away": "A young girl named Chihiro wanders into a spirit world. Her parents are turned into pigs, and she must work in a bathhouse to save them and return to the human world.", "Death Note": "A high school student finds a supernatural notebook that allows him to kill anyone whose name he writes in it. He decides to use it to rid the world of criminals."}.items():
93
+ if st.button(f"📺 {title}"):
94
+ st.session_state["example_text"] = text
95
+ st.rerun()
96
 
97
+ if "example_text" in st.session_state:
98
+ st.text_area(
99
+ "Описание (из примера):",
100
+ value=st.session_state["example_text"],
101
+ height=100
102
+ )
103
+ del st.session_state["example_text"]