From 84f4fd21d8a475090472a91fef9fd797b512728c Mon Sep 17 00:00:00 2001 From: Fabian Hieber Date: Fri, 4 Oct 2024 15:58:18 +0200 Subject: [PATCH] finished lab --- main.ipynb | 423 +---------------------------------------------------- 1 file changed, 1 insertion(+), 422 deletions(-) diff --git a/main.ipynb b/main.ipynb index 9308e12..6427d3c 100644 --- a/main.ipynb +++ b/main.ipynb @@ -1,422 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Lab | Text Generation from Shakespeare's Sonnet\n", - "\n", - "This notebook explores the fascinating domain of text generation using a deep learning model trained on Shakespeare's sonnets. \n", - "\n", - "The objective is to create a neural network capable of generating text sequences that mimic the style and language of Shakespeare.\n", - "\n", - "By utilizing a Recurrent Neural Network (RNN) with Long Short-Term Memory (LSTM) layers, this project aims to demonstrate how a model can learn and replicate the complex patterns of early modern English. \n", - "\n", - "The dataset used consists of Shakespeare's sonnets, which are preprocessed and tokenized to serve as input for the model.\n", - "\n", - "Throughout this notebook, you will see the steps taken to prepare the data, build and train the model, and evaluate its performance in generating text. \n", - "\n", - "This lab provides a hands-on approach to understanding the intricacies of natural language processing (NLP) and the potential of machine learning in creative text generation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's import necessary libraries" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "id": "BOwsuGQQY9OL", - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-08-16 22:09:18.737563: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", - "To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" - ] - } - ], - "source": [ - "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", - "from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout, Bidirectional\n", - "from tensorflow.keras.preprocessing.text import Tokenizer\n", - "from tensorflow.keras.models import Sequential\n", - "from tensorflow.keras.optimizers import Adam\n", - "from tensorflow.keras import regularizers\n", - "import tensorflow.keras.utils as ku \n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's get the data!" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import requests\n", - "url = 'https://raw.githubusercontent.com/martin-gorner/tensorflow-rnn-shakespeare/master/shakespeare/sonnets.txt'\n", - "resp = requests.get(url)\n", - "with open('sonnets.txt', 'wb') as f:\n", - " f.write(resp.content)\n", - "\n", - "data = open('sonnets.txt').read()\n", - "\n", - "corpus = data.lower().split(\"\\n\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Step 1: Initialise a tokenizer and fit it on the corpus variable using .fit_on_texts" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Step 2: Calculate the Vocabulary Size\n", - "\n", - "Let's figure out how many unique words are in your corpus. This will be the size of your vocabulary.\n", - "\n", - "Calculate the length of tokenizer.word_index, add 1 to it and store it in a variable called total_words." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Create an empty list called input_sequences.\n", - "\n", - "For each sentence in your corpus, convert the text into a sequence of integers using the tokenizer.\n", - "Then, generate n-gram sequences from these tokens.\n", - "\n", - "Store the result in the list input_sequences." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Calculate the length of the longest sequence in input_sequences. Assign the result to a variable called max_sequence_len.\n", - "\n", - "Now pad the sequences using pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre').\n", - "Convert it to a numpy array and assign the result back to our variable called input_sequences." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Prepare Predictors and Labels\n", - "\n", - "Split the sequences into two parts:\n", - "\n", - "- Predictors: All elements from input_sequences except the last one.\n", - "- Labels: The last element of each sequence in input_sequences." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "id": "PRnDnCW-Z7qv", - "tags": [] - }, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One-Hot Encode the Labels :\n", - "\n", - "Convert the labels (which are integers) into one-hot encoded vectors. \n", - "\n", - "Ensure the length of these vectors matches the total number of unique words in your vocabulary.\n", - "\n", - "Use ku.to_categorical() on labels with num_classes = total_words\n", - "\n", - "Assign the result back to our variable labels." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Initialize the Model\n", - "\n", - "Start by creating a Sequential model.\n", - "\n", - "Add Layers to the Model:\n", - "\n", - "Embedding Layer: The first layer is an embedding layer. It converts word indices into dense vectors of fixed size (100 in this case). Set the input length to the maximum sequence length minus one, which corresponds to the number of previous words the model will consider when predicting the next word.\n", - "\n", - "Bidirectional LSTM Layer: Add a Bidirectional LSTM layer with 150 units. This layer allows the model to learn context from both directions (past and future) in the sequence. return_sequences=True\n", - "\n", - "Dropout Layer: Add a dropout layer with a rate of 0.2 to prevent overfitting by randomly setting 20% of the input units to 0 during training.\n", - "\n", - "LSTM Layer: Add a second LSTM layer with 100 units. This layer processes the sequence and passes its output to the next layer.\n", - "\n", - "Dense Layer (Intermediate): Add a dense layer with half the total number of words as units, using ReLU activation. A regularization term (L2) is added to prevent overfitting.\n", - "\n", - "Dense Layer (Output): The final dense layer has as many units as there are words in the vocabulary, with a softmax activation function to output a probability distribution over all words." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "model = Sequential([\n", - "\n", - " # Your code here :\n", - " \n", - "])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Compile the Model:\n", - "\n", - "Compile the model using categorical crossentropy as the loss function, the Adam optimizer for efficient training, and accuracy as the metric to evaluate during training." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Print Model Summary:\n", - "\n", - "Use model.summary() to print a summary of the model, which shows the layers, their output shapes, and the number of parameters." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Now train the model for 50 epochs and assign it to a variable called history.\n", - "\n", - "Training the model with 50 epochs should get you around 40% accuracy.\n", - "\n", - "You can train the model for as many epochs as you like depending on the time and computing constraints you are facing. Ideally train it for a larger amount of epochs than 50.\n", - "\n", - "That way you will get better text generation at the end.\n", - "\n", - "However, dont waste your time." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "id": "AIg2f1HBxqof", - "tags": [] - }, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Use plt from matplotlib to plot the training accuracy over epochs and the loss over epochs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First you will have to get the accuracy and loss data over epochs, you can do this by using methods on your model." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "id": "1fXTEO3GJ282", - "tags": [] - }, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Generate text with the model based on a seed text\n", - "\n", - "Now you will create two variables :\n", - "\n", - "- seed_text = 'Write the text you want the model to use as a starting point to generate the next words'\n", - "- next_words = number_of_words_you_want_the_model_to_generate\n", - "\n", - "Please change number_of_words_you_want_the_model_to_generate by an actual integer." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now create a loop that runs based on the next_words variable and generates new text based on your seed_text input string. Print the full text with the generated text at the end.\n", - "\n", - "This time you dont get detailed instructions.\n", - "\n", - "Have fun!" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "id": "6Vc6PHgxa6Hm", - "tags": [] - }, - "outputs": [], - "source": [ - "# Your code here :" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Experiment with at least 3 different seed_text strings and see what happens!" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "# Your code here :" - ] - } - ], - "metadata": { - "accelerator": "GPU", - "colab": { - "name": "NLP_Week4_Exercise_Shakespeare_Answer.ipynb", - "provenance": [], - "toc_visible": true - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.9" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells":[{"cell_type":"markdown","metadata":{"id":"aR1Vq-V6foOF"},"source":["# Lab | Text Generation from Shakespeare's Sonnet\n","\n","This notebook explores the fascinating domain of text generation using a deep learning model trained on Shakespeare's sonnets.\n","\n","The objective is to create a neural network capable of generating text sequences that mimic the style and language of Shakespeare.\n","\n","By utilizing a Recurrent Neural Network (RNN) with Long Short-Term Memory (LSTM) layers, this project aims to demonstrate how a model can learn and replicate the complex patterns of early modern English.\n","\n","The dataset used consists of Shakespeare's sonnets, which are preprocessed and tokenized to serve as input for the model.\n","\n","Throughout this notebook, you will see the steps taken to prepare the data, build and train the model, and evaluate its performance in generating text.\n","\n","This lab provides a hands-on approach to understanding the intricacies of natural language processing (NLP) and the potential of machine learning in creative text generation."]},{"cell_type":"markdown","metadata":{"id":"sFQlaWa4foOM"},"source":["Let's import necessary libraries"]},{"cell_type":"code","metadata":{"id":"BOwsuGQQY9OL","tags":[],"executionInfo":{"status":"ok","timestamp":1728047349661,"user_tz":-120,"elapsed":299,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.279394Z","start_time":"2024-10-04T12:26:22.327251Z"}},"source":["from tensorflow.keras.preprocessing.sequence import pad_sequences\n","from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout, Bidirectional\n","from tensorflow.keras.preprocessing.text import Tokenizer\n","from tensorflow.keras.models import Sequential\n","from tensorflow.keras.optimizers import Adam\n","from tensorflow.keras import regularizers\n","import tensorflow.keras.utils as ku\n","import numpy as np\n","import matplotlib.pyplot as plt"],"outputs":[],"execution_count":24},{"cell_type":"markdown","metadata":{"id":"88Jxz4zSfoOX"},"source":["Let's get the data!"]},{"cell_type":"code","metadata":{"tags":[],"id":"0Z81fsNhfoOY","executionInfo":{"status":"ok","timestamp":1728046523072,"user_tz":-120,"elapsed":21,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.433161100Z","start_time":"2024-10-02T10:14:42.880728Z"}},"source":["import requests\n","\n","url = 'https://raw.githubusercontent.com/martin-gorner/tensorflow-rnn-shakespeare/master/shakespeare/sonnets.txt'\n","resp = requests.get(url)\n","with open('sonnets.txt', 'wb') as f:\n"," f.write(resp.content)\n","\n","data = open('sonnets.txt').read()\n","\n","corpus = data.lower().split(\"\\n\")"],"outputs":[],"execution_count":2},{"cell_type":"markdown","metadata":{"id":"I9SpoKYQfoOZ"},"source":["Step 1: Initialise a tokenizer and fit it on the corpus variable using .fit_on_texts"]},{"cell_type":"code","metadata":{"id":"bsstU8a4foOa","executionInfo":{"status":"ok","timestamp":1728046523077,"user_tz":-120,"elapsed":24,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.435238600Z","start_time":"2024-10-02T10:14:45.809326Z"}},"source":["tokenizer = Tokenizer()\n","tokenizer.fit_on_texts(corpus)"],"outputs":[],"execution_count":3},{"cell_type":"markdown","metadata":{"id":"qVO3hYxufoOb"},"source":["Step 2: Calculate the Vocabulary Size\n","\n","Let's figure out how many unique words are in your corpus. This will be the size of your vocabulary.\n","\n","Calculate the length of tokenizer.word_index, add 1 to it and store it in a variable called total_words."]},{"cell_type":"code","metadata":{"id":"3_gD4NsCfoOc","executionInfo":{"status":"ok","timestamp":1728046523077,"user_tz":-120,"elapsed":23,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.436317100Z","start_time":"2024-10-02T10:14:48.139768Z"}},"source":["total_words = len(tokenizer.word_index) + 1"],"outputs":[],"execution_count":4},{"cell_type":"markdown","metadata":{"id":"EfLQkzBwfoOd"},"source":["Create an empty list called input_sequences.\n","\n","For each sentence in your corpus, convert the text into a sequence of integers using the tokenizer.\n","Then, generate n-gram sequences from these tokens.\n","\n","Store the result in the list input_sequences."]},{"cell_type":"code","metadata":{"id":"R99J0Ys2foOe","executionInfo":{"status":"ok","timestamp":1728046523078,"user_tz":-120,"elapsed":24,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.437455300Z","start_time":"2024-10-02T10:14:50.311432Z"}},"source":["input_sequences = []\n","for line in corpus:\n"," token_list = tokenizer.texts_to_sequences([line])[0]\n"," for i in range(1, len(token_list)):\n"," n_gram_sequence = token_list[:i + 1]\n"," input_sequences.append(n_gram_sequence)"],"outputs":[],"execution_count":5},{"cell_type":"markdown","metadata":{"id":"QFXJ2UhpfoOf"},"source":["Calculate the length of the longest sequence in input_sequences. Assign the result to a variable called max_sequence_len.\n","\n","Now pad the sequences using pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre').\n","Convert it to a numpy array and assign the result back to our variable called input_sequences."]},{"cell_type":"code","metadata":{"id":"qC3JvOE4foOf","executionInfo":{"status":"ok","timestamp":1728046523078,"user_tz":-120,"elapsed":24,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.438536900Z","start_time":"2024-10-02T10:14:51.900778Z"}},"source":["max_sequence_len = max([len(x) for x in input_sequences])\n","input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre')\n","input_sequences = np.array(input_sequences)"],"outputs":[],"execution_count":6},{"cell_type":"markdown","metadata":{"id":"q7nWPDKufoOg"},"source":["Prepare Predictors and Labels\n","\n","Split the sequences into two parts:\n","\n","- Predictors: All elements from input_sequences except the last one.\n","- Labels: The last element of each sequence in input_sequences."]},{"cell_type":"code","source":["input_sequences.shape"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"AqL1jLJJidea","executionInfo":{"status":"ok","timestamp":1728046523078,"user_tz":-120,"elapsed":23,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"ae5f76a5-311e-46a3-c8fc-63c795e66b27","ExecuteTime":{"end_time":"2024-10-04T12:26:45.451486700Z","start_time":"2024-10-02T10:14:53.683106Z"}},"outputs":[{"output_type":"execute_result","data":{"text/plain":["(15484, 11)"]},"metadata":{},"execution_count":7}],"execution_count":7},{"cell_type":"code","metadata":{"id":"PRnDnCW-Z7qv","tags":[],"executionInfo":{"status":"ok","timestamp":1728046523079,"user_tz":-120,"elapsed":21,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.452443200Z","start_time":"2024-10-02T10:14:55.197817Z"}},"source":["predictors = input_sequences[:, :-1]\n","labels = input_sequences[:, -1]"],"outputs":[],"execution_count":8},{"cell_type":"code","source":["print(predictors.shape)\n","print(labels.shape)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"333KU_NNkgih","executionInfo":{"status":"ok","timestamp":1728046523079,"user_tz":-120,"elapsed":20,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"63a3b77c-4491-450f-99fc-7611b89e5208"},"execution_count":9,"outputs":[{"output_type":"stream","name":"stdout","text":["(15484, 10)\n","(15484,)\n"]}]},{"cell_type":"markdown","metadata":{"id":"83JhPmhefoOh"},"source":["One-Hot Encode the Labels :\n","\n","Convert the labels (which are integers) into one-hot encoded vectors.\n","\n","Ensure the length of these vectors matches the total number of unique words in your vocabulary.\n","\n","Use ku.to_categorical() on labels with num_classes = total_words\n","\n","Assign the result back to our variable labels."]},{"cell_type":"code","metadata":{"id":"djbD1kOVfoOi","executionInfo":{"status":"ok","timestamp":1728046523401,"user_tz":-120,"elapsed":339,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"ExecuteTime":{"end_time":"2024-10-04T12:26:45.453447700Z","start_time":"2024-10-02T10:14:57.024266Z"}},"source":["labels = ku.to_categorical(labels, num_classes=total_words)"],"outputs":[],"execution_count":10},{"cell_type":"markdown","metadata":{"id":"mHtL0hxufoOj"},"source":["# Initialize the Model\n","\n","Start by creating a Sequential model.\n","\n","Add Layers to the Model:\n","\n","Embedding Layer: The first layer is an embedding layer. It converts word indices into dense vectors of fixed size (100 in this case). Set the input length to the maximum sequence length minus one, which corresponds to the number of previous words the model will consider when predicting the next word.\n","\n","Bidirectional LSTM Layer: Add a Bidirectional LSTM layer with 150 units. This layer allows the model to learn context from both directions (past and future) in the sequence. return_sequences=True\n","\n","Dropout Layer: Add a dropout layer with a rate of 0.2 to prevent overfitting by randomly setting 20% of the input units to 0 during training.\n","\n","LSTM Layer: Add a second LSTM layer with 100 units. This layer processes the sequence and passes its output to the next layer.\n","\n","Dense Layer (Intermediate): Add a dense layer with half the total number of words as units, using ReLU activation. A regularization term (L2) is added to prevent overfitting.\n","\n","Dense Layer (Output): The final dense layer has as many units as there are words in the vocabulary, with a softmax activation function to output a probability distribution over all words."]},{"cell_type":"code","metadata":{"id":"blvD0r--foOk","ExecuteTime":{"end_time":"2024-10-04T12:26:45.455458500Z","start_time":"2024-10-02T10:18:35.328015Z"},"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1728046523711,"user_tz":-120,"elapsed":316,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"f3585f98-53c4-43f2-8d1f-c9faa3f51aca"},"source":["model = Sequential([\n"," Embedding(input_dim=total_words, output_dim=100, input_length=max_sequence_len - 1),\n"," Bidirectional(LSTM(150, return_sequences=True)),\n"," Dropout(0.2),\n"," LSTM(100),\n"," Dense(units=total_words // 2, activation='relu', kernel_regularizer='L2'),\n"," Dense(units=total_words, activation='softmax')\n","])"],"outputs":[{"output_type":"stream","name":"stderr","text":["/usr/local/lib/python3.10/dist-packages/keras/src/layers/core/embedding.py:90: UserWarning: Argument `input_length` is deprecated. Just remove it.\n"," warnings.warn(\n"]}],"execution_count":11},{"cell_type":"markdown","metadata":{"id":"1714-j6GfoOl"},"source":["# Compile the Model:\n","\n","Compile the model using categorical crossentropy as the loss function, the Adam optimizer for efficient training, and accuracy as the metric to evaluate during training."]},{"metadata":{"ExecuteTime":{"end_time":"2024-10-04T12:26:45.456588400Z","start_time":"2024-10-02T10:18:38.512057Z"},"id":"WLBjb2FEgZNx","executionInfo":{"status":"ok","timestamp":1728049476642,"user_tz":-120,"elapsed":285,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}}},"cell_type":"code","source":["model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])"],"outputs":[],"execution_count":70},{"cell_type":"markdown","metadata":{"id":"DKVzBodUfoOo"},"source":["# Print Model Summary:\n","\n","Use model.summary() to print a summary of the model, which shows the layers, their output shapes, and the number of parameters."]},{"cell_type":"code","metadata":{"id":"xMjW0pmtfoOp","ExecuteTime":{"end_time":"2024-10-04T12:26:45.466418400Z","start_time":"2024-10-02T10:18:40.238235Z"},"colab":{"base_uri":"https://localhost:8080/","height":348},"executionInfo":{"status":"ok","timestamp":1728049479068,"user_tz":-120,"elapsed":281,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"dcb97969-fe90-4797-dbec-47030b8b2c8c"},"source":["model.build()\n","print(model.summary())"],"outputs":[{"output_type":"display_data","data":{"text/plain":["\u001b[1mModel: \"sequential\"\u001b[0m\n"],"text/html":["
Model: \"sequential\"\n","
\n"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n","┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n","┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n","│ embedding (\u001b[38;5;33mEmbedding\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m337,500\u001b[0m │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ bidirectional (\u001b[38;5;33mBidirectional\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m, \u001b[38;5;34m300\u001b[0m) │ \u001b[38;5;34m301,200\u001b[0m │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m, \u001b[38;5;34m300\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ lstm_1 (\u001b[38;5;33mLSTM\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m160,400\u001b[0m │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1687\u001b[0m) │ \u001b[38;5;34m170,387\u001b[0m │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m3375\u001b[0m) │ \u001b[38;5;34m5,697,000\u001b[0m │\n","└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n"],"text/html":["
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n","┃ Layer (type)                          Output Shape                         Param # ┃\n","┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n","│ embedding (Embedding)                │ (None, 10, 100)             │         337,500 │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ bidirectional (Bidirectional)        │ (None, 10, 300)             │         301,200 │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dropout (Dropout)                    │ (None, 10, 300)             │               0 │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ lstm_1 (LSTM)                        │ (None, 100)                 │         160,400 │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dense (Dense)                        │ (None, 1687)                │         170,387 │\n","├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n","│ dense_1 (Dense)                      │ (None, 3375)                │       5,697,000 │\n","└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n","
\n"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["\u001b[1m Total params: \u001b[0m\u001b[38;5;34m6,666,487\u001b[0m (25.43 MB)\n"],"text/html":["
 Total params: 6,666,487 (25.43 MB)\n","
\n"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m6,666,487\u001b[0m (25.43 MB)\n"],"text/html":["
 Trainable params: 6,666,487 (25.43 MB)\n","
\n"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"],"text/html":["
 Non-trainable params: 0 (0.00 B)\n","
\n"]},"metadata":{}},{"output_type":"stream","name":"stdout","text":["None\n"]}],"execution_count":71},{"cell_type":"markdown","metadata":{"id":"rFj9xr0XfoOq"},"source":["# Now train the model for 50 epochs and assign it to a variable called history.\n","\n","Training the model with 50 epochs should get you around 40% accuracy.\n","\n","You can train the model for as many epochs as you like depending on the time and computing constraints you are facing. Ideally train it for a larger amount of epochs than 50.\n","\n","That way you will get better text generation at the end.\n","\n","However, dont waste your time."]},{"cell_type":"code","metadata":{"id":"AIg2f1HBxqof","tags":[],"ExecuteTime":{"end_time":"2024-10-04T12:26:45.468416700Z","start_time":"2024-10-04T12:26:00.906537Z"},"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1728050166494,"user_tz":-120,"elapsed":683368,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"e84031aa-4dad-4792-b2f2-ad97711060f5"},"source":["history = model.fit(predictors, labels, epochs=80, verbose=1)"],"outputs":[{"output_type":"stream","name":"stdout","text":["Epoch 1/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 14ms/step - accuracy: 0.6584 - loss: 1.8659\n","Epoch 2/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 14ms/step - accuracy: 0.6821 - loss: 1.8032\n","Epoch 3/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.6910 - loss: 1.7472\n","Epoch 4/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.6986 - loss: 1.7197\n","Epoch 5/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 14ms/step - accuracy: 0.6871 - loss: 1.7491\n","Epoch 6/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.6998 - loss: 1.7001\n","Epoch 7/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7082 - loss: 1.6554\n","Epoch 8/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7119 - loss: 1.6474\n","Epoch 9/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7193 - loss: 1.6025\n","Epoch 10/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7241 - loss: 1.5765\n","Epoch 11/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7305 - loss: 1.5549\n","Epoch 12/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7334 - loss: 1.5435\n","Epoch 13/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.7335 - loss: 1.5301\n","Epoch 14/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7368 - loss: 1.5245\n","Epoch 15/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.7443 - loss: 1.4838\n","Epoch 16/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7487 - loss: 1.4721\n","Epoch 17/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 13ms/step - accuracy: 0.7426 - loss: 1.4924\n","Epoch 18/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.7438 - loss: 1.4654\n","Epoch 19/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7538 - loss: 1.4364\n","Epoch 20/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7461 - loss: 1.4561\n","Epoch 21/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.7596 - loss: 1.4137\n","Epoch 22/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7612 - loss: 1.4012\n","Epoch 23/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7556 - loss: 1.3996\n","Epoch 24/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7741 - loss: 1.3287\n","Epoch 25/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.7689 - loss: 1.3345\n","Epoch 26/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.7721 - loss: 1.3112\n","Epoch 27/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7729 - loss: 1.3428\n","Epoch 28/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7669 - loss: 1.3251\n","Epoch 29/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7843 - loss: 1.2697\n","Epoch 30/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.7741 - loss: 1.3094\n","Epoch 31/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.7754 - loss: 1.2848\n","Epoch 32/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7818 - loss: 1.2557\n","Epoch 33/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7907 - loss: 1.2365\n","Epoch 34/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7817 - loss: 1.2674\n","Epoch 35/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.7814 - loss: 1.2494\n","Epoch 36/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7843 - loss: 1.2287\n","Epoch 37/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7877 - loss: 1.2332\n","Epoch 38/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7907 - loss: 1.2046\n","Epoch 39/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - accuracy: 0.7896 - loss: 1.1904\n","Epoch 40/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7952 - loss: 1.1820\n","Epoch 41/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.7955 - loss: 1.1624\n","Epoch 42/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.7936 - loss: 1.1703\n","Epoch 43/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8011 - loss: 1.1666\n","Epoch 44/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8051 - loss: 1.1338\n","Epoch 45/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8039 - loss: 1.1367\n","Epoch 46/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8077 - loss: 1.1276\n","Epoch 47/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8063 - loss: 1.1155\n","Epoch 48/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8018 - loss: 1.1382\n","Epoch 49/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 13ms/step - accuracy: 0.8142 - loss: 1.0895\n","Epoch 50/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8034 - loss: 1.1299\n","Epoch 51/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8144 - loss: 1.0795\n","Epoch 52/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8176 - loss: 1.0602\n","Epoch 53/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8119 - loss: 1.0790\n","Epoch 54/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8107 - loss: 1.0809\n","Epoch 55/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8089 - loss: 1.0848\n","Epoch 56/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8156 - loss: 1.0633\n","Epoch 57/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8093 - loss: 1.0636\n","Epoch 58/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - accuracy: 0.8096 - loss: 1.0698\n","Epoch 59/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 14ms/step - accuracy: 0.8132 - loss: 1.0512\n","Epoch 60/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8103 - loss: 1.0508\n","Epoch 61/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8144 - loss: 1.0422\n","Epoch 62/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8173 - loss: 1.0342\n","Epoch 63/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8142 - loss: 1.0371\n","Epoch 64/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8103 - loss: 1.0412\n","Epoch 65/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8160 - loss: 1.0338\n","Epoch 66/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8178 - loss: 1.0179\n","Epoch 67/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8195 - loss: 1.0100\n","Epoch 68/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - accuracy: 0.8212 - loss: 1.0024\n","Epoch 69/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8194 - loss: 1.0044\n","Epoch 70/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8193 - loss: 0.9942\n","Epoch 71/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 13ms/step - accuracy: 0.8316 - loss: 0.9631\n","Epoch 72/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8250 - loss: 0.9797\n","Epoch 73/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8188 - loss: 0.9892\n","Epoch 74/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8226 - loss: 0.9893\n","Epoch 75/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 14ms/step - accuracy: 0.8281 - loss: 0.9621\n","Epoch 76/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 13ms/step - accuracy: 0.8259 - loss: 0.9621\n","Epoch 77/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8319 - loss: 0.9530\n","Epoch 78/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 13ms/step - accuracy: 0.8265 - loss: 0.9620\n","Epoch 79/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 12ms/step - accuracy: 0.8218 - loss: 0.9664\n","Epoch 80/80\n","\u001b[1m484/484\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 12ms/step - accuracy: 0.8289 - loss: 0.9428\n"]}],"execution_count":72},{"cell_type":"markdown","metadata":{"id":"kjISA7-ufoOt"},"source":["# Use plt from matplotlib to plot the training accuracy over epochs and the loss over epochs"]},{"cell_type":"markdown","metadata":{"id":"SA8CjnNOfoOu"},"source":["First you will have to get the accuracy and loss data over epochs, you can do this by using methods on your model."]},{"cell_type":"code","execution_count":73,"metadata":{"id":"1fXTEO3GJ282","tags":[],"colab":{"base_uri":"https://localhost:8080/","height":452},"executionInfo":{"status":"ok","timestamp":1728050172256,"user_tz":-120,"elapsed":382,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"08efaffc-7dc4-48ef-c745-da59c148c214"},"outputs":[{"output_type":"display_data","data":{"text/plain":["
"],"image/png":"iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABZ60lEQVR4nO3deVxVdf7H8ddlu+zgwqai4L5ruaVW5miZmpOtlk5qZk0z1lROM2VN+2LLTNM69ptKbdEsHS1LsxxLTXNySSyXXBKFFFBUQBZBuOf3x1euoKCgwOHC+3ke58G9h3Pu/Rwo74fv8vk6LMuyEBEREbGJl90BiIiISP2mZERERERspWREREREbKVkRERERGylZERERERspWREREREbKVkRERERGylZERERERspWREREREbKVkRERERGylZESklpg5cyYOh4P169fbHUqFHDlyBB8fHz7++OMKnX/jjTficDh44IEHqjkyEfE0SkZE5Jx8+eWXOBwOrrjiirOem5WVxWeffUZcXBwffvghWhJLREpSMiIi52Tx4sX079+f8PDws577n//8h6KiIqZPn05ycjIrV66s/gDPgWVZ5OXl2R2GSL2jZETEw2zcuJGhQ4cSGhpKcHAwgwYN4n//+1+pc44fP84TTzxBmzZt8Pf3p1GjRlx88cUsXbrUfU5qaiq33norzZo1w+l0EhMTw9VXX82ePXvOGoPL5WLJkiUMHz68QjHPmjWLyy+/nIEDB9KhQwdmzZpV5nk///wzN954IxEREQQEBNCuXTsefvjhUufs27eP2267jSZNmuB0OomPj+cPf/gDBQUFADz++OM4HI7TXru4G6zk/cXFxXHVVVfx5Zdf0rNnTwICAvi///s/AGbMmMFvfvMbIiMjcTqddOzYkWnTppUZ9xdffMGAAQMICQkhNDSUXr16MXv2bAAee+wxfH19OXjw4GnX3XHHHYSHh3Ps2LGz/xBF6jAfuwMQkYrbsmULl1xyCaGhofz1r3/F19eX//u//+Oyyy5jxYoV9OnTBzAfyFOnTmXixIn07t2brKws1q9fzw8//MDll18OwHXXXceWLVu4++67iYuL48CBAyxdupSkpCTi4uLOGMe6des4ePAgw4YNO2vM+/fv55tvvuHdd98F4Oabb+af//wnr7/+On5+fu7zfvzxRy655BJ8fX254447iIuL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XCQmJuLt7U2TJk3w8/NTIUk5Z5ZlUVBQwMGDB0lMTKRNmzZnLGx2JpVKRiZNmsTs2bP59NNPCQkJcY/7CAsLIyAgAICxY8fStGlTpk6dCsA999zDgAED+Mc//sHw4cOZM2cO69ev59///vc5BSwiIuemoKAAl8tFbGwsgYGBdocjdUBAQAC+vr7s3buXgoIC/P39z+l1KpXCTJs2jczMTC677DJiYmLc+0cffeQ+JykpiZSUFPfzfv36MXv2bP7973/TrVs35s2bxyeffFLhGiMiIlK1zvWvV5GyVMV/T5Xupjmb5cuXn3bshhtu4IYbbqjMW4mIiEg9ofRYREREbKVkRERE6p24uDhefvll219DDI9YtVdEROq3yy67jO7du1fZh/+6devKXVNNal79TkY2b4bdu6FHD2ja1O5oRETkPFiWRVFRET4+Z/9oi4iIqIGIpKLqdzfNtm2wcSPs2WN3JCIi9rAsKCio+b0Sa7SOHz+eFStW8Morr+BwOHA4HOzZs4fly5fjcDj44osv6NGjB06nk1WrVvHLL79w9dVXExUVRXBwML169eK///1vqdc8tYvF4XDw9ttvc8011xAYGEibNm1YuHBhpX6USUlJXH311QQHBxMaGsqNN95Yqujnpk2bGDhwICEhIYSGhtKjRw/Wr18PwN69exkxYgQNGjQgKCiITp06sXjx4kq9vyer3y0jMTGwdSvs3293JCIi9jh+HE7UhapRU6ZABSt2vvLKK+zYsYPOnTvz5JNPAqZlY8+JPyQffPBB/v73v9OyZUsaNGhAcnIyw4YN45lnnsHpdPLee+8xYsQItm/fTvPmzct9nyeeeIIXXniBF198kddee40xY8awd+/eMy4GW8zlcrkTkRUrVlBYWMikSZMYNWqUe5bpmDFjuOCCC5g2bRre3t4kJCTg6+sLmDpeBQUFrFy5kqCgILZu3UpwcHCFfj51Qf1ORoq7ZpSMiIjUWmFhYfj5+REYGFjmUiJPPvkkl19+uft5w4YN6datm/v5U089xYIFC1i4cCF33XVXue8zfvx4br75ZgCeffZZXn31VdauXcuVV1551hiXLVvGTz/9RGJionsttffee49OnTqxbt06evXqRVJSEn/5y19o3749AG3atHFfn5SUxHXXXUeXLl0AaNmy5Vnfsy6p38lITIz5mpEBubmgioQiUt/4+ppWCjvet4r07Nmz1PPs7Gwef/xxFi1aREpKCoWFheTl5ZGUlHTG1+natav7cVBQEKGhoRw4cKBCMWzbto3Y2NhSi7p27NiR8PBwtm3bRq9evZg8eTITJ07k/fffZ/Dgwdxwww20atUKgD/96U/84Q9/4KuvvmLw4MFcd911peKp6+r3mBF/fyhuflPriIjURw6H6S6p6b0K18Q5dVbM/fffz4IFC3j22Wf59ttvSUhIoEuXLhQUFJzxdXxPSZAcDgcul6vK4nz88cfZsmULw4cP5+uvv6Zjx44sWLAAgIkTJ7J7925uueUWfvrpJ3r27Mlrr71WZe9d29XvZATUVSMi4gH8/PwoKiqq0LmrV69m/PjxXHPNNXTp0oXo6Gj3+JLq0qFDB5KTk0lOTnYf27p1KxkZGXTs2NF9rG3bttx333189dVXXHvttcyYMcP9vdjYWO68807mz5/Pn//8Z956661qjbk2UTJS3FWjZEREpNaKi4vj+++/Z8+ePaSnp5+xxaJNmzbMnz+fhIQENm3axOjRo6u0haMsgwcPpkuXLowZM4YffviBtWvXMnbsWAYMGEDPnj3Jy8vjrrvuYvny5ezdu5fVq1ezbt06OnToAMC9997Ll19+SWJiIj/88APffPON+3v1gZKRJk3MVyUjIiK11v3334+3tzcdO3YkIiLijOM/XnrpJRo0aEC/fv0YMWIEQ4YM4cILL6zW+BwOB59++ikNGjTg0ksvZfDgwbRs2dK9kKy3tzeHDh1i7NixtG3blhtvvJGhQ4fyxBNPAFBUVMSkSZPo0KEDV155JW3btuVf//pXtcZcmzisiqx+Z7OsrCzCwsLIzMwkNDS0al+8oACee87MeZ88GUJCqvb1RURqiWPHjpGYmEh8fPw5L/Uucqoz/XdV0c9vtYz4+UHjxuaxWkdERERqnJIR0CBWERERGykZAQ1iFRERsZGSESg9iLX2D6ERERGpU5SMAERHg5eXqcKalWV3NCIiIvWKkhEAHx+IjDSP9+2zNxYREZF6RslIMdUbERERsYWSkWLFyUhKir1xiIiI1DNKRoppEKuIiIgtlIwUi4wEb284dgyOHLE7GhERqUZxcXG8/PLLdochJ/jYHUCt4e1tZtXs22f2hg3tjkhERE647LLL6N69e5UlEOvWrSMoKKhKXkvOn1pGStIgVhERj2VZFoWFhRU6NyIigsDAwGqOqGZV5v5rGyUjJWkQq4jUMxYWBTZsFhUfmzd+/HhWrFjBK6+8gsPhwOFwsGfPHpYvX47D4eCLL76gR48eOJ1OVq1axS+//MLVV19NVFQUwcHB9OrVi//+97+lXvPUbhqHw8Hbb7/NNddcQ2BgIG3atGHhwoVnjOv999+nZ8+ehISEEB0dzejRozlw4ECpc7Zs2cJVV11FaGgoISEhXHLJJfzyyy/u70+fPp1OnTrhdDqJiYnhrrvuAmDPnj04HA4SEhLc52ZkZOBwOFi+fDnAed1/fn4+DzzwALGxsTidTlq3bs0777yDZVm0bt2av//976XOT0hIwOFwsGvXrjP+TM6VumlKKtky4nKZQmgiInXYcY4zlak1/r5TmIIffhU695VXXmHHjh107tyZJ598EjAtG3v27AHgwQcf5O9//zstW7akQYMGJCcnM2zYMJ555hmcTifvvfceI0aMYPv27TRv3rzc93niiSd44YUXePHFF3nttdcYM2YMe/fupWE53fbHjx/nqaeeol27dhw4cIDJkyczfvx4Fi9eDMC+ffu49NJLueyyy/j6668JDQ1l9erV7taLadOmMXnyZJ577jmGDh1KZmYmq1evruiP0O1c7n/s2LGsWbOGV199lW7dupGYmEh6ejoOh4MJEyYwY8YM7r//fvd7zJgxg0svvZTWrVtXOr6KUDJSUuPG4OsLx4/DoUMQEWF3RCIi9V5YWBh+fn4EBgYSHR192veffPJJLr/8cvfzhg0b0q1bN/fzp556igULFrBw4UJ3y0NZxo8fz8033wzAs88+y6uvvsratWu58soryzx/woQJ7sctW7bk1VdfpVevXmRnZxMcHMwbb7xBWFgYc+bMwdfXF4C2bdu6r3n66af585//zD333OM+1qtXr7P9OE5T2fvfsWMHH3/8MUuXLmXw4MHu+Ev+HB599FHWrl1L7969OX78OLNnzz6ttaQqKRkpycvLLJqXlGQGsSoZEZE6zhdfpjDFlvetKj179iz1PDs7m8cff5xFixaRkpJCYWEheXl5JCUlnfF1unbt6n4cFBREaGjoad0uJW3YsIHHH3+cTZs2ceTIEVwuFwBJSUl07NiRhIQELrnkEnciUtKBAwfYv38/gwYNqsytlqmy95+QkIC3tzcDBgwo8/WaNGnC8OHDmT59Or179+azzz4jPz+fG2644bxjLY/6IU6lQawiUo84cOBnw+bAUWX3cOqsmPvvv58FCxbw7LPP8u2335KQkECXLl0oKCg44+ucmjQ4HA53gnGqnJwchgwZQmhoKLNmzWLdunUsWLAAwP0+AQEB5b7Xmb4H4HVimIBVou7V8ePHyzy3svd/tvcGmDhxInPmzCEvL48ZM2YwatSoah3wq2TkVBrEKiJS6/j5+VFUVFShc1evXs348eO55ppr6NKlC9HR0e7xJVXl559/5tChQzz33HNccskltG/f/rRWlK5du/Ltt9+WmUSEhIQQFxfHsmXLynz9iBMt8yklPotKDmY9k7Pdf5cuXXC5XKxYsaLc1xg2bBhBQUFMmzaNJUuWlOqSqg5KRk5VMhmp4H/4IiJSveLi4vj+++/Zs2cP6enp5bZYALRp04b58+eTkJDApk2bGD169BnPPxfNmzfHz8+P1157jd27d7Nw4UKeeuqpUufcddddZGVlcdNNN7F+/Xp27tzJ+++/z/bt2wF4/PHH+cc//sGrr77Kzp07+eGHH3jttdcA03px0UUX8dxzz7Ft2zZWrFjB3/72twrFdrb7j4uLY9y4cUyYMIFPPvmExMREli9fzscff+w+x9vbm/HjxzNlyhTatGlD3759z/dHdkZKRk7VsCEEBZlE5IsvVBpeRKQWuP/++/H29qZjx45ERESccfzHSy+9RIMGDejXrx8jRoxgyJAhXHjhhVUaT0REBDNnzmTu3Ll07NiR55577rQBno0aNeLrr78mOzubAQMG0KNHD9566y13d9C4ceN4+eWX+de//kWnTp246qqr2Llzp/v66dOnU1hYSI8ePbj33nt5+umnKxRbRe5/2rRpXH/99fzxj3+kffv23H777eTk5JQ657bbbqOgoIBbb731XH5EleKwrNr/aZuVlUVYWBiZmZmEhoZW/xv+/DN89JF5fPnl0K9f9b+niEg1O3bsGImJicTHx+Pv7293OFLLffvttwwaNIjk5GSioqLKPe9M/11V9PNbLSNlad8ehgwxj5cuhS1b7I1HRESkhuTn5/Prr7/y+OOPc8MNN5wxEakqSkbK06cP9O5tHi9YAMnJ9sYjIiJSAz788ENatGhBRkYGL7zwQo28p5KR8jgcpnWkXTszfmTOHDh82O6oREREqtX48eMpKipiw4YNNG3atEbeU8nImXh5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bFWvkxGn08ljjz1Wp6u91od7hPpxn7rHukH3WDfoHquWRwxgFRERkbqrXreMiIiIiP2UjIiIiIitlIyIiIiIrZSMiIiIiK2UjIiIiIit6nUy8sYbbxAXF4e/vz99+vRh7dq1dod0zlauXMmIESNo0qQJDoeDTz75pNT3Lcvi0UcfJSYmhoCAAAYPHszOnTvtCfYcTZ06lV69ehESEkJkZCQjR45k+/btpc45duwYkyZNolGjRgQHB3PdddeRlpZmU8SVN23aNLp27equeNi3b1+++OIL9/c9/f7K8txzz+FwOLj33nvdxzz9Ph9//HEcDkepvX379u7ve/r9Fdu3bx+/+93vaNSoEQEBAXTp0oX169e7v+/p/+7ExcWd9nt0OBxMmjQJqBu/x6KiIh555BHi4+MJCAigVatWPPXUU5ScaFsjv0ernpozZ47l5+dnTZ8+3dqyZYt1++23W+Hh4VZaWprdoZ2TxYsXWw8//LA1f/58C7AWLFhQ6vvPPfecFRYWZn3yySfWpk2brN/+9rdWfHy8lZeXZ0/A52DIkCHWjBkzrM2bN1sJCQnWsGHDrObNm1vZ2dnuc+68804rNjbWWrZsmbV+/Xrroosusvr162dj1JWzcOFCa9GiRdaOHTus7du3Ww899JDl6+trbd682bIsz7+/U61du9aKi4uzunbtat1zzz3u455+n4899pjVqVMnKyUlxb0fPHjQ/X1Pvz/LsqzDhw9bLVq0sMaPH299//331u7du60vv/zS2rVrl/scT/9358CBA6V+h0uXLrUA65tvvrEsq278Hp955hmrUaNG1ueff24lJiZac+fOtYKDg61XXnnFfU5N/B7rbTLSu3dva9KkSe7nRUVFVpMmTaypU6faGFXVODUZcblcVnR0tPXiiy+6j2VkZFhOp9P68MMPbYiwahw4cMACrBUrVliWZe7J19fXmjt3rvucbdu2WYC1Zs0au8I8bw0aNLDefvvtOnd/R48etdq0aWMtXbrUGjBggDsZqQv3+dhjj1ndunUr83t14f4sy7IeeOAB6+KLLy73+3Xx35177rnHatWqleVyuerM73H48OHWhAkTSh279tprrTFjxliWVXO/x3rZTVNQUMCGDRsYPHiw+5iXlxeDBw9mzZo1NkZWPRITE0lNTS11v2FhYfTp08ej7zczMxOAhg0bArBhwwaO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\n"},"metadata":{}}],"source":["plt.title('Loss / Accuracy')\n","plt.plot(history.history['loss'], color='#ff8080', label='train loss')\n","plt.plot(history.history['accuracy'], color='#80ff80', label='train accuracy')\n","plt.legend()\n","plt.show()"]},{"cell_type":"markdown","metadata":{"id":"6pilMAqufoOw"},"source":["# Generate text with the model based on a seed text\n","\n","Now you will create two variables :\n","\n","- seed_text = 'Write the text you want the model to use as a starting point to generate the next words'\n","- next_words = number_of_words_you_want_the_model_to_generate\n","\n","Please change number_of_words_you_want_the_model_to_generate by an actual integer."]},{"cell_type":"code","execution_count":74,"metadata":{"id":"MbqU3pzvfoOy","executionInfo":{"status":"ok","timestamp":1728050175959,"user_tz":-120,"elapsed":399,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}}},"outputs":[],"source":["seed_text = \"Will Stuttgart win the Champions League?\"\n","next_words = 20"]},{"cell_type":"markdown","metadata":{"id":"kTkz90btfoOz"},"source":["\n","Now create a loop that runs based on the next_words variable and generates new text based on your seed_text input string. Print the full text with the generated text at the end.\n","\n","This time you dont get detailed instructions.\n","\n","Have fun!"]},{"cell_type":"code","execution_count":75,"metadata":{"id":"6Vc6PHgxa6Hm","tags":[],"colab":{"base_uri":"https://localhost:8080/","height":35},"executionInfo":{"status":"ok","timestamp":1728050181037,"user_tz":-120,"elapsed":1760,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"619dab85-ce36-41b5-ca65-0d6a0701a512"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["'with a limit past thee well sight in time and words days add some mother leaves leaves cold dearer face'"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"string"}},"metadata":{},"execution_count":75}],"source":["def answer(question, words):\n"," initial = question\n"," for _ in range(words):\n"," token_list = tokenizer.texts_to_sequences([initial])[0]\n"," token_list = pad_sequences([token_list], maxlen=max_sequence_len - 1, padding='pre')\n","\n"," prediction = model.predict(token_list, verbose=0)\n"," prediction_index = np.argmax(prediction, axis=-1)\n","\n"," for word, index in tokenizer.word_index.items():\n"," if index == prediction_index:\n"," initial += \" \" + word\n"," break\n"," return initial.replace(f\"{question} \", \"\")\n","\n","answer(seed_text, next_words)"]},{"cell_type":"code","source":[],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ph9MJd2YsHWd","executionInfo":{"status":"ok","timestamp":1728048064328,"user_tz":-120,"elapsed":294,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"184ccadf-4468-4af1-83ca-db06cc716d5b"},"execution_count":36,"outputs":[{"output_type":"execute_result","data":{"text/plain":["58"]},"metadata":{},"execution_count":36}]},{"cell_type":"markdown","metadata":{"id":"YwCqaT7QfoO1"},"source":["Experiment with at least 3 different seed_text strings and see what happens!"]},{"cell_type":"code","execution_count":76,"metadata":{"id":"_n_CFwXxfoO2","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1728050191601,"user_tz":-120,"elapsed":3935,"user":{"displayName":"Fabian Hieber","userId":"06681858431281640040"}},"outputId":"4c126d22-2b5a-47c2-bbaf-fb9095f45bf4"},"outputs":[{"output_type":"stream","name":"stdout","text":["weeds last days light far ' new spent had far to new time thee so you ' have had thee well so fired hate me\n","full of every hours in night time sight in loss with gentle sight had proved time alone in thine and thee sun heart simple too rhyme quite near thee told\n","should give possession to thy deeds ' ' ' do hate me see me back\n"]}],"source":["print(answer(\"Do you have a cup of coffee?\", 25))\n","print(answer(\"The weather is quite nice\", 30))\n","print(answer(\"Can you help me?\", 15))"]}],"metadata":{"accelerator":"GPU","colab":{"provenance":[]},"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.9"}},"nbformat":4,"nbformat_minor":0} \ No newline at end of file