Whatsapp Telegram Telegram Call Anrufen

Neural Machine Translation using Keras and LSTM


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.
  • Sie bietet Unterstützung für große, mehrdimensionale Arrays und Matrizen, sowie eine Sammlung mathematischer Funktionen, um an diesen Arrays Operationen durchzuführen.
  • Hier wird sie mit dem Alias np importiert, was eine gängige Abkürzung ist.
  • Model, Input, LSTM und Dense aus Keras importieren:

    Model:
    • 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:
    • Input ist eine Funktion, die die Eingabeschicht eines Modells definiert.
    • Sie spezifiziert die Form und den Datentyp der Eingabedaten.
    LSTM:
    • 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:
    • 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')
    


    Pfad zur Datendatei definieren:
  • Hier wird der Dateipfad zu einer Textdatei festgelegt, die english_to_arabic.txt heißt.
  • Diese Datei enthält die Daten, die für das Training des Modells verwendet werden.

  • Datei öffnen und lesen:
  • Die Datei wird im Lese-Modus ('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.

  • Dateiinhalt lesen und in Zeilen aufteilen:
  • Der gesamte Inhalt der Datei wird mit 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.
  • Diese Listen werden verwendet, um die Daten während der Verarbeitung zu speichern.
  • Mengen für Eingabe- und Zielzeichen initialisieren:
  • 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.
  • Mengen (Sets) sind Datenstrukturen, die nur eindeutige Elemente enthalten. Sie eignen sich hervorragend, um die verschiedenen Zeichen in den Texten zu sammeln, ohne dass Duplikate auftreten.
  • Zusammengefasst:

    • input_texts und target_texts: Diese Listen werden verwendet, um die Sätze aus den Eingabe- und Zieldaten zu speichern.
    • input_characters und target_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)])
    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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.

    7. 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.

    8. 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)
    


    Ausgabe:
    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:

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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.

    7. 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.

    8. 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.

    9. 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

    1. 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.

    2. 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.

    3. 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.

    4. 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

    1. 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.

    2. 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.

    3. 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 _).

    4. 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.

    5. 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

    1. 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:

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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.

    7. 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.

    8. 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:

    1. 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.

    2. 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

    1. Funktion definieren: def decode_sequence(input_seq): Eine Funktion namens decode_sequence wird definiert, die eine Eingabesequenz nimmt und die entsprechende Zielsequenz dekodiert.

    2. Encoder-Modell vorhersagen: states_value = encoder_model.predict(input_seq) Die Zustände des Encoders werden durch Vorhersage auf die Eingabesequenz berechnet.

    3. 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.

    4. Startzeichen setzen: target_seq[0, 0, target_token_index['\t']] = 1. Das Startzeichen ('\t') wird als erstes Zeichen der Zielsequenz gesetzt.

    5. 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, und decoded_sentence speichert den dekodierten Satz.

    Dekodierungsschleife

    1. Schleife starten: while not stop_condition: Die Schleife läuft, bis die Stoppbedingung erfüllt ist.

    2. 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 und c.

    3. 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.

    4. Zeichen zum dekodierten Satz hinzufügen: decoded_sentence += sampled_char Das vorhergesagte Zeichen wird zum dekodierten Satz hinzugefügt.

    5. 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.

    6. 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.

    7. Zustände aktualisieren: states_value = [h, c] Die Zustände des Decoders werden aktualisiert.

    8. 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:

    1. 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.

    2. 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:seq_index+1 verwendet, um sicherzustellen, dass die Eingabesequenz die richtige Form hat (1, maximale Sequenzlänge, Anzahl der Eingabezeichen).

    3. 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.

    4. Trennzeichen drucken: print('-') Ein Trennzeichen ('-') wird gedruckt, um die Ausgabe für jede Sequenz optisch zu trennen.

    5. 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.

    6. 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

    1. 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

    1. Zeilenbereich festlegen: for line in lines[0:500]: Eine Schleife wird initialisiert, die über die ersten 500 Zeilen der Liste lines iteriert.

    2. 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 _).

    3. 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.

    4. 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.

    5. 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.

    6. 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

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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

    1. Schleifenbereich festlegen: for seq_index in range(500): Eine Schleife, die über die ersten 500 Sequenzen des neuen Datensatzes iteriert.

    2. 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).

    3. 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.

    4. Trennzeichen drucken: print('-') Ein Trennzeichen ('-') wird gedruckt, um die Ausgabe für jede Sequenz optisch zu trennen.

    5. 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.

    6. 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)
    

    CEO Image

    Ali Ajjoub

    info@ajjoub.com

    Adresse 0049-15773651670

    Adresse Jacob-winter-platz,1 01239 Dresden

    Buchen Sie jetzt Ihren Termin für eine umfassende und individuelle Beratung.

    Termin Buchen

    Kontaktieren Sie uns

    Lassen Sie uns K o n t a k t aufnehmen!