867 lines
129 KiB
Plaintext
867 lines
129 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 232,
|
|
"id": "02cbdb19",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"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": 233,
|
|
"id": "f9c0af74",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"total context 885\n",
|
|
"total question 1547\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Load data\n",
|
|
"with open(\"../dataset/valid_data.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",
|
|
"\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",
|
|
" \n",
|
|
" for qa in item[\"qas\"]:\n",
|
|
" # if qa[\"question\"] == \"\":\n",
|
|
" # continue\n",
|
|
" context = preprocess_text(item[\"context\"])\n",
|
|
" contexts.append(context)\n",
|
|
" token = [preprocess_text(token) for token in item[\"tokens\"]]\n",
|
|
" tokens_list.append(token)\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",
|
|
" print(\"total context \", len(data))\n",
|
|
" print(\"total question \", len(questions))\n",
|
|
" return contexts, tokens_list, ner_list, srl_list, questions, q_types\n",
|
|
"\n",
|
|
"\n",
|
|
"contexts, tokens_list, ner_list, srl_list, questions, q_types = (\n",
|
|
" prepare_question_prediction_data(data)\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 234,
|
|
"id": "952f71da",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Tokenizer untuk teks (context, question)\n",
|
|
"max_vocab_size = 10000\n",
|
|
"tokenizer = Tokenizer(num_words=max_vocab_size, oov_token=\"<OOV>\")\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=\"<OOV>\")\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=\"<OOV>\")\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",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 235,
|
|
"id": "37ffc0e5",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"indices = list(range(len(context_padded)))\n",
|
|
"train_indices, test_indices = train_test_split(indices, test_size=0.1, 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": 236,
|
|
"id": "df580682",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"functional_28\"</span>\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1mModel: \"functional_28\"\u001b[0m\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
|
|
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃<span style=\"font-weight: bold\"> Connected to </span>┃\n",
|
|
"┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
|
|
"│ context_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ token_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ ner_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ srl_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ text_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">223,000</span> │ context_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ token_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ ner_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,700</span> │ ner_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ srl_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,500</span> │ srl_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ bidirectional_56 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">234,496</span> │ text_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ token_features │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">200</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ text_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Concatenate</span>) │ │ │ ner_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
|
|
"│ │ │ │ srl_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ context_attention │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ bidirectional_56… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Attention</span>) │ │ │ bidirectional_56… │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ bidirectional_57 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">38</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">336,896</span> │ token_features[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ context_att_pool │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ context_attentio… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalMaxPooling1…</span> │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ token_pool │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ bidirectional_57… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalMaxPooling1…</span> │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ q_type_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ all_features │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">517</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ context_att_pool… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Concatenate</span>) │ │ │ token_pool[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>], │\n",
|
|
"│ │ │ │ q_type_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">265,216</span> │ all_features[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ dropout_56 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,328</span> │ dropout_56[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ dropout_57 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ decoder_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">65,792</span> │ dropout_57[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ repeat_vector_28 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">15</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ decoder_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">RepeatVector</span>) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ decoder_lstm (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">LSTM</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">15</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │ repeat_vector_28… │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ time_distributed_28 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">15</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2230</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">573,110</span> │ decoder_lstm[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
|
|
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">TimeDistributed</span>) │ │ │ │\n",
|
|
"└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
|
|
"</pre>\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;34m38\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;34m38\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;34m38\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;34m38\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;34m38\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m223,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;34m38\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,700\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;34m38\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,500\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_56 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m38\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;34m38\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;34m38\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ bidirectional_56… │\n",
|
|
"│ (\u001b[38;5;33mAttention\u001b[0m) │ │ │ bidirectional_56… │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ bidirectional_57 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m38\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_57… │\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_56 │ (\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",
|
|
"│ (\u001b[38;5;33mDropout\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_56[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ dropout_57 │ (\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",
|
|
"│ (\u001b[38;5;33mDropout\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_57[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
|
|
"│ (\u001b[38;5;33mDense\u001b[0m) │ │ │ │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ repeat_vector_28 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m15\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;34m15\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │ repeat_vector_28… │\n",
|
|
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
|
|
"│ time_distributed_28 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m15\u001b[0m, \u001b[38;5;34m2230\u001b[0m) │ \u001b[38;5;34m573,110\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": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,358,350</span> (9.00 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m2,358,350\u001b[0m (9.00 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,358,350</span> (9.00 MB)\n",
|
|
"</pre>\n"
|
|
],
|
|
"text/plain": [
|
|
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m2,358,350\u001b[0m (9.00 MB)\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
|
|
"</pre>\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()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6ba404db",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1/70\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 = 70\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=[\n",
|
|
" # checkpoint,\n",
|
|
" early_stop,\n",
|
|
" ],\n",
|
|
")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "184209bc",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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fAgMDOTQoUNs27aNa6+9tlHjFxERETHDhg0bmDhxImFhYVgsFlasWPGz569btw6LxXLOlpGRUeu8RYsW0blzZ1xdXYmNjWXr1q1NfCciIiLSXpneTys+Pp5XXnmFN954g/379zNz5kyKi4uZMWMGAFOnTq016fn/+3//jy+++IKUlBR27NjB73//e44ePVprsvJly5axbt06UlJSWLlyJVdeeSWTJk3iqqsafxZ5ERERkeZWXFxM//79WbRo0UV97sCBA6Snp9dsQUFBNcfee+894uPjmT9/Pjt27KB///6MGzeOrKysJrgDERERae9MHbIHMHnyZE6ePMkjjzxCRkYGAwYMYPXq1TUTnaemptaa++nUqVPcfvvtZGRk4Ovry6BBg/juu+/o1atXzTnp6enEx8eTmZlJaGgoU6dO5eGHHzbl/kREREQa24QJE5gwYcJFfy4oKIgOHTrUeezpp5/m9ttvr/lScPHixXzyySe89tprPPjggw2OWURERORsFsMwDLODaGkKCgrw8fEhPz8fb29vs8MRERGRZtaacgGLxcLy5cuZNGnSec9Zt24dl19+OZGRkZSVldGnTx8effRRRowYAUB5eTnu7u68//77ta4zbdo08vLyWLlyZZ3XLSsro6ysrOZ9QUEB4eHhraLdREREpHFdbP5k+pA9EREREWlaoaGhLF68mA8++IAPPviA8PBwRo8ezY4dOwDIzs6mqqqqpof6j4KDg8+ZZ+psCxcuxMfHp2YLDw9v8nsRERGRtsH0IXsiIiIi0rRiYmKIiYmpeT98+HCSk5N55plneOutt+p93Xnz5hEfH1/z/sceUiIiIiK/RAUpERERkXZo6NChbNy4EYCAgAAcHR3JzMysdU5mZiYhISHnvYbVasVqtTZ5rCIiItL2aMieiIiISDuUkJBAaGgoAC4uLgwaNIi1a9fWHLfZbKxdu5a4uDgToxQREZG2Sj2kRERERFqZoqIikpKSat4fPnyYhIQE/Pz8iIiIYN68eZw4cYI333wTgGeffZaoqCh69+5NaWkpr776Kl999RVffPFFzTXi4+OZNm0agwcPZujQoTz77LMUFxfXrLonIiIi0phUkKrDjwsPFhQUmB2KiIiImODHHKClLka8bds2Lr/88pr3P87jNG3aNJYuXUp6ejqpqak1x8vLy7nvvvs4ceIE7u7u9OvX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nJycHD2T1QzD4J577mH58uV89dVXREVF1To+aNAgnJ2daz2DBw4cIDU1Vc9gtV9qw7okJCQA6Dn8GTabjbKyMj2DrYDyp8an/KlhlD81DeVQtSmHajjlUI2vKfInDdlrRvHx8UybNo3BgwczdOhQnn32WYqLi5kxY4bZobUK999/PxMnTiQyMpK0tDTmz5+Po6MjN910k9mhtVhFRUW1KvyHDx8mISEBPz8/IiIimDt3Lo899hjdu3cnKiqKhx9+mLCwMCZNmmRq3C3Fz7Wfn58fCxYs4PrrryckJITk5GT+9Kc/0a1bN8aNG2dq3C3FrFmzePvtt1m5ciVeXl41Y8p9fHxwc3PDx8eHW2+9lfj4ePz8/PD29mb27NnExcUxbNgws8NvEX6pDZOTk3n77be5+uqr8ff3Z9euXdx7772MGjWKfv36mR1+izBv3jwmTJhAREQEhYWFvP3226xbt47PP/9cz2ArofypYZQ/XTzlTw2nHKphlEM1nHKohmm2/KkJVgOUn/H8888bERERhouLizF06FBj8+bNZofUakyePNkIDQ01XFxcjI4dOxqTJ082kpKSzA6rRfv6668N4Jxt2rRphlG9dPHDDz9sBAcHG1ar1RgzZoxx4MABs8NuMX6u/UpKSoyrrrrKCAwMNJydnY3IyEjj9ttvNzIyMswOu8Woq+0A4/XXX6855/Tp08bdd99t+Pr6Gu7u7sZvfvMbIz093dS4W5JfasPU1FRj1KhRhp+fn2G1Wo1u3boZf/zjH438/HyzQ28xbrnlFiMyMtJwcXExAgMDjTFjxhhffPFFzXE9g62D8qf6U/508ZQ/NZxyqIZRDtVwyqEaprnyJ4th/x9LRERERERERESkWWgOKRERERERERERaVYqSImIiIiIiIiISLNSQUpERERERERERJqVClIiIiIiIiIiItKsVJASEREREREREZFmpYKUiIiIiIiIiIg0KxWkRERERERERESkWakgJSIiIiIiIiIizUoFKRGRRmSxWFixYoXZYYiIiIi0GsqfRNonFaREpM2YPn06FovlnG38+PFmhyYiIiLSIil/EhGzOJkdgIhIYxo/fjyvv/56rX1Wq9W0eERERERaOuVPImIG9ZASkTbFarUSEhJSa/P19YXq7uAvvvgiEyZMwM3NjS5duvD+++/X+vzu3bu54oorcHNzw9/fnzvuuIOioqJa57z22mv07t0bq9VKaGgo99xzT63j2dnZ/OY3v8Hd3Z3u3buzatWqZrhzERERkfpR/iQiZlBBSkTalYcffpjrr7+enTt3MmXKFG688Ub2798PQHFxMePGjcPX15fvv/+eZcuWsWbNmloJ04svvsisWbO444472L17N6tWraJbt261fseCBQu44YYb2LVrF1dffTVTpkwhNze32e9VREREpDEofxKRJmGIiLQR06ZNMxwdHQ0PD49a29/+9jfDMAwDMO66665an4mNjTVmzpxpGIZhvPzyy4avr69RVFRUc/yTTz4xHBwcjIyMDMMwDCMsLMz485//fN4YAOMvf/lLzfuioiIDMD777LNGv18RERGRhlL+JCJm0RxSItKmXH755bz44ou19vn5+dX8HBcXV+tYXFwcCQkJAOzfv5/+/fvj4eFRc3zEiBHYbDYOHDiAxWIhLS2NMWPG/GwM/fr1q/nZw8MDb29vsrKyGnxvIiIiIk1B+ZOImEEFKRFpUzw8PM7pAt5Y3NzcLug8Z2fnWu8tFgs2m61JYhIRERFpKOVPImIGzSElIu3K5s2bz3nfs2dPAHr27MnOnTspLi6uOf7tt9/i4OBATEwMXl5edO7cmbVr1zZ73CIiIiJmUf4kIk1BPaREpE0pKysjIyOj1j4nJycCAgIAWLZsGYMHD+bSSy/lv//9L1u3bmXJkiUATJkyhfnz5zNt2jQeffRRTp48yezZs7n55psJDg4G4NFHH+Wuu+4iKCiICRMmUFhYyLfffsvs2bNNuFsRERGRhlP+JCJmUEFKRNqU1atXExoaWmtfTEwMiYmJUL2Cy7vvvsvdd99NaGgo77zzDr169QLA3d2dzz//nDlz5jBkyBDc3d25/vrrefrpp2uuNW3aNEpLS3nmmWe4//77CQgI4Le//W0z36WIiIhI41H+JCJmsBj2VQ1ERNo8i8XC8uXLmTRpktmhiIiIiLQKyp9EpKloDikREREREREREWlWKkiJiIiIiIiIiEiz0pA9ERERERERERFpVuohJSIiIiIiIiIizUoFKRERERERERERaVYqSImIiIiIiIiISLNSQUpERERERERERJqVClIiIiIiIiIiItKsVJASEREREREREZFmpYKUiIiIiIiIiIg0KxWkRERERERERESkWakgJSIiIiIiIiIizer/A9adHr+DldLwAAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 1200x400 with 2 Axes>"
|
|
]
|
|
},
|
|
"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": [
|
|
"# 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)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "71ec455a",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Model Performance Metrics:\n",
|
|
"Average BLEU Score: 1.05%\n",
|
|
"Average BLEU-1 Precision: 23.45%\n",
|
|
"Average BLEU-2 Precision: 7.38%\n",
|
|
"Average BLEU-3 Precision: 3.56%\n",
|
|
"Average BLEU-4 Precision: 0.97%\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from collections import Counter\n",
|
|
"import pandas as pd\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"def evaluate_model_performance(test_data):\n",
|
|
" output_path = \"bleu_question_calculation.xlsx\"\n",
|
|
"\n",
|
|
" bleu_scores = []\n",
|
|
" rows = []\n",
|
|
"\n",
|
|
" for i in range(len(test_data)):\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",
|
|
" pred_question = predict_question(\n",
|
|
" sample_context, sample_tokens, sample_ner, sample_srl, sample_q_type\n",
|
|
" )\n",
|
|
"\n",
|
|
" actual_tokens = actual_question.split()\n",
|
|
" pred_tokens = pred_question.split()\n",
|
|
"\n",
|
|
" max_n = 4\n",
|
|
" weights = [1 / max_n] * max_n\n",
|
|
" clipped_counts = []\n",
|
|
" total_counts = []\n",
|
|
" precisions = []\n",
|
|
"\n",
|
|
" # print(f\"Sample {i+1}:\")\n",
|
|
" # print(f\"Actual Tokens: {actual_tokens}\")\n",
|
|
" # print(f\"Predicted Tokens: {pred_tokens}\")\n",
|
|
"\n",
|
|
" # Kalkulasi untuk setiap n-gram\n",
|
|
" for n in range(1, max_n + 1):\n",
|
|
" ref_ngrams = Counter(tuple(actual_tokens[j:j + n]) for j in range(len(actual_tokens) - n + 1))\n",
|
|
" cand_ngrams = Counter(tuple(pred_tokens[j:j + n]) for j in range(len(pred_tokens) - n + 1))\n",
|
|
"\n",
|
|
" clip_sum = sum(min(cnt, ref_ngrams.get(ng, 0)) for ng, cnt in cand_ngrams.items())\n",
|
|
" total = sum(cand_ngrams.values())\n",
|
|
" p_n = clip_sum / total if total > 0 else 0\n",
|
|
"\n",
|
|
" clipped_counts.append(clip_sum)\n",
|
|
" total_counts.append(total)\n",
|
|
" precisions.append(p_n)\n",
|
|
"\n",
|
|
" # print(f\"{n}-gram: clipped count = {clip_sum}, total candidate = {total}, precision = {p_n:.4f}\")\n",
|
|
"\n",
|
|
" c = len(pred_tokens)\n",
|
|
" r = len(actual_tokens)\n",
|
|
"\n",
|
|
" if c == 0:\n",
|
|
" bp = 0 \n",
|
|
" # print(f\"Brevity Penalty: BP = {bp:.4f} (c={c}, r={r}) - No predicted tokens.\")\n",
|
|
" else:\n",
|
|
" bp = 1 if c > r else np.exp(1 - r / c)\n",
|
|
" # print(f\"Brevity Penalty: BP = {bp:.4f} (c={c}, r={r})\")\n",
|
|
"\n",
|
|
" if all(p > 0 for p in precisions):\n",
|
|
" bleu = bp * np.exp(sum(w * np.log(p) for w, p in zip(weights, precisions)))\n",
|
|
" else:\n",
|
|
" bleu = 0.0\n",
|
|
"\n",
|
|
" # print(f\"BLEU score = {bleu:.4f}\\n\")\n",
|
|
"\n",
|
|
" bleu_scores.append(bleu)\n",
|
|
" \n",
|
|
" # Membuat row data dengan kolom terpisah\n",
|
|
" row_data = {\n",
|
|
" \"Sample\": i + 1,\n",
|
|
" \"Actual_Question\": actual_question,\n",
|
|
" \"Predicted_Question\": pred_question,\n",
|
|
" \"Actual_Tokens_Count\": len(actual_tokens),\n",
|
|
" \"Predicted_Tokens_Count\": len(pred_tokens),\n",
|
|
" \n",
|
|
" # BLEU-1\n",
|
|
" \"BLEU1_Clipped_Count\": clipped_counts[0],\n",
|
|
" \"BLEU1_Total_Count\": total_counts[0],\n",
|
|
" \"BLEU1_Precision\": precisions[0],\n",
|
|
" \n",
|
|
" # BLEU-2\n",
|
|
" \"BLEU2_Clipped_Count\": clipped_counts[1],\n",
|
|
" \"BLEU2_Total_Count\": total_counts[1],\n",
|
|
" \"BLEU2_Precision\": precisions[1],\n",
|
|
" \n",
|
|
" # BLEU-3\n",
|
|
" \"BLEU3_Clipped_Count\": clipped_counts[2],\n",
|
|
" \"BLEU3_Total_Count\": total_counts[2],\n",
|
|
" \"BLEU3_Precision\": precisions[2],\n",
|
|
" \n",
|
|
" # BLEU-4\n",
|
|
" \"BLEU4_Clipped_Count\": clipped_counts[3],\n",
|
|
" \"BLEU4_Total_Count\": total_counts[3],\n",
|
|
" \"BLEU4_Precision\": precisions[3],\n",
|
|
" \n",
|
|
" # Brevity Penalty dan BLEU Score\n",
|
|
" \"Brevity_Penalty\": bp,\n",
|
|
" \"BLEU_Score\": bleu\n",
|
|
" }\n",
|
|
" \n",
|
|
" rows.append(row_data)\n",
|
|
"\n",
|
|
" # Membuat DataFrame dan menyimpan ke Excel\n",
|
|
" df = pd.DataFrame(rows)\n",
|
|
" \n",
|
|
" # Menambahkan sheet untuk summary statistics\n",
|
|
" with pd.ExcelWriter(output_path, engine='openpyxl') as writer:\n",
|
|
" # Sheet detail untuk setiap sample\n",
|
|
" df.to_excel(writer, sheet_name='BLEU_Details', index=False)\n",
|
|
" \n",
|
|
" # Sheet summary untuk statistik keseluruhan\n",
|
|
" summary_data = {\n",
|
|
" 'Metric': [\n",
|
|
" 'Average BLEU Score',\n",
|
|
" 'Average BLEU-1 Precision',\n",
|
|
" 'Average BLEU-2 Precision', \n",
|
|
" 'Average BLEU-3 Precision',\n",
|
|
" 'Average BLEU-4 Precision',\n",
|
|
" 'Average Brevity Penalty',\n",
|
|
" 'Total Samples'\n",
|
|
" ],\n",
|
|
" 'Value': [\n",
|
|
" np.mean(bleu_scores),\n",
|
|
" df['BLEU1_Precision'].mean(),\n",
|
|
" df['BLEU2_Precision'].mean(),\n",
|
|
" df['BLEU3_Precision'].mean(),\n",
|
|
" df['BLEU4_Precision'].mean(),\n",
|
|
" df['Brevity_Penalty'].mean(),\n",
|
|
" len(test_data)\n",
|
|
" ]\n",
|
|
" }\n",
|
|
" \n",
|
|
" summary_df = pd.DataFrame(summary_data)\n",
|
|
" summary_df.to_excel(writer, sheet_name='Summary', index=False)\n",
|
|
" \n",
|
|
" # print(f\"Hasil disimpan di: {output_path}\")\n",
|
|
" # print(\"File Excel berisi 2 sheet:\")\n",
|
|
" # print(\"1. 'BLEU_Details' - Detail kalkulasi untuk setiap sample\")\n",
|
|
" # print(\"2. 'Summary' - Ringkasan statistik keseluruhan\")\n",
|
|
"\n",
|
|
" results = {\n",
|
|
" \"avg_bleu_score\": np.mean(bleu_scores),\n",
|
|
" \"avg_bleu1_precision\": df['BLEU1_Precision'].mean(),\n",
|
|
" \"avg_bleu2_precision\": df['BLEU2_Precision'].mean(),\n",
|
|
" \"avg_bleu3_precision\": df['BLEU3_Precision'].mean(),\n",
|
|
" \"avg_bleu4_precision\": df['BLEU4_Precision'].mean(),\n",
|
|
" }\n",
|
|
"\n",
|
|
" return results\n",
|
|
"\n",
|
|
"# Jalankan evaluasi\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 BLEU-1 Precision: {performance_metrics['avg_bleu1_precision'] * 100:.2f}%\")\n",
|
|
"print(f\"Average BLEU-2 Precision: {performance_metrics['avg_bleu2_precision'] * 100:.2f}%\")\n",
|
|
"print(f\"Average BLEU-3 Precision: {performance_metrics['avg_bleu3_precision'] * 100:.2f}%\")\n",
|
|
"print(f\"Average BLEU-4 Precision: {performance_metrics['avg_bleu4_precision'] * 100:.2f}%\")"
|
|
]
|
|
}
|
|
],
|
|
"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
|
|
}
|