1. Bibliotheken importieren
import numpy as np
from keras.models import Model
from keras.layers import Input, LSTM, Dense
numpy importieren:
numpy
ist eine Bibliothek für numerische Berechnungen in Python.np
importiert, was eine gängige Abkürzung ist.Model, Input, LSTM und Dense aus Keras importieren:
Model
ist eine Klasse in Keras, die verwendet wird, um ein Modell zu erstellen.- Ein Modell in Keras kann entweder sequentiell oder funktional sein. Hier wird das funktionale API-Format verwendet.
Input
ist eine Funktion, die die Eingabeschicht eines Modells definiert.- Sie spezifiziert die Form und den Datentyp der Eingabedaten.
LSTM
steht für Long Short-Term Memory und ist eine Art von rekurrentem neuronalen Netzwerk (RNN).- LSTMs sind besonders gut geeignet für die Verarbeitung und Vorhersage von zeitlichen Daten oder Sequenzen.
Dense
ist eine vollverbundene Schicht, die oft in neuronalen Netzwerken verwendet wird.- Jede Einheit (Neuron) in dieser Schicht ist mit jeder Einheit in der vorherigen Schicht verbunden.
- Diese Schicht wird typischerweise am Ende des Modells verwendet, um die Ausgabe zu erzeugen.
Zusammengefasst importiert dieser Code numpy
für numerische Operationen und Keras-Module (Model
, Input
, LSTM
, Dense
), die für den Aufbau eines neuronalen Netzwerks erforderlich sind.
2. Daten laden
data_path = 'english_to_arabic.txt'
with open(data_path, 'r', encoding='utf-8') as f:
lines = f.read().split('\n')
'r'
) und mit UTF-8-Kodierung geöffnet.with
sorgt dafür, dass die Datei korrekt geöffnet und geschlossen wird. Es ist eine gute Praxis, um sicherzustellen, dass Ressourcen ordnungsgemäß verwaltet werden.as f
weist der geöffneten Datei die Variable f
zu.f.read()
gelesen.split('\n')
teilt den gelesenen Inhalt an jeder neuen Zeile ('\n'
) und speichert jede Zeile als separates Element in der Liste lines
.lines
# Ausgabe:
['Hi.\tمرحبًا.\tCC-BY 2.0 (France) Attribution: tatoeba.org #538123 (CM) & #629296 (Samer)',
'Run!\tاركض!\tCC-BY 2.0 (France) Attribution: tatoeba.org #906328 (papabear) & #1245450 (saeb)',
'Duck!\tاخفض رأسك!\tCC-BY 2.0 (France) Attribution: tatoeba.org #280158 (CM) & #9036391 (KeEichi)',
'Duck!\tاخفضي رأسك!\tCC-BY 2.0 (France) Attribution: tatoeba.org #280158 (CM) & #9036392 (KeEichi)',
'Duck!\tاخفضوا رؤوسكم!\tCC-BY 2.0 (France) Attribution: tatoeba.org #280158 (CM) & #9036393 (KeEichi)',
'Help!\tالنجدة!\tCC-BY 2.0 (France) Attribution: tatoeba.org #435084 (lukaszpp) & #371293 (saeb)',
'Jump!\tاقفز!\tCC-BY 2.0 (France) Attribution: tatoeba.org #1102981 (jamessilver) & #6009426 (damascene)',
'Stop!\tقف!\tCC-BY 2.0 (France) Attribution: tatoeba.org #448320 (CM) & #1245447 (saeb)',
'Stop!\tتوقف !\tCC-BY 2.0 (France) Attribution: tatoeba.org #448320 (CM) & #5496702 (Wildflower81)',
'Wait!\tإنتظر\tCC-BY 2.0 (France) Attribution: tatoeba.org #1744314 (belgavox) & #5496709 (Wildflower81)',
'Go on.\tداوم.\tCC-BY 2.0 (France) Attribution: tatoeba.org #2230774 (CK) & #5118652 (damascene)',
'Go on.\tاستمر.\tCC-BY 2.0 (France) Attribution: tatoeba.org #2230774 (CK) & #5118653 (damascene)',
'Hello!\tمرحباً.\tCC-BY 2.0 (France) Attribution: tatoeba.org #373330 (CK) & #1904219 (Asma)',
'Hello.\tأهلاً.\tCC-BY 2.0 (France) Attribution: tatoeba.org #1858850 (LanguageExpert) & #1904218 (Asma)',
'Hello.\tمرحباً.\tCC-BY 2.0 (France) Attribution: tatoeba.org #1858850 (LanguageExpert) & #1904219 (Asma)',
.
.
.
]
len(lines)
# Ausgabe:
# 12193
3. Variablen initialisieren
input_texts = []
target_texts = []
input_characters = set()
target_characters = set()
Listen für Eingabe- und Zieltexte initialisieren:
input_texts
ist eine leere Liste, die später die Eingabetexte (z.B. englische Sätze) speichert.target_texts
ist eine leere Liste, die später die Zieltexte (z.B. arabische Übersetzungen) speichert.input_characters
ist eine leere Menge, die alle eindeutigen Zeichen der Eingabetexte speichert.target_characters
ist eine leere Menge, die alle eindeutigen Zeichen der Zieltexte speichert.Zusammengefasst:
input_texts
undtarget_texts
: Diese Listen werden verwendet, um die Sätze aus den Eingabe- und Zieldaten zu speichern.input_characters
undtarget_characters
: Diese Mengen speichern alle eindeutigen Zeichen, die in den Eingabe- und Zieltexten vorkommen.
Diese Initialisierungen sind der erste Schritt in der Vorbereitung der Daten für das Training des Modells. Sie ermöglichen es, die Texte und ihre Zeichen systematisch zu sammeln und weiterzuverarbeiten.
4. Daten verarbeiten
for line in lines[500:10000]:
input_text, target_text, _ = line.split('\t')
target_text = '\t' + target_text + '\n'
input_texts.append(input_text)
target_texts.append(target_text)
for char in input_text:
if char not in input_characters:
input_characters.add(char)
for char in target_text:
if char not in target_characters:
target_characters.add(char)
Zeilenbereich festlegen: for line in lines[500:10000]: Dieser for-Schleifenblock iteriert über die Zeilen 500 bis 9999 der Liste lines. Dies dient dazu, nur einen bestimmten Abschnitt der Daten für das Training zu verwenden.
Zeileninhalte extrahieren: input_text, target_text, _ = line.split('\t') Jede Zeile wird an den Tabulatoren ('\t') aufgeteilt. Es wird angenommen, dass jede Zeile drei Teile hat: Eingabetext (input_text), Zieltext (target_text) und einen dritten Teil, der hier nicht verwendet wird (daher das _).
Zieltext formatieren: target_text = '\t' + target_text + '\n' Der Zieltext wird angepasst, indem ein Tabulatorzeichen ('\t') am Anfang und ein Zeilenumbruch ('\n') am Ende hinzugefügt werden. Dies dient dazu, den Start und das Ende des Zieltextes zu markieren, was beim Training des Modells nützlich ist.
Texte zu Listen hinzufügen: input_texts.append(input_text) target_texts.append(target_text) Der formatierte Eingabetext und Zieltext werden zu den entsprechenden Listen input_texts und target_texts hinzugefügt.
Eingabezeichen sammeln: for char in input_text: if char not in input_characters: input_characters.add(char) Jeder Charakter im input_text wird durchlaufen. Wenn der Charakter nicht bereits in der Menge input_characters vorhanden ist, wird er hinzugefügt. Dies dient dazu, alle einzigartigen Zeichen in den Eingabetexten zu sammeln.
Zielzeichen sammeln: for char in target_text: if char not in target_characters: target_characters.add(char) Jeder Charakter im target_text wird durchlaufen. Wenn der Charakter nicht bereits in der Menge target_characters vorhanden ist, wird er hinzugefügt. Dies dient dazu, alle einzigartigen Zeichen in den Zieltexten zu sammeln.
input_texts
# Ausgabe:
['Come quickly!',
'Come with me.',
'Come with us.',
'Cool it down.',
'Did you call?',
'Do you smoke?',
'Drive safely.',
'Drive safely.',
'Everyone sat.',
'Fear nothing.',
'Fear nothing.',
.
.
.
]
target_texts
# Ausgabe:
['\tتعالَ بسرعة!\n',
'\tتعال معي.\n',
'\tتعال معنا.\n',
'\tهدّء من روعك.\n',
'\tهل اتصلت؟\n',
'\tهل تدخن؟\n',
'\tقد بحذر.\n',
'\tسُق بحذر\n',
'\tجلس الجميع.\n',
'\tلا تخف من أي شيء\n',
'\tإطمئن\n',
'\tاعثر علي القطه\n',
'\tسمك من فضلك.\n',
'\tمساء الخير.\n',
'\tصباح الخير\n',
.
.
.
]
input_characters
# Ausgabe:
{' ',
'!',
'"',
"'",
',',
'-',
'.',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
':',
'?',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'€'}
target_characters
# Ausgabe:
{'\t',
'\n',
' ',
'!',
'"',
'(',
')',
',',
'-',
'.',
'/',
'0',
'1',
'2',
'3',
'5',
'6',
'7',
'9',
':',
'?',
'F',
'M',
'P',
'\\',
'e',
'f',
'i',
'o',
'r',
'x',
'،',
'؟',
'ء',
'آ',
'أ',
'ؤ',
'إ',
'ئ',
'ا',
'ب',
'ة',
'ت',
'ث',
'ج',
'ح',
'خ',
'د',
'ذ',
'ر',
'ز',
'س',
'ش',
'ص',
'ض',
'ط',
'ظ',
'ع',
'غ',
'ـ',
'ف',
'ق',
'ك',
'ل',
'م',
'ن',
'ه',
'و',
'ى',
'ي',
'ً',
'ٌ',
'ٍ',
'َ',
'ُ',
'ِ',
'ّ',
'ْ',
'٠',
'١',
'٢',
'٣',
'٤',
'٥',
'٦',
'٨',
'٩',
'ٱ',
'ی',
'۰',
'۱',
'۹',
'\u200d',
'\u200f'}
5. Zeichen sortieren und indizieren
input_characters = sorted(list(input_characters))
target_characters = sorted(list(target_characters))
num_encoder_tokens = len(input_characters)
num_decoder_tokens = len(target_characters)
max_encoder_seq_length = max([len(txt) for txt in input_texts])
max_decoder_seq_length = max([len(txt) for txt in target_texts])
input_token_index = dict([(char, i) for i, char in enumerate(input_characters)])
target_token_index = dict([(char, i) for i, char in enumerate(target_characters)])
Eingabezeichen sortieren: input_characters = sorted(list(input_characters)) Die Menge der Eingabezeichen wird in eine sortierte Liste umgewandelt. Dies dient der Standardisierung und erleichtert die spätere Verarbeitung.
Zielzeichen sortieren: target_characters = sorted(list(target_characters)) Die Menge der Zielzeichen wird in eine sortierte Liste umgewandelt. Dies dient der Standardisierung und erleichtert die spätere Verarbeitung.
Anzahl der Encoder-Zeichen: num_encoder_tokens = len(input_characters) Hier wird die Anzahl der einzigartigen Zeichen in den Eingabetexten ermittelt. Diese Zahl wird später für die Modellarchitektur verwendet.
Anzahl der Decoder-Zeichen: num_decoder_tokens = len(target_characters) Hier wird die Anzahl der einzigartigen Zeichen in den Zieltexten ermittelt. Diese Zahl wird später für die Modellarchitektur verwendet.
Maximale Encoder-Sequenzlänge: max_encoder_seq_length = max([len(txt) for txt in input_texts]) Hier wird die Länge des längsten Eingabetextes ermittelt. Diese Information ist wichtig, um die Eingabesequenzen zu standardisieren.
Maximale Decoder-Sequenzlänge: max_decoder_seq_length = max([len(txt) for txt in target_texts]) Hier wird die Länge des längsten Zieltextes ermittelt. Diese Information ist wichtig, um die Zielsequenzen zu standardisieren.
Eingabezeichen indizieren: input_token_index = dict([(char, i) for i, char in enumerate(input_characters)]) Es wird ein Wörterbuch erstellt, das jedem Eingabezeichen einen eindeutigen Index zuweist. Dies ist wichtig für die One-Hot-Codierung der Eingabedaten.
Zielzeichen indizieren: target_token_index = dict([(char, i) for i, char in enumerate(target_characters)]) Es wird ein Wörterbuch erstellt, das jedem Zielzeichen einen eindeutigen Index zuweist. Dies ist wichtig für die One-Hot-Codierung der Zieldaten.
print("number of samples for the input", len(input_texts))
print("number of samples for the input", len(target_texts))
print('number of unique input tokens ', num_encoder_tokens)
print('number of unique target tokens ', num_decoder_tokens)
print("max_encoder_seq_length",max_encoder_seq_length)
print("max_decoder_seq_length",max_decoder_seq_length)
number of samples for the input 9500
number of samples for the input 9500
number of unique input tokens 71
number of unique target tokens 94
max_encoder_seq_length 37
max_decoder_seq_length 54
input_token_index
#Ausgabe:
{' ': 0,
'!': 1,
'"': 2,
"'": 3,
',': 4,
'-': 5,
'.': 6,
'0': 7,
'1': 8,
'2': 9,
'3': 10,
'4': 11,
'5': 12,
'6': 13,
'7': 14,
'8': 15,
'9': 16,
':': 17,
'?': 18,
'A': 19,
'B': 20,
'C': 21,
'D': 22,
'E': 23,
'F': 24,
'G': 25,
'H': 26,
'I': 27,
'J': 28,
'K': 29,
'L': 30,
'M': 31,
'N': 32,
'O': 33,
'P': 34,
'Q': 35,
'R': 36,
'S': 37,
'T': 38,
'U': 39,
'V': 40,
'W': 41,
'X': 42,
'Y': 43,
'a': 44,
'b': 45,
'c': 46,
'd': 47,
'e': 48,
'f': 49,
'g': 50,
'h': 51,
'i': 52,
'j': 53,
'k': 54,
'l': 55,
'm': 56,
'n': 57,
'o': 58,
'p': 59,
'q': 60,
'r': 61,
's': 62,
't': 63,
'u': 64,
'v': 65,
'w': 66,
'x': 67,
'y': 68,
'z': 69,
'€': 70}
target_token_index
#Ausgabe:
{'\t': 0,
'\n': 1,
' ': 2,
'!': 3,
'"': 4,
'(': 5,
')': 6,
',': 7,
'-': 8,
'.': 9,
'/': 10,
'0': 11,
'1': 12,
'2': 13,
'3': 14,
'5': 15,
'6': 16,
'7': 17,
'9': 18,
':': 19,
'?': 20,
'F': 21,
'M': 22,
'P': 23,
'\\': 24,
'e': 25,
'f': 26,
'i': 27,
'o': 28,
'r': 29,
'x': 30,
'،': 31,
'؟': 32,
'ء': 33,
'آ': 34,
'أ': 35,
'ؤ': 36,
'إ': 37,
'ئ': 38,
'ا': 39,
'ب': 40,
'ة': 41,
'ت': 42,
'ث': 43,
'ج': 44,
'ح': 45,
'خ': 46,
'د': 47,
'ذ': 48,
'ر': 49,
'ز': 50,
'س': 51,
'ش': 52,
'ص': 53,
'ض': 54,
'ط': 55,
'ظ': 56,
'ع': 57,
'غ': 58,
'ـ': 59,
'ف': 60,
'ق': 61,
'ك': 62,
'ل': 63,
'م': 64,
'ن': 65,
'ه': 66,
'و': 67,
'ى': 68,
'ي': 69,
'ً': 70,
'ٌ': 71,
'ٍ': 72,
'َ': 73,
'ُ': 74,
'ِ': 75,
'ّ': 76,
'ْ': 77,
'٠': 78,
'١': 79,
'٢': 80,
'٣': 81,
'٤': 82,
'٥': 83,
'٦': 84,
'٨': 85,
'٩': 86,
'ٱ': 87,
'ی': 88,
'۰': 89,
'۱': 90,
'۹': 91,
'\u200d': 92,
'\u200f': 93}
6. Daten in Matrizen umwandeln
encoder_input_data = np.zeros((len(input_texts), max_encoder_seq_length, num_encoder_tokens), dtype='float32')
decoder_input_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32')
decoder_target_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32')
for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):
for t, char in enumerate(input_text):
encoder_input_data[i, t, input_token_index[char]] = 1.
encoder_input_data[i, t+1:, input_token_index[' ']] = 1.
for t, char in enumerate(target_text):
decoder_input_data[i, t, target_token_index[char]] = 1.
if t > 0:
decoder_target_data[i, t-1, target_token_index[char]] = 1.
decoder_input_data[i, t+1:, target_token_index[' ']] = 1.
decoder_target_data[i, t:, target_token_index[' ']] = 1.
hier ist die Erklärung des Codes:
Encoder-Eingabedaten initialisieren: encoder_input_data = np.zeros((len(input_texts), max_encoder_seq_length, num_encoder_tokens), dtype='float32') Eine 3D-Numpy-Array wird initialisiert, um die Eingabedaten für den Encoder zu speichern. Die Form des Arrays ist (Anzahl der Eingabetexte, maximale Sequenzlänge der Eingabetexte, Anzahl der einzigartigen Eingabezeichen). Alle Werte werden auf 0 gesetzt.
Decoder-Eingabedaten initialisieren: decoder_input_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32') Eine 3D-Numpy-Array wird initialisiert, um die Eingabedaten für den Decoder zu speichern. Die Form des Arrays ist (Anzahl der Eingabetexte, maximale Sequenzlänge der Zieltexte, Anzahl der einzigartigen Zielzeichen). Alle Werte werden auf 0 gesetzt.
Decoder-Zieldaten initialisieren: decoder_target_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32') Eine 3D-Numpy-Array wird initialisiert, um die Zieldaten für den Decoder zu speichern. Die Form des Arrays ist (Anzahl der Eingabetexte, maximale Sequenzlänge der Zieltexte, Anzahl der einzigartigen Zielzeichen). Alle Werte werden auf 0 gesetzt.
Eingabe- und Zieltexte verarbeiten: for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)): Eine Schleife, die über alle Eingabe- und Zieltextpaare iteriert. Der Index
i
gibt die Position des Textpaares in der Liste an.Eingabetext codieren: for t, char in enumerate(input_text): encoder_input_data[i, t, input_token_index[char]] = 1. Jeder Charakter im Eingabetext wird durchlaufen. Der entsprechende Eintrag im encoder_input_data Array wird auf 1 gesetzt, basierend auf dem Index des Charakters.
Padding der restlichen Sequenz im Encoder: encoder_input_data[i, t+1:, input_token_index[' ']] = 1. Alle verbleibenden Positionen in der Sequenz werden mit Leerzeichen (' ') gepolstert.
Zieltext codieren: for t, char in enumerate(target_text): decoder_input_data[i, t, target_token_index[char]] = 1. Jeder Charakter im Zieltext wird durchlaufen. Der entsprechende Eintrag im decoder_input_data Array wird auf 1 gesetzt, basierend auf dem Index des Charakters.
Zieldaten codieren: if t > 0: decoder_target_data[i, t-1, target_token_index[char]] = 1. Der Zieltext wird ebenfalls codiert, aber hier wird der Charakter um eine Position verschoben, um die Vorhersage des nächsten Charakters zu ermöglichen.
Padding der restlichen Sequenz im Decoder: decoder_input_data[i, t+1:, target_token_index[' ']] = 1. und decoder_target_data[i, t:, target_token_index[' ']] = 1. Alle verbleibenden Positionen in der Sequenz werden mit Leerzeichen (' ') gepolstert.
Zusammengefasst:
Dieser Codeabschnitt erstellt die Eingabe- und Zieldaten für das Training des Sequenz-zu-Sequenz-Modells. Die Texte werden in One-Hot-Arrays umgewandelt, die von den LSTM-Schichten im Modell verarbeitet werden können. Dabei wird auch sichergestellt, dass die Sequenzen die gleiche Länge haben, indem sie mit Leerzeichen gepolstert werden.
encoder_input_data[0]
#Ausgabe:
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[1., 0., 0., ..., 0., 0., 0.],
[1., 0., 0., ..., 0., 0., 0.],
[1., 0., 0., ..., 0., 0., 0.]], dtype=float32)
encoder_input_data[0].shape
# Ausgabe:
(37, 71)
decoder_input_data[0]
# Ausgabe:
array([[1., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 1., ..., 0., 0., 0.],
[0., 0., 1., ..., 0., 0., 0.],
[0., 0., 1., ..., 0., 0., 0.]], dtype=float32)
decoder_input_data[0].shape
# Ausgabe:
(54, 94)
decoder_target_data[0]
# Ausgabe
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 1., ..., 0., 0., 0.],
[0., 0., 1., ..., 0., 0., 0.],
[0., 0., 1., ..., 0., 0., 0.]], dtype=float32)
decoder_target_data.shape
# Ausgabe
(9500, 54, 94)
7. Encoder- und Decoder-Modelle definieren
# Encoder
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
# Decoder
decoder_inputs = Input(shape=(None, num_decoder_tokens))
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
# Modell erstellen
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
hier ist die Erklärung des Codes:
Encoder
Encoder-Eingaben definieren: encoder_inputs = Input(shape=(None, num_encoder_tokens)) Hier wird die Eingabeschicht des Encoders definiert. Die Eingaben haben eine Form von (None, num_encoder_tokens), was bedeutet, dass die Sequenzlänge variabel ist und die Anzahl der Merkmale gleich der Anzahl der Eingabezeichen ist.
LSTM-Schicht des Encoders: encoder = LSTM(latent_dim, return_state=True) Eine LSTM-Schicht mit der Größe latent_dim wird erstellt. Die Option return_state=True stellt sicher, dass die Zustände der LSTM (state_h und state_c) zurückgegeben werden.
Encoder-Ausgaben und -Zustände: encoder_outputs, state_h, state_c = encoder(encoder_inputs) Die LSTM-Schicht verarbeitet die Eingabedaten und gibt die Ausgaben (encoder_outputs) sowie die Zustände (state_h und state_c) zurück.
Encoder-Zustände speichern: encoder_states = [state_h, state_c] Die Zustände des Encoders (state_h und state_c) werden in einer Liste gespeichert. Diese Zustände werden später als Initialisierung für den Decoder verwendet.
Decoder
Decoder-Eingaben definieren: decoder_inputs = Input(shape=(None, num_decoder_tokens)) Hier wird die Eingabeschicht des Decoders definiert. Die Eingaben haben eine Form von (None, num_decoder_tokens), was bedeutet, dass die Sequenzlänge variabel ist und die Anzahl der Merkmale gleich der Anzahl der Zielzeichen ist.
LSTM-Schicht des Decoders: decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True) Eine LSTM-Schicht mit der Größe latent_dim wird erstellt. Die Option return_sequences=True stellt sicher, dass die gesamten Ausgabesequenzen zurückgegeben werden, und return_state=True stellt sicher, dass die Zustände zurückgegeben werden.
Decoder-Ausgaben und -Zustände: decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states) Die LSTM-Schicht des Decoders verarbeitet die Eingabedaten und gibt die Ausgaben (decoder_outputs) sowie die Zustände zurück. Die Zustände werden hier jedoch nicht weiter verwendet (daher das
_
).Dichte Schicht des Decoders: decoder_dense = Dense(num_decoder_tokens, activation='softmax') Eine dichte Schicht (Fully Connected Layer) wird erstellt, um die Ausgabewahrscheinlichkeiten für jedes mögliche Zielzeichen zu berechnen. Die Aktivierungsfunktion 'softmax' stellt sicher, dass die Ausgaben Wahrscheinlichkeiten darstellen, die sich zu 1 summieren.
Decoder-Ausgaben durch die dichte Schicht: decoder_outputs = decoder_dense(decoder_outputs) Die Ausgaben des Decoders werden durch die dichte Schicht geleitet, um die endgültigen Vorhersagen zu erhalten.
Modell erstellen
- Modell definieren: model = Model([encoder_inputs, decoder_inputs], decoder_outputs) Hier wird das Modell definiert, das die Eingaben des Encoders und des Decoders nimmt und die Ausgaben des Decoders zurückgibt. Das Modell wird mit den Encoder-Eingaben (encoder_inputs), den Decoder-Eingaben (decoder_inputs) und den Decoder-Ausgaben (decoder_outputs) erstellt.
Zusammengefasst:
Dieser Codeabschnitt erstellt ein Sequenz-zu-Sequenz-Modell mit einem Encoder und einem Decoder. Der Encoder verarbeitet die Eingabesequenzen und erzeugt Zustände, die als Initialisierung für den Decoder verwendet werden. Der Decoder generiert dann die Zielsequenzen basierend auf diesen Zuständen und seinen eigenen Eingaben. Das Modell ist so aufgebaut, dass es gemeinsam mit den Encoder- und Decoder-Eingaben trainiert werden kann.
state_h.shape
# Ausgabe
# TensorShape([None, 256])
8. Modell kompilieren und trainieren
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=batch_size, epochs=epochs, validation_split=0.2)
Epoch 1/300
119/119 [==============================] - 8s 41ms/step - loss: 1.3319 - accuracy: 0.6935 - val_loss: 1.7311 - val_accuracy: 0.5763
Epoch 2/300
119/119 [==============================] - 4s 34ms/step - loss: 1.0888 - accuracy: 0.7185 - val_loss: 1.4512 - val_accuracy: 0.6122
Epoch 3/300
119/119 [==============================] - 4s 34ms/step - loss: 0.9683 - accuracy: 0.7448 - val_loss: 1.3586 - val_accuracy: 0.6377
Epoch 4/300
119/119 [==============================] - 4s 34ms/step - loss: 0.9224 - accuracy: 0.7555 - val_loss: 1.2907 - val_accuracy: 0.6544
Epoch 5/300
119/119 [==============================] - 4s 34ms/step - loss: 0.8696 - accuracy: 0.7669 - val_loss: 1.2624 - val_accuracy: 0.6597
.
.
.
.
Epoch 298/300
119/119 [==============================] - 4s 33ms/step - loss: 0.0327 - accuracy: 0.9909 - val_loss: 2.8913 - val_accuracy: 0.7124
Epoch 299/300
119/119 [==============================] - 4s 34ms/step - loss: 0.0318 - accuracy: 0.9909 - val_loss: 2.8945 - val_accuracy: 0.7131
Epoch 300/300
119/119 [==============================] - 4s 33ms/step - loss: 0.0321 - accuracy: 0.9910 - val_loss: 2.8720 - val_accuracy: 0.7136
Modell kompilieren
- Optimizer:
'rmsprop'
Der RMSprop-Optimierer wird verwendet, um den Gradientenabstiegsprozess zu steuern. RMSprop ist ein adaptiver Lernraten-Optimierer, der sich gut für Recurrent Neural Networks (RNNs) eignet. - Loss:
'categorical_crossentropy'
Die kategorische Kreuzentropie wird als Verlustfunktion verwendet, da es sich um ein Mehrklassen-Klassifizierungsproblem handelt. Diese Funktion misst die Divergenz zwischen den vorhergesagten Wahrscheinlichkeitsverteilungen und den tatsächlichen Verteilungen. - Metrics:
['accuracy']
Die Genauigkeit wird als Metrik zur Bewertung des Modells während des Trainings und der Validierung verwendet. Sie gibt an, wie oft die Vorhersagen des Modells korrekt sind.
Modell trainieren
- Inputs:
[encoder_input_data, decoder_input_data]
Das Modell wird mit den Encoder-Eingabedaten und den Decoder-Eingabedaten trainiert. - Target:
decoder_target_data
Die Decoder-Zieldaten werden als Zielwerte für das Training verwendet. - Batch Size:
batch_size=batch_size
Die Anzahl der Samples, die in einem Schritt des Gradientenabstiegsprozesses verwendet werden. Eine kleinere Batch-Größe führt zu häufigeren Aktualisierungen der Gewichte, während eine größere Batch-Größe zu stabileren Aktualisierungen führt. - Epochs:
epochs=epochs
Die Anzahl der vollständigen Durchläufe durch den gesamten Trainingsdatensatz. Mehr Epochen führen in der Regel zu besserer Leistung, können aber auch zu Überanpassung führen. - Validation Split:
validation_split=0.2
Ein Teil der Trainingsdaten (20%) wird als Validierungsdatensatz verwendet, um die Leistung des Modells während des Trainings zu überwachen und sicherzustellen, dass es nicht überanpasst.
Zusammengefasst:
Dieser Codeabschnitt kompiliert das Modell mit dem RMSprop-Optimierer und der kategorischen Kreuzentropie als Verlustfunktion. Anschließend wird das Modell mit den vorbereiteten Encoder- und Decoder-Daten trainiert. Die Trainingsdaten werden in Batches verarbeitet, und ein Teil der Daten wird zur Validierung während des Trainings verwendet. Dies hilft, die Genauigkeit und die Verlustwerte des Modells zu überwachen und sicherzustellen, dass das Modell sowohl auf den Trainings- als auch auf den Validierungsdaten gut abschneidet.
9. Modelle speichern und definieren
model.save('eng2arabic.h5')
encoder_model = Model(encoder_inputs, encoder_states)
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states)
hier ist die Erklärung des Codes:
Modell speichern: model.save('eng2arabic.h5') Das trainierte Modell wird in einer Datei namens
eng2arabic.h5
gespeichert. Diese Datei enthält die Architektur, die Gewichte und den Zustand des Modells, sodass es später geladen und wiederverwendet werden kann.Encoder-Modell definieren: encoder_model = Model(encoder_inputs, encoder_states) Ein neues Modell wird definiert, das die Eingaben des Encoders (encoder_inputs) nimmt und die Zustände des Encoders (encoder_states) als Ausgabe liefert. Dieses Modell wird während der Inferenz verwendet, um die Zustände des Encoders zu berechnen, die dann als Initialisierungszustände für den Decoder verwendet werden.
Decoder-Zustandseingaben definieren: decoder_state_input_h = Input(shape=(latent_dim,)) und decoder_state_input_c = Input(shape=(latent_dim,)) Zwei Eingabeschichten werden definiert, um die Zustände des Decoders (hidden state h und cell state c) zu empfangen. Diese Zustände werden während der Inferenz von der vorherigen Dekodierschicht an die aktuelle Schicht weitergegeben.
Decoder-Zustandseingaben in eine Liste speichern: decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c] Die definierten Zustände werden in einer Liste gespeichert, um sie im Decoder zu verwenden.
Decoder-Ausgaben und Zustände berechnen: decoder_outputs, state_h, state_c = decoder_lstm(decoder_inputs, initial_state=decoder_states_inputs) Die LSTM-Schicht des Decoders nimmt die Eingaben und die Zustände als Initialisierungswerte. Sie gibt die Ausgaben (decoder_outputs) sowie die aktualisierten Zustände (state_h und state_c) zurück.
Aktualisierte Zustände speichern: decoder_states = [state_h, state_c] Die aktualisierten Zustände werden in einer Liste gespeichert, um sie in den nächsten Schritt zu übergeben.
Decoder-Ausgaben durch die dichte Schicht leiten: decoder_outputs = decoder_dense(decoder_outputs) Die Ausgaben des Decoders werden durch die dichte Schicht geleitet, um die endgültigen Vorhersagen zu erhalten.
Decoder-Modell definieren: decoder_model = Model([decoder_inputs] + decoder_states_inputs, [decoder_outputs] + decoder_states) Ein neues Modell wird definiert, das die Eingaben des Decoders (decoder_inputs) und die Zustände (decoder_states_inputs) nimmt und die Ausgaben des Decoders (decoder_outputs) sowie die aktualisierten Zustände (decoder_states) zurückgibt. Dieses Modell wird während der Inferenz verwendet, um Sequenzen Schritt für Schritt zu dekodieren.
10. Dekodierfunktion definieren
reverse_target_char_index = dict((i, char) for char, i in target_token_index.items())
reverse_input_char_index = dict((i, char) for char, i in input_token_index.items())
def decode_sequence(input_seq):
states_value = encoder_model.predict(input_seq)
target_seq = np.zeros((1, 1, num_decoder_tokens))
target_seq[0, 0, target_token_index['\t']] = 1.
stop_condition = False
decoded_sentence = ''
while not stop_condition:
output_tokens, h, c = decoder_model.predict([target_seq] + states_value)
sampled_token_index = np.argmax(output_tokens[0, -1, :])
sampled_char = reverse_target_char_index[sampled_token_index]
decoded_sentence += sampled_char
if (sampled_char == '\n' or len(decoded_sentence) > max_decoder_seq_length):
stop_condition = True
target_seq = np.zeros((1, 1, num_decoder_tokens))
target_seq[0, 0, sampled_token_index] = 1.
states_value = [h, c]
return decoded_sentence
hier ist die Erklärung des Codes:
Reverse Target Character Index erstellen: reverse_target_char_index = dict((i, char) for char, i in target_token_index.items()) Ein Wörterbuch wird erstellt, das die Indizes den Zielzeichen zuordnet. Dies ermöglicht die Umwandlung von Indizes zurück in Zeichen während der Dekodierung.
Reverse Input Character Index erstellen: reverse_input_char_index = dict((i, char) for char, i in input_token_index.items()) Ein Wörterbuch wird erstellt, das die Indizes den Eingabezeichen zuordnet. Dies ermöglicht die Umwandlung von Indizes zurück in Zeichen während der Dekodierung.
Funktion zur Sequenzdekodierung definieren
Funktion definieren: def decode_sequence(input_seq): Eine Funktion namens
decode_sequence
wird definiert, die eine Eingabesequenz nimmt und die entsprechende Zielsequenz dekodiert.Encoder-Modell vorhersagen: states_value = encoder_model.predict(input_seq) Die Zustände des Encoders werden durch Vorhersage auf die Eingabesequenz berechnet.
Zielsequenz initialisieren: target_seq = np.zeros((1, 1, num_decoder_tokens)) Eine Nullmatrix für die Zielsequenz wird initialisiert. Dies ist die Eingabe für den Decoder.
Startzeichen setzen: target_seq[0, 0, target_token_index['\t']] = 1. Das Startzeichen (
'\t'
) wird als erstes Zeichen der Zielsequenz gesetzt.Dekodierungsschleife initialisieren: stop_condition = False und decoded_sentence = '' Eine Schleife wird initialisiert, um die Dekodierung zu steuern.
stop_condition
kontrolliert, wann die Schleife beendet wird, unddecoded_sentence
speichert den dekodierten Satz.
Dekodierungsschleife
Schleife starten: while not stop_condition: Die Schleife läuft, bis die Stoppbedingung erfüllt ist.
Decoder-Modell vorhersagen: output_tokens, h, c = decoder_model.predict([target_seq] + states_value) Das Decoder-Modell macht eine Vorhersage basierend auf der Zielsequenz und den Zuständen. Die Ausgabe sind die vorhergesagten Tokens und die neuen Zustände
h
undc
.Vorhergesagtes Zeichen extrahieren: sampled_token_index = np.argmax(output_tokens[0, -1, :]) und sampled_char = reverse_target_char_index[sampled_token_index] Der Index des am meisten wahrscheinlichen Tokens wird gefunden und in das entsprechende Zeichen umgewandelt.
Zeichen zum dekodierten Satz hinzufügen: decoded_sentence += sampled_char Das vorhergesagte Zeichen wird zum dekodierten Satz hinzugefügt.
Stoppbedingung prüfen: if (sampled_char == '\n' or len(decoded_sentence) > max_decoder_seq_length): stop_condition = True Wenn das Zeichen ein Zeilenumbruch ist oder die maximale Sequenzlänge überschritten wird, wird die Schleife gestoppt.
Zielsequenz aktualisieren: target_seq = np.zeros((1, 1, num_decoder_tokens)) und target_seq[0, 0, sampled_token_index] = 1. Die Zielsequenz wird aktualisiert, um das vorhergesagte Zeichen zu enthalten.
Zustände aktualisieren: states_value = [h, c] Die Zustände des Decoders werden aktualisiert.
Dekodierten Satz zurückgeben: return decoded_sentence Die Funktion gibt den vollständig dekodierten Satz zurück.
11. Testen auf Trainingsdaten
for seq_index in range(5):
input_seq = encoder_input_data[seq_index:seq_index+1]
decoded_sequence = decode_sequence(input_seq)
print('-')
print('Input sentence:', input_texts[seq_index])
print('Decoded sentence:', decoded_sequence)
Ausgabe:
1/1 [==============================] - 0s 355ms/step
1/1 [==============================] - 0s 333ms/step
1/1 [==============================] - 0s 27ms/step
1/1 [==============================] - 0s 40ms/step
1/1 [==============================] - 0s 29ms/step
1/1 [==============================] - 0s 30ms/step
1/1 [==============================] - 0s 28ms/step
1/1 [==============================] - 0s 31ms/step
1/1 [==============================] - 0s 55ms/step
1/1 [==============================] - 0s 43ms/step
1/1 [==============================] - 0s 49ms/step
1/1 [==============================] - 0s 32ms/step
1/1 [==============================] - 0s 39ms/step
1/1 [==============================] - 0s 40ms/step
-
Input sentence: Come quickly!
decoded sentence: تعالَ بسرعة!
1/1 [==============================] - 0s 25ms/step
1/1 [==============================] - 0s 27ms/step
1/1 [==============================] - 0s 19ms/step
1/1 [==============================] - 0s 23ms/step
1/1 [==============================] - 0s 20ms/step
1/1 [==============================] - 0s 38ms/step
1/1 [==============================] - 0s 36ms/step
1/1 [==============================] - 0s 53ms/step
1/1 [==============================] - 0s 40ms/step
1/1 [==============================] - 0s 35ms/step
1/1 [==============================] - 0s 43ms/step
-
Input sentence: Come with me.
decoded sentence: تعال معي.
.
.
.
hier ist die Erklärung des Codes:
Schleifenbereich festlegen: for seq_index in range(5): Eine Schleife wird initialisiert, die über die ersten 5 Sequenzen des Datensatzes iteriert. Der Schleifenindex
seq_index
reicht von 0 bis 4.Eingabesequenz auswählen: input_seq = encoder_input_data[seq_index
+1] Die Eingabesequenz für den aktuellen Index wird aus den Encoder-Eingabedaten ausgewählt. Dabei wirdseq_index:seq_index+1
verwendet, um sicherzustellen, dass die Eingabesequenz die richtige Form hat (1, maximale Sequenzlänge, Anzahl der Eingabezeichen).Sequenz dekodieren: decoded_sequence = decode_sequence(input_seq) Die ausgewählte Eingabesequenz wird an die Funktion
decode_sequence
übergeben, um die entsprechende Zielsequenz zu dekodieren. Das Ergebnis ist die dekodierte Sequenz.Trennzeichen drucken: print('-') Ein Trennzeichen (
'-'
) wird gedruckt, um die Ausgabe für jede Sequenz optisch zu trennen.Eingabesatz drucken: print('Input sentence:', input_texts[seq_index]) Der ursprüngliche Eingabesatz für den aktuellen Index wird aus der Liste
input_texts
ausgewählt und gedruckt.Dekodierten Satz drucken: print('Decoded sentence:', decoded_sequence) Die dekodierte Sequenz wird gedruckt. Dies zeigt die Vorhersage des Modells für den entsprechenden Eingabesatz.
Zusammengefasst:
Dieser Codeabschnitt testet das Modell, indem er die ersten 5 Eingabesequenzen des Datensatzes durchläuft, sie dekodiert und die ursprünglichen Eingabesätze sowie die dekodierten Sätze ausgibt. Dies ermöglicht eine visuelle Überprüfung der Leistung des Modells und gibt Aufschluss darüber, wie gut das Modell die Eingabesequenzen in Zielsequenzen übersetzen kann.
12. Testen auf neuen Daten
input_texts = []
target_texts = []
input_characters = set()
target_characters = set()
for line in lines[0:500]:
input_text, target_text, _ = line.split('\t')
target_text = '\t' + target_text + '\n'
input_texts.append(input_text)
target_texts.append(target_text)
for char in input_text:
if char not in input_characters:
input_characters.add(char)
for char in target_text:
if char not in target_characters:
target_characters.add(char)
for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):
for t, char in enumerate(input_text):
encoder_input_data[i, t, input_token_index[char]] = 1.
encoder_input_data[i, t+1:, input_token_index[' ']] = 1.
for t, char in enumerate(target_text):
decoder_input_data[i, t, target_token_index[char]] = 1.
if t > 0:
decoder_target_data[i, t-1, target_token_index[char]] = 1.
decoder_input_data[i, t+1:, target_token_index[' ']] = 1.
decoder_target_data[i, t:, target_token_index[' ']] = 1.
for seq_index in range(500):
input_seq = encoder_input_data[seq_index:seq_index+1]
decoded_sequence = decode_sequence(input_seq)
print('-')
print('Input sentence:', input_texts[seq_index])
print('Decoded sentence:', decoded_sequence)
Ausgabe:
1/1 [==============================] - 0s 19ms/step
1/1 [==============================] - 0s 21ms/step
1/1 [==============================] - 0s 23ms/step
1/1 [==============================] - 0s 42ms/step
1/1 [==============================] - 0s 33ms/step
1/1 [==============================] - 0s 31ms/step
1/1 [==============================] - 0s 36ms/step
1/1 [==============================] - 0s 38ms/step
1/1 [==============================] - 0s 40ms/step
1/1 [==============================] - 0s 33ms/step
1/1 [==============================] - 0s 33ms/step
1/1 [==============================] - 0s 39ms/step
1/1 [==============================] - 0s 41ms/step
1/1 [==============================] - 0s 20ms/step
1/1 [==============================] - 0s 38ms/step
1/1 [==============================] - 0s 26ms/step
1/1 [==============================] - 0s 20ms/step
1/1 [==============================] - 0s 38ms/step
1/1 [==============================] - 0s 28ms/step
1/1 [==============================] - 0s 30ms/step
1/1 [==============================] - 0s 29ms/step
1/1 [==============================] - 0s 47ms/step
-
Input sentence: Hi.
decoded sentence: كيف بإمكاني مساعدتك؟
1/1 [==============================] - 0s 30ms/step
1/1 [==============================] - 0s 45ms/step
1/1 [==============================] - 0s 41ms/step
1/1 [==============================] - 0s 19ms/step
1/1 [==============================] - 0s 23ms/step
1/1 [==============================] - 0s 22ms/step
1/1 [==============================] - 0s 36ms/step
1/1 [==============================] - 0s 27ms/step
1/1 [==============================] - 0s 31ms/step
1/1 [==============================] - 0s 46ms/step
1/1 [==============================] - 0s 23ms/step
1/1 [==============================] - 0s 28ms/step
1/1 [==============================] - 0s 44ms/step
1/1 [==============================] - 0s 23ms/step
-
Input sentence: Run!
decoded sentence: المحمل لديَ.
.
.
Erklärung des Codes:
Initialisierung und Verarbeitung neuer Daten
- Listen und Sets initialisieren: input_texts = [] und target_texts = [], input_characters = set() und target_characters = set() Leere Listen für die Eingabe- und Zieltexte sowie leere Sets für die Eingabe- und Zielzeichen werden initialisiert. Diese werden verwendet, um die neuen Daten zu speichern und zu verarbeiten.
Verarbeitung der ersten 500 Zeilen
Zeilenbereich festlegen: for line in lines[0:500]: Eine Schleife wird initialisiert, die über die ersten 500 Zeilen der Liste
lines
iteriert.Zeileninhalte extrahieren: input_text, target_text, _ = line.split('\t') Jede Zeile wird an den Tabulatoren ('\t') aufgeteilt. Es wird angenommen, dass jede Zeile drei Teile hat: Eingabetext (input_text), Zieltext (target_text) und einen dritten Teil, der hier nicht verwendet wird (daher das
_
).Zieltext formatieren: target_text = '\t' + target_text + '\n' Der Zieltext wird angepasst, indem ein Tabulatorzeichen ('\t') am Anfang und ein Zeilenumbruch ('\n') am Ende hinzugefügt werden. Dies dient dazu, den Start und das Ende des Zieltextes zu markieren.
Texte zu Listen hinzufügen: input_texts.append(input_text) und target_texts.append(target_text) Der formatierte Eingabetext und Zieltext werden zu den entsprechenden Listen input_texts und target_texts hinzugefügt.
Eingabezeichen sammeln: for char in input_text: if char not in input_characters: input_characters.add(char) Jeder Charakter im input_text wird durchlaufen. Wenn der Charakter nicht bereits in der Menge input_characters vorhanden ist, wird er hinzugefügt. Dies dient dazu, alle einzigartigen Zeichen in den Eingabetexten zu sammeln.
Zielzeichen sammeln: for char in target_text: if char not in target_characters: target_characters.add(char) Jeder Charakter im target_text wird durchlaufen. Wenn der Charakter nicht bereits in der Menge target_characters vorhanden ist, wird er hinzugefügt. Dies dient dazu, alle einzigartigen Zeichen in den Zieltexten zu sammeln.
One-Hot-Encoding der Texte
Texte zu Matrizen umwandeln: for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)): Eine Schleife, die über alle Eingabe- und Zieltextpaare iteriert.
Eingabetext codieren: for t, char in enumerate(input_text): encoder_input_data[i, t, input_token_index[char]] = 1. Jeder Charakter im Eingabetext wird durchlaufen. Der entsprechende Eintrag im encoder_input_data Array wird auf 1 gesetzt, basierend auf dem Index des Charakters.
Padding der restlichen Sequenz im Encoder: encoder_input_data[i, t+1:, input_token_index[' ']] = 1. Alle verbleibenden Positionen in der Sequenz werden mit Leerzeichen (' ') gepolstert.
Zieltext codieren: for t, char in enumerate(target_text): decoder_input_data[i, t, target_token_index[char]] = 1. Jeder Charakter im Zieltext wird durchlaufen. Der entsprechende Eintrag im decoder_input_data Array wird auf 1 gesetzt, basierend auf dem Index des Charakters.
Zieldaten codieren: if t > 0: decoder_target_data[i, t-1, target_token_index[char]] = 1. Der Zieltext wird ebenfalls codiert, aber hier wird der Charakter um eine Position verschoben, um die Vorhersage des nächsten Charakters zu ermöglichen.
Padding der restlichen Sequenz im Decoder: decoder_input_data[i, t+1:, target_token_index[' ']] = 1. und decoder_target_data[i, t:, target_token_index[' ']] = 1. Alle verbleibenden Positionen in der Sequenz werden mit Leerzeichen (' ') gepolstert.
Testen auf neuen Daten
Schleifenbereich festlegen: for seq_index in range(500): Eine Schleife, die über die ersten 500 Sequenzen des neuen Datensatzes iteriert.
Eingabesequenz auswählen: input_seq = encoder_input_data[seq_index
+1] Die Eingabesequenz für den aktuellen Index wird aus den Encoder-Eingabedaten ausgewählt. Dabei wird seq_index+1 verwendet, um sicherzustellen, dass die Eingabesequenz die richtige Form hat (1, maximale Sequenzlänge, Anzahl der Eingabezeichen).Sequenz dekodieren: decoded_sequence = decode_sequence(input_seq) Die ausgewählte Eingabesequenz wird an die Funktion decode_sequence übergeben, um die entsprechende Zielsequenz zu dekodieren. Das Ergebnis ist die dekodierte Sequenz.
Trennzeichen drucken: print('-') Ein Trennzeichen ('-') wird gedruckt, um die Ausgabe für jede Sequenz optisch zu trennen.
Eingabesatz drucken: print('Input sentence:', input_texts[seq_index]) Der ursprüngliche Eingabesatz für den aktuellen Index wird aus der Liste input_texts ausgewählt und gedruckt.
Dekodierten Satz drucken: print('Decoded sentence:', decoded_sequence) Die dekodierte Sequenz wird gedruckt. Dies zeigt die Vorhersage des Modells für den entsprechenden Eingabesatz.
Zusammengefasst:
Dieser Codeabschnitt initialisiert und verarbeitet die ersten 500 Zeilen eines neuen Datensatzes, um die Eingabe- und Zieltexte sowie die einzigartigen Zeichen zu sammeln. Anschließend werden die Texte in One-Hot-codierte Matrizen umgewandelt. Der letzte Teil des Codes testet das Modell, indem es die ersten 500 Eingabesequenzen des neuen Datensatzes durchläuft, sie dekodiert und die ursprünglichen Eingabesätze sowie die dekodierten Sätze ausgibt. Dies ermöglicht eine visuelle Überprüfung der Leistung des Modells auf neuen Daten.
13. Der gesamte Code
import numpy as np
from keras.models import Model
from keras.layers import Input, LSTM, Dense
data_path = ‘ara.txt'
with open(data_path, 'r', encoding='utf-8') as f:
lines = f.read().split('\n')
input_texts = []
target_texts= []
input_characters = set()
target_characters = set()
for line in lines [500:10000]:
input_text , target_text, _ = line.split('\t')
target_text = '\t'+target_text+'\n'
input_texts.append(input_text)
target_texts.append(target_text)
for char in input_text:
if char not in input_characters:
input_characters.add(char)
for char in target_text:
if char not in target_characters:
target_characters.add(char)
input_characters = sorted(list(input_characters))
target_characters = sorted(list(target_characters))
num_encoder_tokens = len(input_characters)
num_decoder_tokens = len(target_characters)
max_encoder_seq_length = max([len(txt) for txt in input_texts])
max_decoder_seq_length = max([len(txt) for txt in target_texts])
input_token_index = dict([(char,i) for i, char in enumerate(input_characters)])
target_token_index = dict([(char,i) for i, char in enumerate(target_characters)])
batch_size = 64
epochs = 300
latent_dim = 256
encoder_input_data = np.zeros((len(input_texts), max_encoder_seq_length, num_encoder_tokens), dtype='float32')
decoder_input_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32')
decoder_target_data = np.zeros((len(input_texts), max_decoder_seq_length, num_decoder_tokens), dtype='float32')
for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):
for t, char in enumerate(input_text):
encoder_input_data[i,t, input_token_index[char]] = 1.
encoder_input_data[i, t+1:, input_token_index[' ']] =1.
for t, char in enumerate(target_text):
decoder_input_data[i,t,target_token_index[char]] =1.
if t>0:
decoder_target_data[i, t-1, target_token_index[char]]=1.
decoder_input_data[i, t+1:, target_token_index[' ']] =1.
decoder_target_data[i, t:, target_token_index[' ']] =1.
# the first LSTM ele.
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder = LSTM(latent_dim, return_state= True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]
# the Second Element
decoder_inputs = Input(shape=(None, num_decoder_tokens))
decoder_lstm = LSTM(latent_dim,return_sequences=True,return_state= True )
encoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state = encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(encoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=batch_size, epochs= epochs, validation_split=0.2)
model.save('eng2arabic.h5')
encoder_model = Model(encoder_inputs, encoder_states)
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
decoder_outputs, state_h,state_c = decoder_lstm(decoder_inputs,initial_state = decoder_states_inputs)
decoder_states = [state_h, state_c]
decoder_outputs = decoder_dense(decoder_outputs)
decoder_model = Model([decoder_inputs]+decoder_states_inputs,[decoder_outputs]+decoder_states)
reverse_target_char_index = dict((i,char) for char, i in target_token_index.items())
reverse_input_char_index = dict((i,char) for char, i in input_token_index.items())
def decode_sequence(input_seq):
states_value = encoder_model.predict(input_seq)
target_seq = np.zeros((1,1, num_decoder_tokens))
target_seq[0,0, target_token_index['\t']] = 1.
stop_condition = False
decoded_sentence = ''
while not stop_condition:
output_tokens, h,c = decoder_model.predict([target_seq]+states_value)
sample_token_index = np.argmax(output_tokens[0,-1,:])
sampled_char = reverse_target_char_index[sample_token_index]
decoded_sentence = decoded_sentence+sampled_char
if (sampled_char == '\n' or len(decoded_sentence)> max_decoder_seq_length):
stop_condition = True
target_seq = np.zeros((1,1, num_decoder_tokens))
target_seq[0,0,sample_token_index] = 1.
states_value = [h,c]
return decoded_sentence
for seq_index in range(5):
input_seq = encoder_input_data[seq_index:seq_index+1]
decoded_sequence= decode_sequence(input_seq)
print('-')
print('Input sentence: ', input_texts[seq_index])
print('decoded sentence: ', decoded_sequence)
# Test on New data
input_texts = []
target_texts= []
input_characters = set()
target_characters = set()
#num_samples = 10000
for line in lines [0:500]:
input_text , target_text, _ = line.split('\t')
target_text = '\t'+target_text+'\n'
input_texts.append(input_text)
target_texts.append(target_text)
for char in input_text:
if char not in input_characters:
input_characters.add(char)
for char in target_text:
if char not in target_characters:
target_characters.add(char)
for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)):
for t, char in enumerate(input_text):
encoder_input_data[i,t, input_token_index[char]] = 1.
encoder_input_data[i, t+1:, input_token_index[' ']] =1.
for t, char in enumerate(target_text):
decoder_input_data[i,t,target_token_index[char]] =1.
if t>0:
decoder_target_data[i, t-1, target_token_index[char]]=1.
decoder_input_data[i, t+1:, target_token_index[' ']] =1.
decoder_target_data[i, t:, target_token_index[' ']] =1.
for seq_index in range(500):
input_seq = encoder_input_data[seq_index:seq_index+1]
decoded_sequence= decode_sequence(input_seq)
print('-')
print('Input sentence: ', input_texts[seq_index])
print('decoded sentence: ', decoded_sequence)