{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "02cbdb19", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2025-05-14 22:59:30.964921: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", "2025-05-14 22:59:30.965513: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", "2025-05-14 22:59:30.969003: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", "2025-05-14 22:59:30.976754: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:467] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n", "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n", "E0000 00:00:1747238370.990701 467162 cuda_dnn.cc:8579] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n", "E0000 00:00:1747238370.994078 467162 cuda_blas.cc:1407] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n", "W0000 00:00:1747238371.004091 467162 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n", "W0000 00:00:1747238371.004113 467162 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n", "W0000 00:00:1747238371.004115 467162 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n", "W0000 00:00:1747238371.004117 467162 computation_placer.cc:177] computation placer already registered. Please check linkage and avoid linking the same target more than once.\n", "2025-05-14 22:59:31.007720: 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 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" ] } ], "source": [ "import numpy as np\n", "import json\n", "import random\n", "import tensorflow as tf\n", "from tensorflow.keras.preprocessing.text import Tokenizer\n", "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", "from tensorflow.keras.models import Model, load_model\n", "from tensorflow.keras.layers import (\n", " Input,\n", " LSTM,\n", " Dense,\n", " Embedding,\n", " Bidirectional,\n", " Concatenate,\n", " Dropout,\n", ")\n", "from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n", "from sklearn.model_selection import train_test_split\n", "import matplotlib.pyplot as plt\n", "import re\n", "from rouge_score import rouge_scorer\n", "from nltk.translate.bleu_score import sentence_bleu\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "f9c0af74", "metadata": {}, "outputs": [], "source": [ "\n", "# Load data\n", "with open(\"data_converted.json\", \"r\") as f:\n", " data = json.load(f)\n", "\n", "\n", "# Preprocessing function\n", "def preprocess_text(text):\n", " \"\"\"Melakukan preprocessing teks dasar\"\"\"\n", " text = text.lower()\n", " text = re.sub(r\"\\s+\", \" \", text).strip()\n", " return text\n", "\n", "\n", "# Persiapkan data untuk model prediksi pertanyaan\n", "def prepare_question_prediction_data(data):\n", " \"\"\"Siapkan data untuk model prediksi pertanyaan\"\"\"\n", " contexts = []\n", " tokens_list = []\n", " ner_list = []\n", " srl_list = []\n", " questions = []\n", " q_types = []\n", "\n", " for item in data:\n", " for qa in item[\"qas\"]:\n", " contexts.append(preprocess_text(item[\"context\"]))\n", " tokens_list.append(item[\"tokens\"])\n", " ner_list.append(item[\"ner\"])\n", " srl_list.append(item[\"srl\"])\n", " questions.append(preprocess_text(qa[\"question\"]))\n", " q_types.append(qa[\"type\"])\n", " # Tidak mengambil jawaban (answer) sebagai input\n", "\n", " return contexts, tokens_list, ner_list, srl_list, questions, q_types\n", "\n", "\n", "# Siapkan data\n", "contexts, tokens_list, ner_list, srl_list, questions, q_types = (\n", " prepare_question_prediction_data(data)\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "id": "952f71da", "metadata": {}, "outputs": [], "source": [ "\n", "# Tokenizer untuk teks (context, question)\n", "max_vocab_size = 10000\n", "tokenizer = Tokenizer(num_words=max_vocab_size, oov_token=\"\")\n", "all_texts = contexts + questions + [\" \".join(item) for item in tokens_list]\n", "tokenizer.fit_on_texts(all_texts)\n", "vocab_size = len(tokenizer.word_index) + 1\n", "\n", "# Encoding untuk NER\n", "ner_tokenizer = Tokenizer(oov_token=\"\")\n", "ner_tokenizer.fit_on_texts([\" \".join(ner) for ner in ner_list])\n", "ner_vocab_size = len(ner_tokenizer.word_index) + 1\n", "\n", "# Encoding untuk SRL\n", "srl_tokenizer = Tokenizer(oov_token=\"\")\n", "srl_tokenizer.fit_on_texts([\" \".join(srl) for srl in srl_list])\n", "srl_vocab_size = len(srl_tokenizer.word_index) + 1\n", "\n", "# Encoding untuk tipe pertanyaan\n", "q_type_tokenizer = Tokenizer()\n", "q_type_tokenizer.fit_on_texts(q_types)\n", "q_type_vocab_size = len(q_type_tokenizer.word_index) + 1\n", "\n", "\n", "# Konversi token, ner, srl ke sequences\n", "def tokens_to_sequences(tokens, ner, srl):\n", " \"\"\"Konversi token, ner, dan srl ke sequences\"\"\"\n", " token_seqs = [tokenizer.texts_to_sequences([\" \".join(t)])[0] for t in tokens]\n", " ner_seqs = [ner_tokenizer.texts_to_sequences([\" \".join(n)])[0] for n in ner]\n", " srl_seqs = [srl_tokenizer.texts_to_sequences([\" \".join(s)])[0] for s in srl]\n", " return token_seqs, ner_seqs, srl_seqs\n", "\n", "\n", "# Sequences\n", "context_seqs = tokenizer.texts_to_sequences(contexts)\n", "question_seqs = tokenizer.texts_to_sequences(questions)\n", "token_seqs, ner_seqs, srl_seqs = tokens_to_sequences(tokens_list, ner_list, srl_list)\n", "\n", "# Menentukan panjang maksimum untuk padding\n", "max_context_len = max([len(seq) for seq in context_seqs])\n", "max_question_len = max([len(seq) for seq in question_seqs])\n", "max_token_len = max([len(seq) for seq in token_seqs])\n", "\n", "\n", "# Pad sequences untuk memastikan semua input sama panjang\n", "def pad_all_sequences(context_seqs, token_seqs, ner_seqs, srl_seqs, question_seqs):\n", " \"\"\"Padding semua sequences\"\"\"\n", " context_padded = pad_sequences(context_seqs, maxlen=max_context_len, padding=\"post\")\n", " token_padded = pad_sequences(token_seqs, maxlen=max_token_len, padding=\"post\")\n", " ner_padded = pad_sequences(ner_seqs, maxlen=max_token_len, padding=\"post\")\n", " srl_padded = pad_sequences(srl_seqs, maxlen=max_token_len, padding=\"post\")\n", " question_padded = pad_sequences(\n", " question_seqs, maxlen=max_question_len, padding=\"post\"\n", " )\n", " return (\n", " context_padded,\n", " token_padded,\n", " ner_padded,\n", " srl_padded,\n", " question_padded,\n", " )\n", "\n", "\n", "# Encode tipe pertanyaan\n", "q_type_indices = []\n", "for q_type in q_types:\n", " q_type_idx = q_type_tokenizer.word_index.get(q_type, 0)\n", " q_type_indices.append(q_type_idx)\n", "\n", "# Konversi ke numpy array\n", "q_type_indices = np.array(q_type_indices)\n", "\n", "# One-hot encode tipe pertanyaan\n", "q_type_categorical = tf.keras.utils.to_categorical(\n", " q_type_indices, num_classes=q_type_vocab_size\n", ")\n", "\n", "# Pad sequences\n", "context_padded, token_padded, ner_padded, srl_padded, question_padded = (\n", " pad_all_sequences(context_seqs, token_seqs, ner_seqs, srl_seqs, question_seqs)\n", ")\n", "\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "37ffc0e5", "metadata": {}, "outputs": [], "source": [ "# Split data menjadi train dan test sets\n", "indices = list(range(len(context_padded)))\n", "train_indices, test_indices = train_test_split(indices, test_size=0.2, random_state=42)\n", "\n", "\n", "def get_subset(data, indices):\n", " return np.array([data[i] for i in indices])\n", "\n", "\n", "# Train data\n", "train_context = get_subset(context_padded, train_indices)\n", "train_token = get_subset(token_padded, train_indices)\n", "train_ner = get_subset(ner_padded, train_indices)\n", "train_srl = get_subset(srl_padded, train_indices)\n", "train_q_type = get_subset(q_type_categorical, train_indices)\n", "train_question = get_subset(question_padded, train_indices)\n", "\n", "# Test data\n", "test_context = get_subset(context_padded, test_indices)\n", "test_token = get_subset(token_padded, test_indices)\n", "test_ner = get_subset(ner_padded, test_indices)\n", "test_srl = get_subset(srl_padded, test_indices)\n", "test_q_type = get_subset(q_type_categorical, test_indices)\n", "test_question = get_subset(question_padded, test_indices)" ] }, { "cell_type": "code", "execution_count": 5, "id": "df580682", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2025-05-14 22:59:34.337587: E external/local_xla/xla/stream_executor/cuda/cuda_platform.cc:51] failed call to cuInit: INTERNAL: CUDA error: Failed call to cuInit: UNKNOWN ERROR (303)\n" ] }, { "data": { "text/html": [ "
Model: \"functional\"\n",
       "
\n" ], "text/plain": [ "\u001b[1mModel: \"functional\"\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃ Layer (type)         Output Shape          Param #  Connected to      ┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ context_input       │ (None, 31)        │          0 │ -                 │\n",
       "│ (InputLayer)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ token_input         │ (None, 31)        │          0 │ -                 │\n",
       "│ (InputLayer)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ ner_input           │ (None, 31)        │          0 │ -                 │\n",
       "│ (InputLayer)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ srl_input           │ (None, 31)        │          0 │ -                 │\n",
       "│ (InputLayer)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ text_embedding      │ (None, 31, 100)   │    146,000 │ context_input[0]… │\n",
       "│ (Embedding)         │                   │            │ token_input[0][0] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ ner_embedding       │ (None, 31, 50)    │      1,550 │ ner_input[0][0]   │\n",
       "│ (Embedding)         │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ srl_embedding       │ (None, 31, 50)    │      1,150 │ srl_input[0][0]   │\n",
       "│ (Embedding)         │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ bidirectional       │ (None, 31, 256)   │    234,496 │ text_embedding[0… │\n",
       "│ (Bidirectional)     │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ token_features      │ (None, 31, 200)   │          0 │ text_embedding[1… │\n",
       "│ (Concatenate)       │                   │            │ ner_embedding[0]… │\n",
       "│                     │                   │            │ srl_embedding[0]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ context_attention   │ (None, 31, 256)   │          0 │ bidirectional[0]… │\n",
       "│ (Attention)         │                   │            │ bidirectional[0]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ bidirectional_1     │ (None, 31, 256)   │    336,896 │ token_features[0… │\n",
       "│ (Bidirectional)     │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ context_att_pool    │ (None, 256)       │          0 │ context_attentio… │\n",
       "│ (GlobalMaxPooling1… │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ token_pool          │ (None, 256)       │          0 │ bidirectional_1[ │\n",
       "│ (GlobalMaxPooling1… │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ q_type_input        │ (None, 5)         │          0 │ -                 │\n",
       "│ (InputLayer)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ all_features        │ (None, 517)       │          0 │ context_att_pool… │\n",
       "│ (Concatenate)       │                   │            │ token_pool[0][0], │\n",
       "│                     │                   │            │ q_type_input[0][ │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_1 (Dense)     │ (None, 512)       │    265,216 │ all_features[0][ │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout (Dropout)   │ (None, 512)       │          0 │ dense_1[0][0]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_2 (Dense)     │ (None, 256)       │    131,328 │ dropout[0][0]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout_1 (Dropout) │ (None, 256)       │          0 │ dense_2[0][0]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ decoder_input       │ (None, 256)       │     65,792 │ dropout_1[0][0]   │\n",
       "│ (Dense)             │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ repeat_vector       │ (None, 12, 256)   │          0 │ decoder_input[0]… │\n",
       "│ (RepeatVector)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ decoder_lstm (LSTM) │ (None, 12, 256)   │    525,312 │ repeat_vector[0]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ time_distributed    │ (None, 12, 1460)  │    375,220 │ decoder_lstm[0][ │\n",
       "│ (TimeDistributed)   │                   │            │                   │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
       "
\n" ], "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┃\u001b[1m \u001b[0m\u001b[1mConnected to \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n", "│ context_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ token_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ ner_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ srl_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ text_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m146,000\u001b[0m │ context_input[\u001b[38;5;34m0\u001b[0m]… │\n", "│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ token_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ ner_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,550\u001b[0m │ ner_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ srl_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,150\u001b[0m │ srl_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ bidirectional │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m234,496\u001b[0m │ text_embedding[\u001b[38;5;34m0\u001b[0m… │\n", "│ (\u001b[38;5;33mBidirectional\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ token_features │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m200\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ text_embedding[\u001b[38;5;34m1\u001b[0m… │\n", "│ (\u001b[38;5;33mConcatenate\u001b[0m) │ │ │ ner_embedding[\u001b[38;5;34m0\u001b[0m]… │\n", "│ │ │ │ srl_embedding[\u001b[38;5;34m0\u001b[0m]… │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ context_attention │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ bidirectional[\u001b[38;5;34m0\u001b[0m]… │\n", "│ (\u001b[38;5;33mAttention\u001b[0m) │ │ │ bidirectional[\u001b[38;5;34m0\u001b[0m]… │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ bidirectional_1 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m31\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m336,896\u001b[0m │ token_features[\u001b[38;5;34m0\u001b[0m… │\n", "│ (\u001b[38;5;33mBidirectional\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ context_att_pool │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ context_attentio… │\n", "│ (\u001b[38;5;33mGlobalMaxPooling1…\u001b[0m │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ token_pool │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ bidirectional_1[\u001b[38;5;34m…\u001b[0m │\n", "│ (\u001b[38;5;33mGlobalMaxPooling1…\u001b[0m │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ q_type_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ all_features │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m517\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ context_att_pool… │\n", "│ (\u001b[38;5;33mConcatenate\u001b[0m) │ │ │ token_pool[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m], │\n", "│ │ │ │ q_type_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m265,216\u001b[0m │ all_features[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ dense_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m131,328\u001b[0m │ dropout[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ dense_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ decoder_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m65,792\u001b[0m │ dropout_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", "│ (\u001b[38;5;33mDense\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ repeat_vector │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ decoder_input[\u001b[38;5;34m0\u001b[0m]… │\n", "│ (\u001b[38;5;33mRepeatVector\u001b[0m) │ │ │ │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ decoder_lstm (\u001b[38;5;33mLSTM\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │ repeat_vector[\u001b[38;5;34m0\u001b[0m]… │\n", "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", "│ time_distributed │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m1460\u001b[0m) │ \u001b[38;5;34m375,220\u001b[0m │ decoder_lstm[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", "│ (\u001b[38;5;33mTimeDistributed\u001b[0m) │ │ │ │\n", "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Total params: 2,082,960 (7.95 MB)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m2,082,960\u001b[0m (7.95 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Trainable params: 2,082,960 (7.95 MB)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m2,082,960\u001b[0m (7.95 MB)\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
 Non-trainable params: 0 (0.00 B)\n",
       "
\n" ], "text/plain": [ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "embedding_dim = 100\n", "lstm_units = 128\n", "ner_embedding_dim = 50\n", "srl_embedding_dim = 50\n", "dropout_rate = 0.3\n", "\n", "\n", "# Function untuk membuat model prediksi pertanyaan\n", "def create_question_prediction_model():\n", " # Input layers\n", " context_input = Input(shape=(max_context_len,), name=\"context_input\")\n", " token_input = Input(shape=(max_token_len,), name=\"token_input\")\n", " ner_input = Input(shape=(max_token_len,), name=\"ner_input\")\n", " srl_input = Input(shape=(max_token_len,), name=\"srl_input\")\n", " q_type_input = Input(shape=(q_type_vocab_size,), name=\"q_type_input\")\n", "\n", " # Shared embedding layer for text\n", " text_embedding = Embedding(vocab_size, embedding_dim, name=\"text_embedding\")\n", "\n", " # Embedding untuk NER dan SRL\n", " ner_embedding = Embedding(ner_vocab_size, ner_embedding_dim, name=\"ner_embedding\")(\n", " ner_input\n", " )\n", " srl_embedding = Embedding(srl_vocab_size, srl_embedding_dim, name=\"srl_embedding\")(\n", " srl_input\n", " )\n", "\n", " # Apply embeddings\n", " context_embed = text_embedding(context_input)\n", " token_embed = text_embedding(token_input)\n", "\n", " # Bi-directional LSTM untuk context dan token-level features\n", " context_lstm = Bidirectional(\n", " LSTM(lstm_units, return_sequences=True, name=\"context_lstm\")\n", " )(context_embed)\n", "\n", " # Concat token features (tokens, NER, SRL)\n", " token_features = Concatenate(name=\"token_features\")(\n", " [token_embed, ner_embedding, srl_embedding]\n", " )\n", " token_lstm = Bidirectional(\n", " LSTM(lstm_units, return_sequences=True, name=\"token_lstm\")\n", " )(token_features)\n", "\n", " # Apply attention to context LSTM\n", " context_attention = tf.keras.layers.Attention(name=\"context_attention\")(\n", " [context_lstm, context_lstm]\n", " )\n", "\n", " # Pool attention outputs\n", " context_att_pool = tf.keras.layers.GlobalMaxPooling1D(name=\"context_att_pool\")(\n", " context_attention\n", " )\n", " token_pool = tf.keras.layers.GlobalMaxPooling1D(name=\"token_pool\")(token_lstm)\n", "\n", " # Concat all features (tidak ada answer feature)\n", " all_features = Concatenate(name=\"all_features\")(\n", " [context_att_pool, token_pool, q_type_input]\n", " )\n", "\n", " # Dense layers with expanded capacity for sequence generation\n", " x = Dense(512, activation=\"relu\", name=\"dense_1\")(all_features)\n", " x = Dropout(dropout_rate)(x)\n", " x = Dense(256, activation=\"relu\", name=\"dense_2\")(x)\n", " x = Dropout(dropout_rate)(x)\n", "\n", " # Reshape untuk sequence decoder\n", " decoder_dense = Dense(vocab_size, activation=\"softmax\", name=\"decoder_dense\")\n", "\n", " # Many-to-many architecture for sequence generation\n", " # Decoder LSTM\n", " decoder_lstm = LSTM(lstm_units * 2, return_sequences=True, name=\"decoder_lstm\")\n", "\n", " # Reshape untuk input ke decoder\n", " decoder_input = Dense(lstm_units * 2, activation=\"relu\", name=\"decoder_input\")(x)\n", "\n", " # Decoder sequence with teacher forcing\n", " # Expand dimensionality to match expected sequence length\n", " repeated_vector = tf.keras.layers.RepeatVector(max_question_len)(decoder_input)\n", "\n", " # Process through decoder LSTM\n", " decoder_outputs = decoder_lstm(repeated_vector)\n", "\n", " # Apply dense layer to each timestep\n", " question_output_seq = tf.keras.layers.TimeDistributed(decoder_dense)(\n", " decoder_outputs\n", " )\n", "\n", " # Create model\n", " model = Model(\n", " inputs=[\n", " context_input,\n", " token_input,\n", " ner_input,\n", " srl_input,\n", " q_type_input,\n", " ],\n", " outputs=question_output_seq,\n", " )\n", "\n", " # Compile model with categorical crossentropy for sequence prediction\n", " model.compile(\n", " optimizer=\"adam\", loss=\"sparse_categorical_crossentropy\", metrics=[\"accuracy\"]\n", " )\n", "\n", " return model\n", "\n", "\n", "# Buat model\n", "model = create_question_prediction_model()\n", "model.summary()\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "6ba404db", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/50\n", "\u001b[1m 1/127\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m9:29\u001b[0m 5s/step - accuracy: 0.0000e+00 - loss: 7.2794" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2025-05-14 22:59:38.997189: E tensorflow/core/util/util.cc:131] oneDNN supports DT_INT32 only on platforms with AVX-512. Falling back to the default Eigen-based implementation if present.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.5656 - loss: 3.8053\n", "Epoch 1: val_accuracy improved from -inf to 0.57087, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 37ms/step - accuracy: 0.5658 - loss: 3.7953 - val_accuracy: 0.5709 - val_loss: 2.6996\n", "Epoch 2/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.5855 - loss: 2.5936\n", "Epoch 2: val_accuracy improved from 0.57087 to 0.61122, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 32ms/step - accuracy: 0.5857 - loss: 2.5922 - val_accuracy: 0.6112 - val_loss: 2.5294\n", "Epoch 3/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.6186 - loss: 2.3447\n", "Epoch 3: val_accuracy improved from 0.61122 to 0.62106, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 32ms/step - accuracy: 0.6187 - loss: 2.3432 - val_accuracy: 0.6211 - val_loss: 2.3282\n", "Epoch 4/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6334 - loss: 2.1035\n", "Epoch 4: val_accuracy did not improve from 0.62106\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 29ms/step - accuracy: 0.6335 - loss: 2.1030 - val_accuracy: 0.6201 - val_loss: 2.2961\n", "Epoch 5/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.6481 - loss: 1.9185\n", "Epoch 5: val_accuracy improved from 0.62106 to 0.62139, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 28ms/step - accuracy: 0.6480 - loss: 1.9196 - val_accuracy: 0.6214 - val_loss: 2.1985\n", "Epoch 6/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6440 - loss: 1.9085\n", "Epoch 6: val_accuracy improved from 0.62139 to 0.62533, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.6440 - loss: 1.9085 - val_accuracy: 0.6253 - val_loss: 2.1628\n", "Epoch 7/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.6489 - loss: 1.8557\n", "Epoch 7: val_accuracy improved from 0.62533 to 0.62697, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 28ms/step - accuracy: 0.6489 - loss: 1.8555 - val_accuracy: 0.6270 - val_loss: 2.1144\n", "Epoch 8/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 26ms/step - accuracy: 0.6594 - loss: 1.7365\n", "Epoch 8: val_accuracy improved from 0.62697 to 0.63681, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 29ms/step - accuracy: 0.6594 - loss: 1.7369 - val_accuracy: 0.6368 - val_loss: 2.0357\n", "Epoch 9/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - accuracy: 0.6580 - loss: 1.7307\n", "Epoch 9: val_accuracy improved from 0.63681 to 0.64337, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.6580 - loss: 1.7307 - val_accuracy: 0.6434 - val_loss: 2.0130\n", "Epoch 10/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.6721 - loss: 1.5986\n", "Epoch 10: val_accuracy improved from 0.64337 to 0.64501, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 28ms/step - accuracy: 0.6721 - loss: 1.5991 - val_accuracy: 0.6450 - val_loss: 1.9954\n", "Epoch 11/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - accuracy: 0.6779 - loss: 1.5699\n", "Epoch 11: val_accuracy did not improve from 0.64501\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 26ms/step - accuracy: 0.6776 - loss: 1.5714 - val_accuracy: 0.6424 - val_loss: 1.9498\n", "Epoch 12/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 23ms/step - accuracy: 0.6810 - loss: 1.5323\n", "Epoch 12: val_accuracy improved from 0.64501 to 0.64993, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 26ms/step - accuracy: 0.6808 - loss: 1.5335 - val_accuracy: 0.6499 - val_loss: 1.9735\n", "Epoch 13/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - accuracy: 0.6834 - loss: 1.5085\n", "Epoch 13: val_accuracy improved from 0.64993 to 0.65354, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.6833 - loss: 1.5089 - val_accuracy: 0.6535 - val_loss: 1.9068\n", "Epoch 14/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - accuracy: 0.6798 - loss: 1.4922\n", "Epoch 14: val_accuracy did not improve from 0.65354\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 26ms/step - accuracy: 0.6799 - loss: 1.4921 - val_accuracy: 0.6496 - val_loss: 1.8996\n", "Epoch 15/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 26ms/step - accuracy: 0.6862 - loss: 1.4473\n", "Epoch 15: val_accuracy improved from 0.65354 to 0.65453, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.6862 - loss: 1.4474 - val_accuracy: 0.6545 - val_loss: 1.8677\n", "Epoch 16/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.6848 - loss: 1.4202\n", "Epoch 16: val_accuracy did not improve from 0.65453\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6848 - loss: 1.4203 - val_accuracy: 0.6539 - val_loss: 1.8963\n", "Epoch 17/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6879 - loss: 1.3888\n", "Epoch 17: val_accuracy improved from 0.65453 to 0.65846, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6879 - loss: 1.3888 - val_accuracy: 0.6585 - val_loss: 1.8342\n", "Epoch 18/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 29ms/step - accuracy: 0.6904 - loss: 1.3864\n", "Epoch 18: val_accuracy did not improve from 0.65846\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6905 - loss: 1.3860 - val_accuracy: 0.6562 - val_loss: 1.8491\n", "Epoch 19/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6932 - loss: 1.3283\n", "Epoch 19: val_accuracy improved from 0.65846 to 0.66273, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6932 - loss: 1.3284 - val_accuracy: 0.6627 - val_loss: 1.8534\n", "Epoch 20/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6984 - loss: 1.3098\n", "Epoch 20: val_accuracy improved from 0.66273 to 0.66339, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6984 - loss: 1.3101 - val_accuracy: 0.6634 - val_loss: 1.8651\n", "Epoch 21/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.6995 - loss: 1.2942\n", "Epoch 21: val_accuracy improved from 0.66339 to 0.66667, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.6995 - loss: 1.2941 - val_accuracy: 0.6667 - val_loss: 1.8329\n", "Epoch 22/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.7113 - loss: 1.2285\n", "Epoch 22: val_accuracy improved from 0.66667 to 0.66995, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.7112 - loss: 1.2287 - val_accuracy: 0.6699 - val_loss: 1.8237\n", "Epoch 23/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.7184 - loss: 1.1800\n", "Epoch 23: val_accuracy did not improve from 0.66995\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.7183 - loss: 1.1805 - val_accuracy: 0.6690 - val_loss: 1.8186\n", "Epoch 24/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.7123 - loss: 1.1906\n", "Epoch 24: val_accuracy did not improve from 0.66995\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.7123 - loss: 1.1908 - val_accuracy: 0.6690 - val_loss: 1.8289\n", "Epoch 25/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.7074 - loss: 1.1998\n", "Epoch 25: val_accuracy improved from 0.66995 to 0.67060, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.7074 - loss: 1.1997 - val_accuracy: 0.6706 - val_loss: 1.8420\n", "Epoch 26/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.7191 - loss: 1.1513\n", "Epoch 26: val_accuracy did not improve from 0.67060\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.7190 - loss: 1.1517 - val_accuracy: 0.6604 - val_loss: 1.8648\n", "Epoch 27/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 29ms/step - accuracy: 0.7175 - loss: 1.1522\n", "Epoch 27: val_accuracy improved from 0.67060 to 0.67848, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 33ms/step - accuracy: 0.7174 - loss: 1.1526 - val_accuracy: 0.6785 - val_loss: 1.8066\n", "Epoch 28/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.7166 - loss: 1.1271\n", "Epoch 28: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.7166 - loss: 1.1273 - val_accuracy: 0.6706 - val_loss: 1.8183\n", "Epoch 29/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.7264 - loss: 1.1001\n", "Epoch 29: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.7264 - loss: 1.1002 - val_accuracy: 0.6749 - val_loss: 1.8125\n", "Epoch 30/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - accuracy: 0.7377 - loss: 1.0295\n", "Epoch 30: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.7373 - loss: 1.0315 - val_accuracy: 0.6752 - val_loss: 1.8446\n", "Epoch 31/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 26ms/step - accuracy: 0.7296 - loss: 1.0660\n", "Epoch 31: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 28ms/step - accuracy: 0.7296 - loss: 1.0662 - val_accuracy: 0.6781 - val_loss: 1.8458\n", "Epoch 32/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 26ms/step - accuracy: 0.7300 - loss: 1.0442\n", "Epoch 32: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 28ms/step - accuracy: 0.7300 - loss: 1.0444 - val_accuracy: 0.6781 - val_loss: 1.8412\n", "Epoch 33/50\n", "\u001b[1m125/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - accuracy: 0.7419 - loss: 1.0121\n", "Epoch 33: val_accuracy did not improve from 0.67848\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 27ms/step - accuracy: 0.7417 - loss: 1.0129 - val_accuracy: 0.6736 - val_loss: 1.8169\n", "Epoch 34/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.7399 - loss: 0.9723\n", "Epoch 34: val_accuracy improved from 0.67848 to 0.68110, saving model to question_prediction_model.h5\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 32ms/step - accuracy: 0.7398 - loss: 0.9731 - val_accuracy: 0.6811 - val_loss: 1.8420\n", "Epoch 35/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - accuracy: 0.7402 - loss: 0.9793\n", "Epoch 35: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.7402 - loss: 0.9797 - val_accuracy: 0.6686 - val_loss: 1.8767\n", "Epoch 36/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 29ms/step - accuracy: 0.7460 - loss: 0.9750\n", "Epoch 36: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 32ms/step - accuracy: 0.7460 - loss: 0.9751 - val_accuracy: 0.6739 - val_loss: 1.8811\n", "Epoch 37/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.7546 - loss: 0.9229\n", "Epoch 37: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.7545 - loss: 0.9232 - val_accuracy: 0.6745 - val_loss: 1.8617\n", "Epoch 38/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.7424 - loss: 0.9487\n", "Epoch 38: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 31ms/step - accuracy: 0.7424 - loss: 0.9487 - val_accuracy: 0.6804 - val_loss: 1.8202\n", "Epoch 39/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 28ms/step - accuracy: 0.7484 - loss: 0.9280\n", "Epoch 39: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 30ms/step - accuracy: 0.7485 - loss: 0.9281 - val_accuracy: 0.6736 - val_loss: 1.8549\n", "Epoch 40/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 31ms/step - accuracy: 0.7468 - loss: 0.9305\n", "Epoch 40: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 33ms/step - accuracy: 0.7468 - loss: 0.9303 - val_accuracy: 0.6781 - val_loss: 1.8830\n", "Epoch 41/50\n", "\u001b[1m126/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 31ms/step - accuracy: 0.7534 - loss: 0.9027\n", "Epoch 41: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 34ms/step - accuracy: 0.7534 - loss: 0.9030 - val_accuracy: 0.6749 - val_loss: 1.8625\n", "Epoch 42/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 31ms/step - accuracy: 0.7543 - loss: 0.8655\n", "Epoch 42: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 34ms/step - accuracy: 0.7542 - loss: 0.8658 - val_accuracy: 0.6722 - val_loss: 1.8615\n", "Epoch 43/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 30ms/step - accuracy: 0.7573 - loss: 0.8701\n", "Epoch 43: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 33ms/step - accuracy: 0.7572 - loss: 0.8703 - val_accuracy: 0.6732 - val_loss: 1.8650\n", "Epoch 44/50\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 30ms/step - accuracy: 0.7495 - loss: 0.8897\n", "Epoch 44: val_accuracy did not improve from 0.68110\n", "\u001b[1m127/127\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 32ms/step - accuracy: 0.7495 - loss: 0.8896 - val_accuracy: 0.6808 - val_loss: 1.8494\n", "Epoch 44: early stopping\n" ] } ], "source": [ "checkpoint = ModelCheckpoint(\n", " \"question_prediction_model.h5\",\n", " monitor=\"val_accuracy\",\n", " save_best_only=True,\n", " verbose=1,\n", ")\n", "\n", "early_stop = EarlyStopping(monitor=\"val_accuracy\", patience=10, verbose=1)\n", "\n", "# Reshaping question data for sequence-to-sequence training\n", "# We need to reshape to (samples, max_question_len, 1) for sparse categorical crossentropy\n", "train_question_target = np.expand_dims(train_question, -1)\n", "test_question_target = np.expand_dims(test_question, -1)\n", "\n", "# Training parameters\n", "batch_size = 8\n", "epochs = 50\n", "\n", "# Train model\n", "history = model.fit(\n", " [train_context, train_token, train_ner, train_srl, train_q_type],\n", " train_question_target,\n", " batch_size=batch_size,\n", " epochs=epochs,\n", " validation_data=(\n", " [test_context, test_token, test_ner, test_srl, test_q_type],\n", " test_question_target,\n", " ),\n", " callbacks=[checkpoint, early_stop],\n", ")" ] }, { "cell_type": "code", "execution_count": 7, "id": "184209bc", "metadata": {}, "outputs": [ { "data": { "image/png": "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DtZg2scE0zEmmLbRQW65iqDhFd12220UFBTw2GOPYbPZ6NGjBwsXLqyb/DwnJwez2Vy3/4kTJ7jvvvuw2WyEhYWRmprKmjVr6NSpU73zvv/++zidTn7961+f854Wi4X333+fxx9/HLvdTlJSEhMnTqw3PM9QdfNJaZJzEREREREREXeWGBHAg4Pb8ODgNj/rPC0CfOnfJpL+bSLrttlrajlQUMHx8iqKTlZRfLKKoooqTlRUUXSy+nvPq6isdpBXaiev1M43+8723DKZIDE8oF5Y1cEaTFJkIL7e5gtUdPmZnE7nBUY3yg8pLS0lNDSUkpISQkJCLu3J3/s1ZC6A4c9A2u8u7blFRETkkrqsbQIPo+9CRETEWKWV1WTll7PXVkZmXhmZtjL25pVRWF513v1/3TeBaSO7Xfo6GtgmMLynlFyAl0U9pURERERERESkwUL8fOiVGEavxPpTExWW29mbV/a9sKqc9tZgw2pFoZSb+vV7UFtjdBUiIiIiIiIi0gREBlmIDLLUGxrodDqprjV28JxCKXflpUsjIiIiIiIiIpeHyWTC1/vcCdgbk3GzWYmIiIiIiIiISLOlUEpERERERERERBqdQikREREREREREWl0CqVERERERERERKTRKZQSEREREREREZFGp1BKREREREREREQanUIpERERERERERFpdAqlRERERERERESk0SmUEhERERERERGRRqdQSkREREREREREGp230QV4KqfTCUBpaanRpYiIiIiBzrQFzrQNmjO1j0RERISf0D5SKHWRysrKAEhISDC6FBEREXEDZWVlhIaGGl2GodQ+EhERke/6sfaRyalf610Uh8PB0aNHCQ4OxmQyXdJzl5aWkpCQwOHDhwkJCbmk55bLR9fN8+iaeSZdN8/T1K+Z0+mkrKyMuLg4zObmPTOC2kfyXbpmnknXzfPomnmmpn7dGto+Uk+pi2Q2m2nZsuVlfY+QkJAm+cPZ1Om6eR5dM8+k6+Z5mvI1a+49pM5Q+0jOR9fMM+m6eR5dM8/UlK9bQ9pHzfvXeSIiIiIiIiIiYgiFUiIiIiIiIiIi0ugUSrkhi8XC1KlTsVgsRpciP4Gum+fRNfNMum6eR9dMLgX9HHkeXTPPpOvmeXTNPJOum4smOhcRERERERERkUannlIiIiIiIiIiItLoFEqJiIiIiIiIiEijUyglIiIiIiIiIiKNTqGUG5oxYwatW7fGz8+PtLQ0NmzYYHRJctrKlSu58cYbiYuLw2Qy8emnn9Z73el08thjjxEbG4u/vz9Dhw5l3759htUrMG3aNPr06UNwcDDR0dGMGDGCzMzMevtUVlYyduxYIiIiCAoKYtSoUeTl5RlWs8DLL79Mt27dCAkJISQkhPT0dL788su613XN3N/TTz+NyWTikUceqdum6yY/h9pH7kvtI8+j9pFnUvvI86l9dC6FUm7mgw8+YNKkSUydOpXNmzfTvXt3hg0bRn5+vtGlCVBRUUH37t2ZMWPGeV9/5plnePHFF5k5cybr168nMDCQYcOGUVlZ2ei1isuKFSsYO3Ys69atY8mSJVRXV3PttddSUVFRt8/EiRP5/PPP+eijj1ixYgVHjx5l5MiRhtbd3LVs2ZKnn36aTZs2sXHjRq6++mpuuukmdu3aBbpmbu/bb7/llVdeoVu3bvW267rJxVL7yL2pfeR51D7yTGofeTa1jy7AKW6lb9++zrFjx9Y9r62tdcbFxTmnTZtmaF1yLsA5d+7cuucOh8MZExPjfPbZZ+u2FRcXOy0Wi/O9994zqEr5vvz8fCfgXLFihdN5+hr5+Pg4P/roo7p99uzZ4wSca9euNbBS+b6wsDDna6+9pmvm5srKypzt2rVzLlmyxDlo0CDnhAkTnE79WZOfSe0jz6H2kWdS+8hzqX3kGdQ+ujD1lHIjVVVVbNq0iaFDh9ZtM5vNDB06lLVr1xpam/y47OxsbDZbvesXGhpKWlqarp8bKSkpASA8PByATZs2UV1dXe+6dezYkcTERF03N1FbW8v7779PRUUF6enpumZubuzYsdxwww31rg/6syY/g9pHnk3tI8+g9pHnUfvIs6h9dGHeRhcgZxUWFlJbW4vVaq233Wq1kpGRYVhd0jA2mw1OX6/vslqtda+JsRwOB4888ggDBgygS5cucPq6+fr60qJFi3r76roZb8eOHaSnp1NZWUlQUBBz586lU6dObN26VdfMTb3//vts3ryZb7/99pzX9GdNLpbaR55N7SP3p/aRZ1H7yPOoffTDFEqJSLMxduxYdu7cyapVq4wuRRqgQ4cObN26lZKSEubMmcOYMWNYsWKF0WXJBRw+fJgJEyawZMkS/Pz8jC5HREQaSO0jz6L2kWdR++jHafieG4mMjMTLy+ucmfbz8vKIiYkxrC5pmDPXSNfPPY0bN44vvviCr7/+mpYtW9Ztj4mJoaqqiuLi4nr767oZz9fXl7Zt25Kamsq0adPo3r07//znP3XN3NSmTZvIz8+nV69eeHt74+3tzYoVK3jxxRfx9vbGarXquslFUfvIs6l95N7UPvI8ah95FrWPfpxCKTfi6+tLamoqS5curdvmcDhYunQp6enphtYmPy4pKYmYmJh616+0tJT169fr+hnI6XQybtw45s6dy7Jly0hKSqr3empqKj4+PvWuW2ZmJjk5ObpubsbhcGC323XN3NSQIUPYsWMHW7durbv17t2b0aNH1z3WdZOLofaRZ1P7yD2pfdR0qH3k3tQ++nEavudmJk2axJgxY+jduzd9+/Zl+vTpVFRUcPfddxtdmgDl5eVkZWXVPc/Ozmbr1q2Eh4eTmJjII488wt///nfatWtHUlISjz76KHFxcYwYMcLQupuzsWPH8u677/LZZ58RHBxcNzY7NDQUf39/QkNDuffee5k0aRLh4eGEhIQwfvx40tPT6devn9HlN1tTpkxh+PDhJCYmUlZWxrvvvsvy5ctZtGiRrpmbCg4OrpuL5IzAwEAiIiLqtuu6ycVS+8i9qX3kedQ+8kxqH3ketY8awOjl/+Rc//rXv5yJiYlOX19fZ9++fZ3r1q0zuiQ57euvv3YC59zGjBnjdJ5e9vjRRx91Wq1Wp8VicQ4ZMsSZmZlpdNnN2vmuF+B844036vY5deqU86GHHnKGhYU5AwICnDfffLPz2LFjhtbd3N1zzz3OVq1aOX19fZ1RUVHOIUOGOBcvXlz3uq6ZZ/juksdOXTf5mdQ+cl9qH3ketY88k9pHTYPaR/WZnK6/lERERERERERERBqN5pQSEREREREREZFGp1BKREREREREREQanUIpERERERERERFpdAqlRERERERERESk0SmUEhERERERERGRRqdQSkREREREREREGp1CKRERERERERERaXQKpUREREREREREpNEplBIRMYDJZOLTTz81ugwRERERt6C2kUjzpFBKRJqdu+66C5PJdM7tuuuuM7o0ERERkUantpGIGMXb6AJERIxw3XXX8cYbb9TbZrFYDKtHRERExEhqG4mIEdRTSkSaJYvFQkxMTL1bWFgYnO4+/vLLLzN8+HD8/f1JTk5mzpw59Y7fsWMHV199Nf7+/kRERHD//fdTXl5eb59Zs2bRuXNnLBYLsbGxjBs3rt7rhYWF3HzzzQQEBNCuXTvmzZvXCJ9cRERE5FxqG4mIERRKiYicx6OPPsqoUaPYtm0bo0eP5le/+hV79uwBoKKigmHDhhEWFsa3337LRx99xFdffVWvYfXyyy8zduxY7r//fnbs2MG8efNo27Ztvfd44oknuPXWW9m+fTvXX389o0ePpqioqNE/q4iIiMiPUdtIRC4Lp4hIMzNmzBinl5eXMzAwsN7tH//4h9PpdDoB5wMPPFDvmLS0NOeDDz7odDqdzldffdUZFhbmLC8vr3t9/vz5TrPZ7LTZbE6n0+mMi4tz/uUvf7lgDYDzr3/9a93z8vJyJ+D88ssvL/nnFREREfkhahuJiFE0p5SINEtXXXUVL7/8cr1t4eHhdY/T09PrvZaens7WrVsB2LNnD927dycwMLDu9QEDBuBwOMjMzMRkMnH06FGGDBnygzV069at7nFgYCAhISHk5+f/7M8mIiIi8lOpbSQiRlAoJSLNUmBg4Dldxi8Vf3//Bu3n4+NT77nJZMLhcFyWmkRERER+iNpGImIEzSklInIe69atO+d5SkoKACkpKWzbto2Kioq611evXo3ZbKZDhw4EBwfTunVrli5d2uh1i4iIiFwOahuJyOWgnlIi0izZ7XZsNlu9bd7e3kRGRgLw0Ucf0bt3b6644greeecdNmzYwOuvvw7A6NGjmTp1KmPGjOHxxx+noKCA8ePHc8cdd2C1WgF4/PHHeeCBB4iOjmb48OGUlZWxevVqxo8fb8CnFREREflhahuJiBEUSolIs7Rw4UJiY2PrbevQoQMZGRlwevWX999/n4ceeojY2Fjee+89OnXqBEBAQACLFi1iwoQJ9OnTh4CAAEaNGsXzzz9fd64xY8ZQWVnJCy+8wO9//3siIyO55ZZbGvlTioiIiDSM2kYiYgST07XSgYiInGYymZg7dy4jRowwuhQRERERw6ltJCKXi+aUEhERERERERGRRqdQSkREREREREREGp2G74mIiIiIiIiISKNTTykREREREREREWl0CqVERERERERERKTRKZQSEREREREREZFGp1BKREREREREREQanUIpERERERERERFpdAqlRERERERERESk0SmUEhERERERERGRRqdQSkREREREREREGp1CKRERERERERERaXT/H/TvlsPVHrF1AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "\n", "# Plot training history\n", "plt.figure(figsize=(12, 4))\n", "plt.subplot(1, 2, 1)\n", "plt.plot(history.history[\"accuracy\"])\n", "plt.plot(history.history[\"val_accuracy\"])\n", "plt.title(\"Model Accuracy\")\n", "plt.ylabel(\"Accuracy\")\n", "plt.xlabel(\"Epoch\")\n", "plt.legend([\"Train\", \"Validation\"], loc=\"upper left\")\n", "\n", "plt.subplot(1, 2, 2)\n", "plt.plot(history.history[\"loss\"])\n", "plt.plot(history.history[\"val_loss\"])\n", "plt.title(\"Model Loss\")\n", "plt.ylabel(\"Loss\")\n", "plt.xlabel(\"Epoch\")\n", "plt.legend([\"Train\", \"Validation\"], loc=\"upper left\")\n", "plt.tight_layout()\n", "plt.savefig(\"question_prediction_training_history.png\")\n", "plt.show()\n", "\n", "# Simpan model dan tokenizer\n", "model.save(\"question_prediction_model_final.h5\")\n", "\n", "# Simpan tokenizer\n", "tokenizer_data = {\n", " \"word_tokenizer\": tokenizer.to_json(),\n", " \"ner_tokenizer\": ner_tokenizer.to_json(),\n", " \"srl_tokenizer\": srl_tokenizer.to_json(),\n", " \"q_type_tokenizer\": q_type_tokenizer.to_json(),\n", " \"max_context_len\": max_context_len,\n", " \"max_question_len\": max_question_len,\n", " \"max_token_len\": max_token_len,\n", "}\n", "\n", "with open(\"question_prediction_tokenizers.json\", \"w\") as f:\n", " json.dump(tokenizer_data, f)\n", "\n" ] }, { "cell_type": "code", "execution_count": 11, "id": "71ec455a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "Model Performance Metrics:\n", "Average BLEU Score: 3.06%\n", "Average ROUGE-1 Score: 38.89%\n", "Average ROUGE-2 Score: 13.38%\n", "Average ROUGE-L Score: 38.55%\n" ] } ], "source": [ "\n", "# Fungsi untuk memprediksi pertanyaan\n", "def predict_question(context, tokens, ner, srl, q_type):\n", " context = preprocess_text(context)\n", "\n", " context_seq = tokenizer.texts_to_sequences([context])[0]\n", " token_seq = tokenizer.texts_to_sequences([\" \".join(tokens)])[0]\n", " ner_seq = ner_tokenizer.texts_to_sequences([\" \".join(ner)])[0]\n", " srl_seq = srl_tokenizer.texts_to_sequences([\" \".join(srl)])[0]\n", "\n", " context_padded = pad_sequences(\n", " [context_seq], maxlen=max_context_len, padding=\"post\"\n", " )\n", " token_padded = pad_sequences([token_seq], maxlen=max_token_len, padding=\"post\")\n", " ner_padded = pad_sequences([ner_seq], maxlen=max_token_len, padding=\"post\")\n", " srl_padded = pad_sequences([srl_seq], maxlen=max_token_len, padding=\"post\")\n", "\n", " # Q-type one-hot encoding\n", " q_type_idx = q_type_tokenizer.word_index.get(q_type, 0)\n", " q_type_one_hot = tf.keras.utils.to_categorical(\n", " [q_type_idx], num_classes=q_type_vocab_size\n", " )\n", "\n", " # Predict\n", " pred = model.predict(\n", " [context_padded, token_padded, ner_padded, srl_padded, q_type_one_hot],\n", " verbose=0,\n", " )\n", "\n", " # Convert prediction to words\n", " pred_seq = np.argmax(pred[0], axis=1)\n", "\n", " # Convert indices to words\n", " reverse_word_map = {v: k for k, v in tokenizer.word_index.items()}\n", " pred_words = [reverse_word_map.get(i, \"\") for i in pred_seq if i != 0]\n", "\n", " return \" \".join(pred_words)\n", "\n", "\n", "def evaluate_model_performance(test_data):\n", "\n", " # Initialize ROUGE scorer\n", " scorer = rouge_scorer.RougeScorer([\"rouge1\", \"rouge2\", \"rougeL\"], use_stemmer=True)\n", "\n", " # Lists to store scores\n", " bleu_scores = []\n", " rouge1_scores = []\n", " rouge2_scores = []\n", " rougel_scores = []\n", "\n", " # Iterate through test data\n", " for i in range(len(test_data)):\n", " # Get test sample\n", " sample_context = contexts[test_data[i]]\n", " sample_tokens = tokens_list[test_data[i]]\n", " sample_ner = ner_list[test_data[i]]\n", " sample_srl = srl_list[test_data[i]]\n", " sample_q_type = q_types[test_data[i]]\n", " actual_question = questions[test_data[i]]\n", "\n", " # Predict question\n", " pred_question = predict_question(\n", " sample_context, sample_tokens, sample_ner, sample_srl, sample_q_type\n", " )\n", "\n", " # Tokenize for BLEU score\n", " actual_tokens = actual_question.split()\n", " pred_tokens = pred_question.split()\n", "\n", " # Calculate BLEU score\n", " # Using unigram, bigram, trigram, and 4-gram\n", " # print(\"kaliamt aktual\", actual_tokens)\n", " # print(\"kaliamt prediksi\", pred_tokens)\n", " bleu_score = sentence_bleu([actual_tokens], pred_tokens)\n", " bleu_scores.append(bleu_score)\n", "\n", " try:\n", " rouge_scores = scorer.score(actual_question, pred_question)\n", "\n", " # Extract F1 scores\n", " rouge1_scores.append(rouge_scores[\"rouge1\"].fmeasure)\n", " rouge2_scores.append(rouge_scores[\"rouge2\"].fmeasure)\n", " rougel_scores.append(rouge_scores[\"rougeL\"].fmeasure)\n", " except Exception as e:\n", " print(f\"Error calculating ROUGE score: {e}\")\n", "\n", " # Calculate average scores\n", " results = {\n", " \"avg_bleu_score\": np.mean(bleu_scores),\n", " \"avg_rouge1\": np.mean(rouge1_scores),\n", " \"avg_rouge2\": np.mean(rouge2_scores),\n", " \"avg_rougel\": np.mean(rougel_scores),\n", " }\n", "\n", " return results\n", "\n", "\n", "loaded_model = load_model(\"question_prediction_model_final.h5\")\n", "\n", "with open(\"question_prediction_tokenizers.json\", \"r\") as f:\n", " tokenizer_data = json.load(f)\n", "\n", "# Ambil beberapa sampel dari data test\n", "sample_idx = random.randint(0, len(test_indices) - 1)\n", "sample_context = contexts[test_indices[sample_idx]]\n", "sample_tokens = tokens_list[test_indices[sample_idx]]\n", "sample_ner = ner_list[test_indices[sample_idx]]\n", "sample_srl = srl_list[test_indices[sample_idx]]\n", "sample_q_type = q_types[test_indices[sample_idx]]\n", "\n", "performance_metrics = evaluate_model_performance(test_indices)\n", "\n", "print(\"\\nModel Performance Metrics:\")\n", "print(f\"Average BLEU Score: {performance_metrics['avg_bleu_score'] * 100:.2f}%\")\n", "print(f\"Average ROUGE-1 Score: {performance_metrics['avg_rouge1'] * 100:.2f}%\")\n", "print(f\"Average ROUGE-2 Score: {performance_metrics['avg_rouge2'] * 100:.2f}%\")\n", "print(f\"Average ROUGE-L Score: {performance_metrics['avg_rougel'] * 100:.2f}%\")\n" ] } ], "metadata": { "kernelspec": { "display_name": "myenv", "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.10.16" } }, "nbformat": 4, "nbformat_minor": 5 }