E-Adam commited on
Commit
32fdebd
·
verified ·
1 Parent(s): 02df8e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +292 -220
app.py CHANGED
@@ -1,245 +1,317 @@
1
- import sys
2
  import subprocess
3
- import importlib
4
- import os
5
- os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
6
- #import subprocess
7
- #subprocess.check_call([sys.executable, "-m", "pip", "install", "tensorflow-cpu"])
8
-
9
  import gradio as gr
10
  import numpy as np
11
 
12
- def install_tensorflow_with_deps():
13
- packages_to_install = [
14
- "absl-py",
15
- "six",
16
- "numpy",
17
- "protobuf",
18
- "tensorflow-cpu==2.19.0"
19
- ]
20
-
21
- for package in packages_to_install:
22
- try:
23
- print(f"Installation de {package}...")
24
- subprocess.check_call([
25
- sys.executable, "-m", "pip", "install",
26
- package, "--quiet", "--no-warn-script-location"
27
- ])
28
- except Exception as e:
29
- print(f"Erreur avec {package}: {e}")
30
-
31
- try:
32
- import tensorflow as tf
33
- print(f"✓ TensorFlow {tf.__version__} prêt")
34
- return tf
35
- except Exception as e:
36
- print(f"✗ Erreur finale: {e}")
37
- return None
38
 
39
- # Usage
40
- tf = install_tensorflow_with_deps()
41
 
42
- if tf is not None:
43
- from tensorflow.keras.models import Sequential
44
- from tensorflow.keras.layers import Embedding, GRU, Dense
45
- from tensorflow.keras.preprocessing.text import Tokenizer
46
- from tensorflow.keras.preprocessing.sequence import pad_sequences
47
-
48
- #creation du model
49
- model = Sequential()
50
- # analyse du texte
51
- tokenizer = Tokenizer()
52
-
53
- max_sequence_len=0
54
-
55
- textes = [
56
- "la goutte d'eau qui fait déborder le vase",
57
- "Il n'y a pas de fumée sans feu",
58
- "Il faut battre le fer tant qu'il est chaud",
59
- "Il ne faut pas mettre tous ses oeufs dans le même panier",
60
- "Il faut tourner sept fois sa langue dans sa bouche avant de parler",
61
- "L'habit ne fait pas le moine",
62
- "Il ne faut pas réveiller le chat qui dort",
63
- "Il faut se méfier de l'eau qui dort",
64
- "C'est l'hôpital qui se moque de la charité",
65
- "Qui vole un oeuf vole un boeuf",
66
- "Chercher midi à quatorze heures",
67
- "Avoir un poil dans la main",
68
- "Être dans de beaux draps",
69
- "Avoir la tête dans les nuages",
70
- "Mettre les pieds dans le plat"]
71
-
72
-
73
- def afficher_liste(liste):
74
- return "\n".join(liste)
75
-
76
- def ajouter_a_liste(liste_actuelle, nouveau_texte):
77
- if nouveau_texte:
78
- liste_actuelle.append(nouveau_texte)
79
- return liste_actuelle, ""
80
-
81
- def supprimer_de_liste(liste_actuelle, index_a_supprimer):
82
- if index_a_supprimer is not None and 0 <= index_a_supprimer < len(liste_actuelle):
83
- ligne_supprimee = liste_actuelle.pop(index_a_supprimer)
84
- message = f"Ligne supprimée : '{ligne_supprimee}'"
85
  else:
86
- message = "Aucune ligne sélectionnée pour suppression"
87
- return liste_actuelle, liste_actuelle, message # Liste mise à jour, choix mis à jour, message
88
-
89
- def apprendre(liste_actuelle):
90
- global max_sequence_len
91
- # Traiter la liste finale
92
- resultat = ", ".join(liste_actuelle)
93
- print("Liste soumise:", liste_actuelle) # Pour voir dans la console
94
- # analyse du texte
95
- tokenizer.fit_on_texts(liste_actuelle)
96
- total_words = len(tokenizer.word_index) + 1
97
- print("nb de mots différents rencontrés :", total_words)
98
- type(tokenizer.word_index)
99
- #from dict to list
100
- liste = list(tokenizer.word_index.keys())
101
- print("voici les premiers mots trouvés : ")
102
- for i in range(10): print(f"({i+1}:'{liste[i]}')", end= ", ")
103
- print()
104
- # transformation des textes en vecteurs
105
- input_sequences = []
106
- for sentence in liste_actuelle:
107
- token_list = tokenizer.texts_to_sequences([sentence])[0]
108
- for i in range(1, len(token_list)):
109
- n_gram_sequence = token_list[:i+1]
110
- input_sequences.append(n_gram_sequence)
111
- # calibrage des vecteurs pour qu'ils aient tous la même longueur
112
- max_sequence_len = max([len(x) for x in input_sequences])
113
- input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  print("la phrase '", liste_actuelle[0], "' est traduite en plusieurs vecteurs :")
115
- split = liste_actuelle[0].split()
116
- for i in range(6):
117
  print(input_sequences[i], end=" -> '")
118
- for j in range(i+2):
119
  print(split[j], end=" ")
120
  print("'")
121
- # creer les x (premieres valeurs de chaque vecteur)
122
- X = input_sequences[:, :-1]
123
- # creer les y (derniere valeur de chaque vecteur)
124
- y = input_sequences[:, -1]
125
- # chaque mot de sortie est représenté par un vecteur de 0, avec 1 correspondant à l'indice du mot
126
- #donc le vecteur est aussi grand que le nb de mots trouvés
127
- y = tf.keras.utils.to_categorical(y, num_classes=total_words)
128
- #creation du model
129
- model.add(Embedding(total_words, 50, input_length=max_sequence_len-1))
130
- model.add(GRU(120, return_sequences=False))
131
- model.add(Dense(total_words, activation='softmax'))
132
- # Compile the model
133
- model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
134
- # entrainer le modele
135
- print("patienter 30s pendant l'entrainement...")
136
- model.fit(X, y, epochs=300, verbose=0)
137
- return f"Entrainement effectué, saisissez un début de phrase pour demander la suite"
138
-
139
-
140
- # fonction pour prédire le mot suivant
141
- def predict_next_word(start_text, nb_words):
142
- print("===> start_text=",start_text)
143
- print(f"prédictions de {nb_words} mots.")
144
- for _ in range(nb_words):
145
- token_list = tokenizer.texts_to_sequences([start_text])[0]
146
- token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
147
- print("===> token_list=",token_list)
148
- predicted = np.argmax(model.predict(token_list), axis=-1)
149
- print("===> predicted=",predicted)
150
- for word, index in tokenizer.word_index.items():
151
- if index == predicted:
152
- start_text += " " + word
153
- break
154
- print(f"Prediction: {start_text}")
155
- print("-" * 50)
156
- return start_text
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- with gr.Blocks() as demo:
160
- #ENTETE
161
- gr.Markdown("# Exemple de prévision de mots")
162
- gr.Markdown("Exemple simple, utilisant un réseau de neurone de type **GRU**")
163
- gr.Markdown("- Le réseau 'apprend' les phrases de la liste (vous pouvez en ajouter)")
164
- gr.Markdown("- Cliquez sur apprendre si l'apprentissage n'a pas eu lieu")
165
- gr.Markdown("- Donnez plus bas un début de phrase et laissez le réseau en déduire la suite")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
- #Liste de phrases
168
- with gr.Row():
169
- sortie = gr.Textbox(label="Phrases actuelles", lines=5)
170
- liste = gr.State( textes)
171
- # Ajouter et supprimer des lignes
172
- with gr.Column():
173
- texte = gr.Textbox(label="Nouvelle phrase courte")
174
- btn_add = gr.Button("Ajouter")
175
- # Liste déroulante pour sélectionner une ligne à supprimer
176
- choix_ligne = gr.Dropdown(
177
- choices=textes,
178
- label="Sélectionner une ligne à supprimer",
179
- type="index" # Retourne l'index et non la valeur
180
- )
181
- btn_supprimer = gr.Button("Supprimer de la liste")
182
- feedback = gr.Textbox(label="Message", lines=1)
183
- # ajouter une ligne
184
- btn_add.click(
185
- fn=ajouter_a_liste,
186
- inputs=[liste, texte],
187
- outputs=[liste, texte]
188
- ).then(
189
- fn=lambda x: "\n".join(x),
190
- inputs=[liste],
191
- outputs=[sortie]
192
- )
193
- # Supprimer une ligne
194
- btn_supprimer.click(
195
- fn=supprimer_de_liste,
196
- inputs=[liste, choix_ligne],
197
- outputs=[liste, choix_ligne, feedback]
198
- ).then(
199
- fn=afficher_liste,
200
- inputs=[liste],
201
- outputs=[sortie]
202
- )
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
- #apprentissage
206
- texte_app = "Apprentissage non réalisé. Cliquez et attendez > 30s"
207
- if len(model.layers) > 0:
208
- texte_app = "Apprentissage déjà réalisé"
209
- with gr.Row():
210
- message_apprentissage = gr.Textbox(label="Résultat de l'apprentissage", value=texte_app)
211
- apprendre_btn = gr.Button("Apprendre")
212
- apprendre_btn.click(
213
- fn=apprendre,
214
- inputs=[liste],
215
- outputs=[message_apprentissage]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  )
 
217
 
218
- #prédiction
219
- with gr.Row():
220
- bout_texte = gr.Textbox(label="Début de phrase ")
221
- with gr.Column():
222
- nb_mots_pred = gr.Slider(
 
 
 
 
 
 
223
  minimum=1,
224
  maximum=6,
225
  value=3,
226
  step=1,
227
  label="Nombre de mots à prédire",
228
  interactive=True
229
- )
230
- btn_suite = gr.Button("Poursuivre")
231
- btn_suite.click(
232
- fn=predict_next_word,
233
- inputs=[bout_texte, nb_mots_pred],
234
- outputs=[bout_texte])
235
- else:
236
- gr.Textbox(label="Pas de tensorflow installé ")
237
-
238
- # Afficher la liste initiale au lancement
239
- # demo.load(
240
- # fn=afficher_liste,
241
- # inputs=[liste],
242
- # outputs=[sortie]
243
- # )
244
 
245
- #demo.launch()
 
 
 
1
  import subprocess
2
+ import sys
 
 
 
 
 
3
  import gradio as gr
4
  import numpy as np
5
 
6
+ # Installation PyTorch (plus fiable que TensorFlow)
7
+ try:
8
+ import torch
9
+ import torch.nn as nn
10
+ import torch.optim as optim
11
+ from collections import Counter
12
+ print(f"PyTorch {torch.__version__} déjà disponible")
13
+ except ImportError:
14
+ print("Installation de PyTorch...")
15
+ subprocess.check_call([
16
+ sys.executable, "-m", "pip", "install",
17
+ "torch", "--index-url", "https://download.pytorch.org/whl/cpu"
18
+ ])
19
+ import torch
20
+ import torch.nn as nn
21
+ import torch.optim as optim
22
+ from collections import Counter
 
 
 
 
 
 
 
 
 
23
 
24
+ print(f"✓ PyTorch {torch.__version__} prêt")
 
25
 
26
+ # Tokenizer simple pour remplacer Keras
27
+ class SimpleTokenizer:
28
+ def __init__(self):
29
+ self.word_index = {}
30
+ self.index_word = {}
31
+
32
+ def fit_on_texts(self, texts):
33
+ # Compter tous les mots
34
+ word_counts = Counter()
35
+ for text in texts:
36
+ words = text.lower().split()
37
+ word_counts.update(words)
38
+
39
+ # Créer les dictionnaires word <-> index
40
+ self.word_index = {word: i+1 for i, (word, _) in enumerate(word_counts.most_common())}
41
+ self.index_word = {i+1: word for word, i in self.word_index.items()}
42
+
43
+ def texts_to_sequences(self, texts):
44
+ sequences = []
45
+ for text in texts:
46
+ words = text.lower().split()
47
+ sequence = [self.word_index.get(word, 0) for word in words]
48
+ sequences.append(sequence)
49
+ return sequences
50
+
51
+ # Fonction de padding
52
+ def pad_sequences(sequences, maxlen, padding='pre'):
53
+ padded = []
54
+ for seq in sequences:
55
+ if len(seq) > maxlen:
56
+ if padding == 'pre':
57
+ seq = seq[-maxlen:]
58
+ else:
59
+ seq = seq[:maxlen]
 
 
 
 
 
 
 
 
 
60
  else:
61
+ if padding == 'pre':
62
+ seq = [0] * (maxlen - len(seq)) + seq
63
+ else:
64
+ seq = seq + [0] * (maxlen - len(seq))
65
+ padded.append(seq)
66
+ return np.array(padded)
67
+
68
+ # Modèle PyTorch équivalent au modèle Keras
69
+ class GRUWordPredictor(nn.Module):
70
+ def __init__(self, vocab_size, embedding_dim=50, hidden_dim=120, max_seq_len=10):
71
+ super(GRUWordPredictor, self).__init__()
72
+ self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0)
73
+ self.gru = nn.GRU(embedding_dim, hidden_dim, batch_first=True)
74
+ self.fc = nn.Linear(hidden_dim, vocab_size)
75
+ self.softmax = nn.Softmax(dim=1)
76
+
77
+ def forward(self, x):
78
+ embedded = self.embedding(x)
79
+ gru_out, _ = self.gru(embedded)
80
+ # Prendre la dernière sortie de la séquence
81
+ output = self.fc(gru_out[:, -1, :])
82
+ return self.softmax(output)
83
+
84
+ # Variables globales
85
+ model = None
86
+ tokenizer = SimpleTokenizer()
87
+ max_sequence_len = 0
88
+
89
+ textes = [
90
+ "la goutte d'eau qui fait déborder le vase",
91
+ "Il n'y a pas de fumée sans feu",
92
+ "Il faut battre le fer tant qu'il est chaud",
93
+ "Il ne faut pas mettre tous ses oeufs dans le même panier",
94
+ "Il faut tourner sept fois sa langue dans sa bouche avant de parler",
95
+ "L'habit ne fait pas le moine",
96
+ "Il ne faut pas réveiller le chat qui dort",
97
+ "Il faut se méfier de l'eau qui dort",
98
+ "C'est l'hôpital qui se moque de la charité",
99
+ "Qui vole un oeuf vole un boeuf",
100
+ "Chercher midi à quatorze heures",
101
+ "Avoir un poil dans la main",
102
+ "Être dans de beaux draps",
103
+ "Avoir la tête dans les nuages",
104
+ "Mettre les pieds dans le plat"
105
+ ]
106
+
107
+ def afficher_liste(liste):
108
+ return "\n".join(liste)
109
+
110
+ def ajouter_a_liste(liste_actuelle, nouveau_texte):
111
+ if nouveau_texte:
112
+ liste_actuelle.append(nouveau_texte)
113
+ return liste_actuelle, ""
114
+
115
+ def supprimer_de_liste(liste_actuelle, index_a_supprimer):
116
+ if index_a_supprimer is not None and 0 <= index_a_supprimer < len(liste_actuelle):
117
+ ligne_supprimee = liste_actuelle.pop(index_a_supprimer)
118
+ message = f"Ligne supprimée : '{ligne_supprimee}'"
119
+ else:
120
+ message = "Aucune ligne sélectionnée pour suppression"
121
+ return liste_actuelle, liste_actuelle, message
122
+
123
+ def apprendre(liste_actuelle):
124
+ global max_sequence_len, model, tokenizer
125
+
126
+ print("Liste soumise:", liste_actuelle)
127
+
128
+ # Analyse du texte
129
+ tokenizer.fit_on_texts(liste_actuelle)
130
+ total_words = len(tokenizer.word_index) + 1
131
+ print("nb de mots différents rencontrés :", total_words)
132
+
133
+ # Afficher les premiers mots
134
+ liste_mots = list(tokenizer.word_index.keys())
135
+ print("voici les premiers mots trouvés : ")
136
+ for i in range(min(10, len(liste_mots))):
137
+ print(f"({i+1}:'{liste_mots[i]}')", end=", ")
138
+ print()
139
+
140
+ # Transformation des textes en séquences
141
+ input_sequences = []
142
+ for sentence in liste_actuelle:
143
+ token_list = tokenizer.texts_to_sequences([sentence])[0]
144
+ for i in range(1, len(token_list)):
145
+ n_gram_sequence = token_list[:i+1]
146
+ input_sequences.append(n_gram_sequence)
147
+
148
+ # Calibrage des séquences
149
+ max_sequence_len = max([len(x) for x in input_sequences])
150
+ input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre')
151
+
152
+ # Afficher exemple de transformation
153
+ if liste_actuelle:
154
  print("la phrase '", liste_actuelle[0], "' est traduite en plusieurs vecteurs :")
155
+ split = liste_actuelle[0].lower().split()
156
+ for i in range(min(6, len(input_sequences))):
157
  print(input_sequences[i], end=" -> '")
158
+ for j in range(min(i+2, len(split))):
159
  print(split[j], end=" ")
160
  print("'")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
+ # Créer X et y
163
+ X = input_sequences[:, :-1]
164
+ y = input_sequences[:, -1]
165
+
166
+ # Convertir en tenseurs PyTorch
167
+ X_tensor = torch.LongTensor(X)
168
+ y_tensor = torch.LongTensor(y)
169
+
170
+ # Créer le modèle
171
+ model = GRUWordPredictor(
172
+ vocab_size=total_words,
173
+ embedding_dim=50,
174
+ hidden_dim=120,
175
+ max_seq_len=max_sequence_len-1
176
+ )
177
+
178
+ # Définir la fonction de perte et l'optimiseur
179
+ criterion = nn.CrossEntropyLoss()
180
+ optimizer = optim.Adam(model.parameters())
181
+
182
+ # Entraînement
183
+ print("patienter 30s pendant l'entrainement...")
184
+ model.train()
185
+
186
+ for epoch in range(300):
187
+ optimizer.zero_grad()
188
+ outputs = model(X_tensor)
189
+ loss = criterion(outputs, y_tensor)
190
+ loss.backward()
191
+ optimizer.step()
192
 
193
+ if epoch % 50 == 0:
194
+ print(f"Epoch {epoch}, Loss: {loss.item():.4f}")
195
+
196
+ model.eval() # Mode évaluation
197
+ return f"Entrainement effectué, saisissez un début de phrase pour demander la suite"
198
+
199
+ def predict_next_word(start_text, nb_words):
200
+ global model, tokenizer, max_sequence_len
201
+
202
+ if model is None:
203
+ return "Veuillez d'abord entraîner le modèle"
204
+
205
+ print("===> start_text=", start_text)
206
+ print(f"prédictions de {nb_words} mots.")
207
+
208
+ current_text = start_text.lower()
209
+
210
+ for _ in range(nb_words):
211
+ token_list = tokenizer.texts_to_sequences([current_text])[0]
212
+ token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
213
+ print("===> token_list=", token_list)
214
 
215
+ # Prédiction avec PyTorch
216
+ with torch.no_grad():
217
+ input_tensor = torch.LongTensor(token_list)
218
+ outputs = model(input_tensor)
219
+ predicted = torch.argmax(outputs, dim=-1).item()
220
+
221
+ print("===> predicted=", predicted)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
 
223
+ # Trouver le mot correspondant
224
+ if predicted in tokenizer.index_word:
225
+ word = tokenizer.index_word[predicted]
226
+ current_text += " " + word
227
+ else:
228
+ break # Si pas de mot trouvé, arrêter
229
+
230
+ print(f"Prediction: {current_text}")
231
+ print("-" * 50)
232
+ return current_text
233
+
234
+ # Interface Gradio
235
+ with gr.Blocks() as demo:
236
+ # ENTETE
237
+ gr.Markdown("# Exemple de prévision de mots (PyTorch)")
238
+ gr.Markdown("Exemple simple, utilisant un réseau de neurone de type **GRU** avec PyTorch")
239
+ gr.Markdown("- Le réseau 'apprend' les phrases de la liste (vous pouvez en ajouter)")
240
+ gr.Markdown("- Cliquez sur apprendre si l'apprentissage n'a pas eu lieu")
241
+ gr.Markdown("- Donnez plus bas un début de phrase et laissez le réseau en déduire la suite")
242
 
243
+ # Liste de phrases
244
+ with gr.Row():
245
+ sortie = gr.Textbox(label="Phrases actuelles", lines=5)
246
+ liste = gr.State(textes)
247
+ # Ajouter et supprimer des lignes
248
+ with gr.Column():
249
+ texte = gr.Textbox(label="Nouvelle phrase courte")
250
+ btn_add = gr.Button("Ajouter")
251
+ # Liste déroulante pour sélectionner une ligne à supprimer
252
+ choix_ligne = gr.Dropdown(
253
+ choices=textes,
254
+ label="Sélectionner une ligne à supprimer",
255
+ type="index"
256
+ )
257
+ btn_supprimer = gr.Button("Supprimer de la liste")
258
+ feedback = gr.Textbox(label="Message", lines=1)
259
+
260
+ # Ajouter une ligne
261
+ btn_add.click(
262
+ fn=ajouter_a_liste,
263
+ inputs=[liste, texte],
264
+ outputs=[liste, texte]
265
+ ).then(
266
+ fn=lambda x: "\n".join(x),
267
+ inputs=[liste],
268
+ outputs=[sortie]
269
+ )
270
+
271
+ # Supprimer une ligne
272
+ btn_supprimer.click(
273
+ fn=supprimer_de_liste,
274
+ inputs=[liste, choix_ligne],
275
+ outputs=[liste, choix_ligne, feedback]
276
+ ).then(
277
+ fn=afficher_liste,
278
+ inputs=[liste],
279
+ outputs=[sortie]
280
+ )
281
+
282
+ # Apprentissage
283
+ with gr.Row():
284
+ message_apprentissage = gr.Textbox(
285
+ label="Résultat de l'apprentissage",
286
+ value="Apprentissage non réalisé. Cliquez et attendez > 30s"
287
  )
288
+ apprendre_btn = gr.Button("Apprendre")
289
 
290
+ apprendre_btn.click(
291
+ fn=apprendre,
292
+ inputs=[liste],
293
+ outputs=[message_apprentissage]
294
+ )
295
+
296
+ # Prédiction
297
+ with gr.Row():
298
+ bout_texte = gr.Textbox(label="Début de phrase ")
299
+ with gr.Column():
300
+ nb_mots_pred = gr.Slider(
301
  minimum=1,
302
  maximum=6,
303
  value=3,
304
  step=1,
305
  label="Nombre de mots à prédire",
306
  interactive=True
307
+ )
308
+ btn_suite = gr.Button("Poursuivre")
309
+
310
+ btn_suite.click(
311
+ fn=predict_next_word,
312
+ inputs=[bout_texte, nb_mots_pred],
313
+ outputs=[bout_texte]
314
+ )
 
 
 
 
 
 
 
315
 
316
+ if __name__ == "__main__":
317
+ demo.launch()