diff --git a/README.md b/README.md index c4ce89b..22dbe2f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

MIT License - +

--- @@ -17,6 +17,7 @@ * [Chatbot](#chatbot) * [Dependency Parser](#dependency-parser) * [Entity Tagging](#entity-tagging) + * [Extractive Summarization](#extractive-summarization) * [Generator](#generator) * [Language Detection](#language-detection) * [Neural Machine Translation](neural-machine-translation) @@ -174,6 +175,16 @@ Trained on [CONLL NER](https://cogcomp.org/page/resource_view/81). 7. Char Ngrams + Attention is you all Need + CRF, test accuracy 90% 8. BERT, test accuracy 99% +### [Extractive Summarization](extractive-summarization) + +Trained on [CNN News dataset](https://cs.nyu.edu/~kcho/DMQA/). + +Accuracy based on ROUGE-2. + +1. LSTM RNN, test accuracy 16.13% +2. Dilated-CNN, test accuracy 15.54% +3. Multihead Attention, test accuracy 26.33% + ### [Generator](generator) Trained on [Shakespeare dataset](generator/shakespeare.txt). diff --git a/extractive-summarization/1.rnn-lstm.ipynb b/extractive-summarization/1.rnn-lstm.ipynb new file mode 100644 index 0000000..3a35e44 --- /dev/null +++ b/extractive-summarization/1.rnn-lstm.ipynb @@ -0,0 +1,882 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/home/husein/.local/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "import pickle" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['train_texts', 'test_texts', 'train_clss', 'test_clss', 'train_labels', 'test_labels'])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with open('dataset.pkl', 'rb') as fopen:\n", + " dataset = pickle.load(fopen)\n", + "dataset.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "73967" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(dataset['train_texts'])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "with open('dictionary.pkl', 'rb') as fopen:\n", + " dictionary = pickle.load(fopen)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "rev_dictionary = dictionary['rev_dictionary']\n", + "dictionary = dictionary['dictionary']" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "class Model:\n", + " def __init__(self, size_layer, num_layers, embedded_size,\n", + " dict_size, learning_rate):\n", + " \n", + " def cells(reuse=False):\n", + " return tf.nn.rnn_cell.LSTMCell(size_layer,initializer=tf.orthogonal_initializer(),reuse=reuse)\n", + " \n", + " self.X = tf.placeholder(tf.int32, [None, None])\n", + " self.Y = tf.placeholder(tf.float32, [None, None])\n", + " self.mask = tf.placeholder(tf.int32, [None, None])\n", + " self.clss = tf.placeholder(tf.int32, [None, None])\n", + " mask = tf.cast(self.mask, tf.float32)\n", + " encoder_embeddings = tf.Variable(tf.random_uniform([dict_size, embedded_size], -1, 1))\n", + " encoder_embedded = tf.nn.embedding_lookup(encoder_embeddings, self.X)\n", + " rnn_cells = tf.nn.rnn_cell.MultiRNNCell([cells() for _ in range(num_layers)])\n", + " outputs, _ = tf.nn.dynamic_rnn(rnn_cells, encoder_embedded, dtype = tf.float32)\n", + " outputs = tf.gather(outputs, self.clss, axis = 1, batch_dims = 1)\n", + " self.logits = tf.layers.dense(outputs, 1)\n", + " self.logits = tf.squeeze(self.logits, axis=-1)\n", + " self.logits = self.logits * mask\n", + " crossent = tf.nn.sigmoid_cross_entropy_with_logits(logits=self.logits, labels=self.Y)\n", + " crossent = crossent * mask\n", + " crossent = tf.reduce_sum(crossent)\n", + " total_size = tf.reduce_sum(mask)\n", + " self.cost = tf.div_no_nan(crossent, total_size)\n", + " \n", + " self.optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(self.cost)\n", + " \n", + " l = tf.round(tf.sigmoid(self.logits))\n", + " self.accuracy = tf.reduce_mean(tf.cast(tf.boolean_mask(l, tf.equal(self.Y, 1)), tf.float32))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "size_layer = 256\n", + "num_layers = 2\n", + "embedded_size = 256\n", + "learning_rate = 1e-3\n", + "batch_size = 128\n", + "epoch = 20" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:From :6: LSTMCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "This class is equivalent as tf.keras.layers.LSTMCell, and will be replaced by that in Tensorflow 2.0.\n", + "WARNING:tensorflow:From :15: MultiRNNCell.__init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "This class is equivalent as tf.keras.layers.StackedRNNCells, and will be replaced by that in Tensorflow 2.0.\n", + "WARNING:tensorflow:From :16: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Please use `keras.layers.RNN(cell)`, which is equivalent to this API\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/rnn_cell_impl.py:961: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Call initializer instance with the dtype argument instead of passing it to the constructor\n", + "WARNING:tensorflow:From :18: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use keras.layers.dense instead.\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Call initializer instance with the dtype argument instead of passing it to the constructor\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/nn_impl.py:180: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.where in 2.0, which has the same broadcast rule as np.where\n" + ] + } + ], + "source": [ + "tf.reset_default_graph()\n", + "sess = tf.InteractiveSession()\n", + "model = Model(size_layer,num_layers,embedded_size,len(dictionary),learning_rate)\n", + "sess.run(tf.global_variables_initializer())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "UNK = 3\n", + "\n", + "def str_idx(corpus, dic):\n", + " X = []\n", + " for i in corpus:\n", + " ints = []\n", + " for k in i.split():\n", + " ints.append(dic.get(k,UNK))\n", + " X.append(ints)\n", + " return X\n", + "\n", + "def pad_sentence_batch(sentence_batch, pad_int):\n", + " padded_seqs = []\n", + " seq_lens = []\n", + " max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n", + " for sentence in sentence_batch:\n", + " padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n", + " seq_lens.append(len(sentence))\n", + " return padded_seqs, seq_lens" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "train_X = str_idx(dataset['train_texts'], dictionary)\n", + "test_X = str_idx(dataset['test_texts'], dictionary)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "train_clss = dataset['train_clss']\n", + "test_clss = dataset['test_clss']\n", + "train_Y = dataset['train_labels']\n", + "test_Y = dataset['test_labels']" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.27272728, 0.68941796)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "batch_x, _ = pad_sentence_batch(train_X[:5], 0)\n", + "batch_y, _ = pad_sentence_batch(train_Y[:5], 0)\n", + "batch_clss, _ = pad_sentence_batch(train_clss[:5], -1)\n", + "batch_clss = np.array(batch_clss)\n", + "batch_mask = 1 - (batch_clss == -1)\n", + "batch_clss[batch_clss == -1] = 0\n", + "\n", + "feed = {model.X: batch_x,\n", + " model.Y: batch_y,\n", + " model.mask: batch_mask,\n", + " model.clss: batch_clss}\n", + "acc, loss, _ = sess.run([model.accuracy, model.cost,model.optimizer], feed_dict = feed)\n", + "acc, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "minibatch loop: 100%|██████████| 578/578 [23:49<00:00, 2.47s/it, accuracy=0, cost=0.267] \n", + "minibatch loop: 100%|██████████| 145/145 [02:01<00:00, 1.19it/s, accuracy=0, cost=0.221]\n", + "minibatch loop: 0%| | 0/578 [00:00:4: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use `tf.cast` instead.\n", + "WARNING:tensorflow:From :25: conv1d (from tensorflow.python.layers.convolutional) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use `tf.keras.layers.Conv1D` instead.\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Call initializer instance with the dtype argument instead of passing it to the constructor\n", + "WARNING:tensorflow:From :54: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use keras.layers.dense instead.\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/nn_impl.py:180: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.where in 2.0, which has the same broadcast rule as np.where\n" + ] + } + ], + "source": [ + "tf.reset_default_graph()\n", + "sess = tf.InteractiveSession()\n", + "model = Model(size_layer,num_layers,embedded_size,len(dictionary),learning_rate)\n", + "sess.run(tf.global_variables_initializer())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "UNK = 3\n", + "\n", + "def str_idx(corpus, dic):\n", + " X = []\n", + " for i in corpus:\n", + " ints = []\n", + " for k in i.split():\n", + " ints.append(dic.get(k,UNK))\n", + " X.append(ints)\n", + " return X\n", + "\n", + "def pad_sentence_batch(sentence_batch, pad_int):\n", + " padded_seqs = []\n", + " seq_lens = []\n", + " max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n", + " for sentence in sentence_batch:\n", + " padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n", + " seq_lens.append(len(sentence))\n", + " return padded_seqs, seq_lens" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "train_X = str_idx(dataset['train_texts'], dictionary)\n", + "test_X = str_idx(dataset['test_texts'], dictionary)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "train_clss = dataset['train_clss']\n", + "test_clss = dataset['test_clss']\n", + "train_Y = dataset['train_labels']\n", + "test_Y = dataset['test_labels']" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.36363637, 0.80718136)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "batch_x, _ = pad_sentence_batch(train_X[:5], 0)\n", + "batch_y, _ = pad_sentence_batch(train_Y[:5], 0)\n", + "batch_clss, _ = pad_sentence_batch(train_clss[:5], -1)\n", + "batch_clss = np.array(batch_clss)\n", + "batch_mask = 1 - (batch_clss == -1)\n", + "batch_clss[batch_clss == -1] = 0\n", + "\n", + "feed = {model.X: batch_x,\n", + " model.Y: batch_y,\n", + " model.mask: batch_mask,\n", + " model.clss: batch_clss}\n", + "acc, loss, _ = sess.run([model.accuracy, model.cost,model.optimizer], feed_dict = feed)\n", + "acc, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "minibatch loop: 100%|██████████| 578/578 [05:11<00:00, 1.86it/s, accuracy=0, cost=0.268] \n", + "minibatch loop: 100%|██████████| 145/145 [00:21<00:00, 6.74it/s, accuracy=0, cost=0.221] \n", + "minibatch loop: 0%| | 0/578 [00:00:98: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use `tf.cast` instead.\n", + "WARNING:tensorflow:From :68: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use keras.layers.dense instead.\n", + "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Call initializer instance with the dtype argument instead of passing it to the constructor\n", + "WARNING:tensorflow:From :41: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use tf.where in 2.0, which has the same broadcast rule as np.where\n", + "WARNING:tensorflow:From :30: dropout (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "Instructions for updating:\n", + "Use keras.layers.dropout instead.\n" + ] + } + ], + "source": [ + "tf.reset_default_graph()\n", + "sess = tf.InteractiveSession()\n", + "model = Model(size_layer,embedded_size,len(dictionary),learning_rate)\n", + "sess.run(tf.global_variables_initializer())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "UNK = 3\n", + "\n", + "def str_idx(corpus, dic):\n", + " X = []\n", + " for i in corpus:\n", + " ints = []\n", + " for k in i.split():\n", + " ints.append(dic.get(k,UNK))\n", + " X.append(ints)\n", + " return X\n", + "\n", + "def pad_sentence_batch(sentence_batch, pad_int):\n", + " padded_seqs = []\n", + " seq_lens = []\n", + " max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n", + " for sentence in sentence_batch:\n", + " padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n", + " seq_lens.append(len(sentence))\n", + " return padded_seqs, seq_lens" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "train_X = str_idx(dataset['train_texts'], dictionary)\n", + "test_X = str_idx(dataset['test_texts'], dictionary)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "train_clss = dataset['train_clss']\n", + "test_clss = dataset['test_clss']\n", + "train_Y = dataset['train_labels']\n", + "test_Y = dataset['test_labels']" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1.0, 1.4390177)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "batch_x, _ = pad_sentence_batch(train_X[:64], 0)\n", + "batch_y, _ = pad_sentence_batch(train_Y[:64], 0)\n", + "batch_clss, _ = pad_sentence_batch(train_clss[:64], -1)\n", + "batch_clss = np.array(batch_clss)\n", + "batch_mask = 1 - (batch_clss == -1)\n", + "batch_clss[batch_clss == -1] = 0\n", + "\n", + "feed = {model.X: batch_x,\n", + " model.Y: batch_y,\n", + " model.mask: batch_mask,\n", + " model.clss: batch_clss}\n", + "acc, loss, _ = sess.run([model.accuracy, model.cost,model.optimizer], feed_dict = feed)\n", + "acc, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "minibatch loop: 100%|██████████| 1156/1156 [06:35<00:00, 2.92it/s, accuracy=0.0167, cost=0.376] \n", + "minibatch loop: 100%|██████████| 289/289 [00:37<00:00, 7.65it/s, accuracy=0.00641, cost=0.397]\n", + "minibatch loop: 0%| | 0/1156 [00:00')\n", + " elif re.match(_regex._money, w):\n", + " tokens.append('')\n", + " elif re.match(_regex._date, w):\n", + " tokens.append('')\n", + " else:\n", + " tokens.append(w)\n", + " return tokens\n", + "\n", + "def split_story(doc):\n", + " index = doc.find('@highlight')\n", + " story, highlights = doc[:index], doc[index:].split('@highlight')\n", + " highlights = [h.strip() for h in highlights if len(h) > 0]\n", + " stories = []\n", + " for s in splitter(story):\n", + " stories.append(preprocessing(s))\n", + " summaries = []\n", + " for s in highlights:\n", + " summaries.append(preprocessing(s))\n", + " return stories, summaries" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "min_src_nsents = 3\n", + "max_src_nsents = 20\n", + "min_src_ntokens_per_sent = 5\n", + "max_src_ntokens_per_sent = 30\n", + "min_tgt_ntokens = 5\n", + "max_tgt_ntokens = 500\n", + "sep_token = '[SEP]'\n", + "cls_token = '[CLS]'" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "with open(stories[0]) as fopen:\n", + " story = fopen.read()\n", + "story, highlights = split_story(story)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def _get_ngrams(n, text):\n", + " ngram_set = set()\n", + " text_length = len(text)\n", + " max_index_ngram_start = text_length - n\n", + " for i in range(max_index_ngram_start + 1):\n", + " ngram_set.add(tuple(text[i:i + n]))\n", + " return ngram_set\n", + "\n", + "\n", + "def _get_word_ngrams(n, sentences):\n", + " assert len(sentences) > 0\n", + " assert n > 0\n", + "\n", + " words = sum(sentences, [])\n", + " return _get_ngrams(n, words)\n", + "\n", + "def cal_rouge(evaluated_ngrams, reference_ngrams):\n", + " reference_count = len(reference_ngrams)\n", + " evaluated_count = len(evaluated_ngrams)\n", + "\n", + " overlapping_ngrams = evaluated_ngrams.intersection(reference_ngrams)\n", + " overlapping_count = len(overlapping_ngrams)\n", + "\n", + " if evaluated_count == 0:\n", + " precision = 0.0\n", + " else:\n", + " precision = overlapping_count / evaluated_count\n", + "\n", + " if reference_count == 0:\n", + " recall = 0.0\n", + " else:\n", + " recall = overlapping_count / reference_count\n", + "\n", + " f1_score = 2.0 * ((precision * recall) / (precision + recall + 1e-8))\n", + " return {\"f\": f1_score, \"p\": precision, \"r\": recall}\n", + "\n", + "\n", + "def greedy_selection(doc_sent_list, abstract_sent_list, summary_size):\n", + " def _rouge_clean(s):\n", + " return re.sub(r'[^a-zA-Z0-9 ]', '', s)\n", + "\n", + " max_rouge = 0.0\n", + " abstract = sum(abstract_sent_list, [])\n", + " abstract = _rouge_clean(' '.join(abstract)).split()\n", + " sents = [_rouge_clean(' '.join(s)).split() for s in doc_sent_list]\n", + " evaluated_1grams = [_get_word_ngrams(1, [sent]) for sent in sents]\n", + " reference_1grams = _get_word_ngrams(1, [abstract])\n", + " evaluated_2grams = [_get_word_ngrams(2, [sent]) for sent in sents]\n", + " reference_2grams = _get_word_ngrams(2, [abstract])\n", + "\n", + " selected = []\n", + " for s in range(summary_size):\n", + " cur_max_rouge = max_rouge\n", + " cur_id = -1\n", + " for i in range(len(sents)):\n", + " if (i in selected):\n", + " continue\n", + " c = selected + [i]\n", + " candidates_1 = [evaluated_1grams[idx] for idx in c]\n", + " candidates_1 = set.union(*map(set, candidates_1))\n", + " candidates_2 = [evaluated_2grams[idx] for idx in c]\n", + " candidates_2 = set.union(*map(set, candidates_2))\n", + " rouge_1 = cal_rouge(candidates_1, reference_1grams)['f']\n", + " rouge_2 = cal_rouge(candidates_2, reference_2grams)['f']\n", + " rouge_score = rouge_1 + rouge_2\n", + " if rouge_score > cur_max_rouge:\n", + " cur_max_rouge = rouge_score\n", + " cur_id = i\n", + " if (cur_id == -1):\n", + " return selected\n", + " selected.append(cur_id)\n", + " max_rouge = cur_max_rouge\n", + "\n", + " return sorted(selected)\n", + "\n", + "def get_xy(story, highlights):\n", + " idxs = [i for i, s in enumerate(story) if (len(s) > min_src_ntokens_per_sent)]\n", + " \n", + " idxs = [i for i, s in enumerate(story) if (len(s) > min_src_ntokens_per_sent)]\n", + "\n", + " src = [story[i][:max_src_ntokens_per_sent] for i in idxs]\n", + " src = src[:max_src_nsents]\n", + "\n", + " sent_labels = greedy_selection(src, highlights, 3)\n", + "\n", + " _sent_labels = [0] * len(src)\n", + " for l in sent_labels:\n", + " _sent_labels[l] = 1\n", + " _sent_labels\n", + " \n", + " src_txt = [' '.join(sent) for sent in src]\n", + " text = ' {} {} '.format(sep_token, cls_token).join(src_txt)\n", + " text = '[CLS] %s [SEP]'%(text)\n", + " cls_ids = [i for i, t in enumerate(text.split()) if t == cls_token]\n", + " \n", + " return text, cls_ids, _sent_labels" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import collections\n", + "import json\n", + "\n", + "def build_dataset(words, n_words, atleast=1):\n", + " count = [['PAD', 0], ['GO', 1], ['EOS', 2], ['UNK', 3]]\n", + " counter = collections.Counter(words).most_common(n_words)\n", + " counter = [i for i in counter if i[1] >= atleast]\n", + " count.extend(counter)\n", + " dictionary = dict()\n", + " for word, _ in count:\n", + " dictionary[word] = len(dictionary)\n", + " data = list()\n", + " unk_count = 0\n", + " for word in words:\n", + " index = dictionary.get(word, 0)\n", + " if index == 0:\n", + " unk_count += 1\n", + " data.append(index)\n", + " count[0][1] = unk_count\n", + " reversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))\n", + " return data, count, dictionary, reversed_dictionary" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# from dask import delayed\n", + "# import dask\n", + "\n", + "# def process(i):\n", + "# with open(stories[i]) as fopen:\n", + "# story = fopen.read()\n", + "# story, highlights = split_story(story)\n", + "# return get_xy(story, highlights)\n", + "\n", + "# train = []\n", + "# for i in range(len(stories)):\n", + "# im = delayed(process)(i)\n", + "# train.append(im)\n", + " \n", + "# train = dask.compute(*train)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "with open(stories[1]) as fopen:\n", + " story = fopen.read()\n", + "story, highlights = split_story(story)\n", + "text, cls_ids, sent_labels = get_xy(story, highlights)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(20, 20, 560)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(sent_labels), len(cls_ids), len(text.split())" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 92579/92579 [16:41<00:00, 92.41it/s] \n" + ] + } + ], + "source": [ + "from tqdm import tqdm\n", + "\n", + "texts, clss, labels = [], [], []\n", + "\n", + "for i in tqdm(range(len(stories))):\n", + " with open(stories[i]) as fopen:\n", + " story = fopen.read()\n", + " story, highlights = split_story(story)\n", + " text, cls_ids, sent_labels = get_xy(story, highlights)\n", + " if len(cls_ids) != len(sent_labels):\n", + " continue\n", + " texts.append(text)\n", + " clss.append(cls_ids)\n", + " labels.append(sent_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "vocab from size: 118356\n", + "Most common words [('the', 1974502), (',', 1740960), ('[CLS]', 1668596), ('[SEP]', 1668596), ('.', 1284463), ('to', 844716)]\n" + ] + } + ], + "source": [ + "concat = ' '.join(texts).split()\n", + "vocabulary_size = len(list(set(concat)))\n", + "_, count, dictionary, rev_dictionary = build_dataset(concat, vocabulary_size, atleast = 2)\n", + "print('vocab from size: %d'%(len(dictionary)))\n", + "print('Most common words', count[4:10])" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "\n", + "train_texts, test_texts, train_clss, test_clss, train_labels, test_labels = \\\n", + "train_test_split(texts, clss, labels, test_size = 0.2)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "import pickle\n", + "\n", + "with open('dataset.pkl', 'wb') as fopen:\n", + " pickle.dump({'train_texts': train_texts,\n", + " 'test_texts': test_texts,\n", + " 'train_clss': train_clss,\n", + " 'test_clss': test_clss,\n", + " 'train_labels': train_labels,\n", + " 'test_labels': test_labels}, fopen)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "with open('dictionary.pkl', 'wb') as fopen:\n", + " pickle.dump({'dictionary': dictionary, 'rev_dictionary': rev_dictionary}, fopen)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/neural-machine-translation/43.attention-is-all-you-need-beam.ipynb b/neural-machine-translation/43.attention-is-all-you-need-beam.ipynb index 430f59b..340ca63 100644 --- a/neural-machine-translation/43.attention-is-all-you-need-beam.ipynb +++ b/neural-machine-translation/43.attention-is-all-you-need-beam.ipynb @@ -7,7 +7,7 @@ "outputs": [], "source": [ "import os\n", - "os.environ['CUDA_VISIBLE_DEVICES'] = '2'" + "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" ] }, { @@ -303,12 +303,13 @@ " encoder_embedded = tf.nn.embedding_lookup(encoder_embedding, x)\n", " en_masks = tf.sign(x)\n", " encoder_embedded += sinusoidal_position_encoding(x, en_masks, size_layer)\n", + " enc = encoder_embedded\n", " \n", " for i in range(num_blocks):\n", " with tf.variable_scope('encoder_self_attn_%d'%i,reuse=reuse):\n", - " enc = multihead_attention(queries=encoder_embedded,\n", - " keys=encoder_embedded,\n", - " values=encoder_embedded,\n", + " enc = multihead_attention(queries=enc,\n", + " keys=enc,\n", + " values=enc,\n", " num_heads=num_heads,\n", " causality=False)\n", " enc = ff(enc, num_units=[size_layer * ratio_hidden, size_layer])\n", @@ -399,19 +400,19 @@ "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:507: calling count_nonzero (from tensorflow.python.ops.math_ops) with axis is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "reduction_indices is deprecated, use axis instead\n", - "WARNING:tensorflow:From :102: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", + "WARNING:tensorflow:From :102: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use `tf.cast` instead.\n", - "WARNING:tensorflow:From :72: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "WARNING:tensorflow:From :72: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use keras.layers.dense instead.\n", "WARNING:tensorflow:From /home/husein/.local/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Call initializer instance with the dtype argument instead of passing it to the constructor\n", - "WARNING:tensorflow:From :45: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", + "WARNING:tensorflow:From :45: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use tf.where in 2.0, which has the same broadcast rule as np.where\n", - "WARNING:tensorflow:From :34: dropout (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", + "WARNING:tensorflow:From :34: dropout (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", "Instructions for updating:\n", "Use keras.layers.dropout instead.\n", "WARNING:tensorflow:\n", @@ -498,339 +499,339 @@ "name": "stderr", "output_type": "stream", "text": [ - "minibatch loop: 100%|██████████| 1389/1389 [05:30<00:00, 4.20it/s, accuracy=0.153, cost=6.59] \n", - "minibatch loop: 100%|██████████| 30/30 [00:03<00:00, 9.85it/s, accuracy=0.158, cost=6.6] \n", - "minibatch loop: 0%| | 1/1389 [00:00<04:21, 5.31it/s, accuracy=0.195, cost=5.64]" + "minibatch loop: 100%|██████████| 1389/1389 [06:42<00:00, 3.45it/s, accuracy=0.142, cost=6.66] \n", + "minibatch loop: 100%|██████████| 30/30 [00:03<00:00, 7.95it/s, accuracy=0.144, cost=6.6] \n", + "minibatch loop: 0%| | 0/1389 [00:00 phút ở đây , về ba thế hệ phụ nữ , về thế hệ sức mạnh của đời sống bằng cách hỗ trợ cuộc sống thực của bà bà ta hơn năm sau khi bà bà bà bà bà bà còn nhỏ nhất hơn so với bà bà bà bà ấy hơn năm trước hơn so với hơn so với hơn so với hơn so với hơn năm so với hơn so với hơn so với hơn so với hơn năm chúng ta ? Trong câu trả\n", + "0 predict: Lúc này tôi có thể nói phút còn khoảng phút của phụ nữ , về việc làm thế nào một cô bé xuất ra một cô gái tuổi , cô bé gái tuổi của cao tuổi này với con gái tuổi và cô gái đang ở tuổi tuổi tuổi tuổi mà đã giảm số lượng lớn tuổi của cô ấy đã giảm số tuổi của Trung Quốc . Một năm trước . . . . . . . . . . . . . . . . .\n", "0 actual: Làm sao tôi có thể trình bày trong phút về sợi dây liên kết những người phụ nữ qua ba thế hệ , về việc làm thế nào những sợi dây mạnh mẽ đáng kinh ngạc ấy đã níu chặt lấy cuộc sống của một cô bé bốn tuổi co quắp với đứa em gái nhỏ của cô bé , với mẹ và bà trong suốt năm ngày đêm trên con thuyền nhỏ lênh đênh trên Biển Đông hơn năm trước , những sợi dây liên kết đã níu lấy cuộc đời cô bé ấy và không bao giờ rời đi - - cô bé ấy giờ sống ở San Francisco và đang nói chuyện với các bạn hôm nay ?\n", "\n", - "1 predict: Đây không phải là câu chuyện hoàn thiện . Câu chuyện của chúng ta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . đó là một câu chuyện . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "1 predict: Đây không phải là một câu chuyện . . . . . . . . . . . . . . . . . . . . này không phải là một câu chuyện . . . . . . . . . . . . . . . . . . . . . . . . . . này không phải như thế này . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "1 actual: Câu chuyện này chưa kết thúc .\n", "\n", - "2 predict: Nó là một ứng dụng chúng vẫn đang được hợp lại với nhau . Hãy cùng làm việc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "2 predict: Nó vẫn tiếp tục tôn trọng nhau . Nó vẫn được gắn bó . . . . . . . . . vào nhau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nó là cái nghĩa là là sự xã hội . . . . . . . . . . . .\n", "2 actual: Nó là một trò chơi ghép hình vẫn đang được xếp .\n", "\n", - "3 predict: Để tôi kể cho các bạn vài mảnh giấy phiêu lưu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "3 predict: Để tôi kể các bạn nghe về một số đoạn nhạc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . để kể tôi . . . . . . . . . . . . . . . . . . . . . . . .\n", "3 actual: Hãy để tôi kể cho các bạn về vài mảnh ghép nhé .\n", "\n", - "4 predict: Hãy hình dung : một bong bóng gà đầu tiên của anh ta . Trong công việc của anh ấy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "4 predict: Hãy tưởng tượng sinh vật đầu tiên : Hệ thống cuộc đời của anh ta . . . . . . . . . . . . . . . . . . . . hãy tưởng tượng xem như nhau . . . . . . . . . . . . . . . . . . . hãy tưởng tượng này như nhau tưởng tượng luôn luôn luôn luôn luôn luôn thú tượng tượng luôn luôn đếm tưởng tượng này . . . . . . . . . . . . . . . .\n", "4 actual: Hãy tưởng tượng mảnh đầu tiên : một người đàn ông đốt cháy sự nghiệp cả đời mình .\n", "\n", - "5 predict: Ông ấy là một nhà thơ , một người đàn ông , một người duy nhất đã bị bỏ rơi trên đất nước và sự tự do ngoại trừ sự tự do ý chí . Đó là sự tự do và sự tự do ngôn ngữ và sự tự do . Nó chính là sự tự do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "5 predict: Anh ta là một nhà thơ , một người đàn ông có cuộc sống của mình và tự do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tự do và tự do . . . . . . . . . . . . . tự do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "5 actual: Ông là nhà thơ , nhà viết kịch , một người mà cả cuộc đời chênh vênh trên tia hi vọng duy nhất rằng đất nước ông sẽ độc lập tự do .\n", "\n", - "6 predict: Hãy tưởng tượng anh ấy là nơi trên thực tế , đã hoàn toàn xấu xa của anh ta . Thật sự lãng phí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . thực sự là một sự lãng lãng cốt . . . . . . .\n", + "6 predict: Hãy tưởng tượng ông ta là sở hữu , thực tế rằng cuộc đời của ông đã hoàn thành . . . . . . . . . . . . . . . . . . . . . . . . . . . . . hãy tưởng tượng ra một hoàn thách . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "6 actual: Hãy tưởng tượng ông , một người cộng sản tiến vào , đối diện sự thật rằng cả cuộc đời ông đã phí hoài .\n", "\n", - "7 predict: Từ lúc này , cho hàng loạt những người bạn đâu đó vì ông ấy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "7 predict: Thêm vào đó vì bạn bè . . . . . . . . . . của anh ấy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . từ rất nhiều việc bị kỵ tự nhiên . . . . . . . . . . . . . . như vậy . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "7 actual: Ngôn từ , qua bao năm tháng là bạn đồng hành với ông , giờ quay ra chế giễu ông .\n", "\n", - "8 predict: Anh ấy đi vào sự tĩnh lặng . Thật ra ngoài . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "8 predict: Anh ta đi vào sự im lặng . Có khi im lặng . . . . . . . . . . . . . . . . . . . khi anh ấy đi vào đèn hư hỏng . . . . . . . . . . . . . . . . . . . . . . . . cởi cởi cởi cởi chán khoá khoá khoá khoá . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "8 actual: Ông rút lui vào yên lặng .\n", "\n", - "9 predict: Anh ta chết đuối nháy . Anh đã chết lịch sử . Anh ấy đã chết . Anh ấy đã chết . Anh ấy đã chết . Anh ấy đã chết lịch sử . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "9 predict: Anh ta mất đi bằng lịch sử . . . . . . . . . . . . . . . . . . . . . . . . . . đã qua đời . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . này kể đời đời . . . . . . . . . . . . . . . . . . . . .\n", "9 actual: Ông qua đời , bị lịch sử quật ngã .\n", "\n", - "10 predict: Anh ấy là ông nội tại ông nội . Anh ấy là ông ấy . Anh ấy đang thực hiện . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "10 predict: Ông ấy là ông của tôi . Ông ấy là kiến thức của ông . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ông là anh là người đời . . . . . . . . của ông . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "10 actual: Ông là ông của tôi .\n", "\n", - "11 predict: Tôi không bao giờ biết nó trong cuộc sống thực sự . . . . . . . . . . . . . . . . . . . . . tôi không bao giờ biết thật sự . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "11 predict: Tôi chưa bao giờ biết gì cả . . . . . . . . . . . . . . . . . . . . . . . . chưa bao giờ đi chăng chăng như tôi trước như tôi chưa bao giờ . . . . . . . như tôi chưa bao giờ hiểu được bao giờ như vậy . . . . . như tôi chưa bao giờ như tôi chưa bao giờ bao giờ bao giờ bao giờ bao giờ bao giờ nhớ bao giờ . như tôi chưa bao giờ bao giờ\n", "11 actual: Tôi chưa bao giờ gặp ông ngoài đời .\n", "\n", - "12 predict: Nhưng cuộc sống của chúng ta hơn nhiều so với ký ức của chúng ta . Thừa đến hơn là ký ức . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cuộc cuộc sống của chúng ta hơn nhiều thời điểm . . . . . . . . . . . . . . . .\n", + "12 predict: Nhưng cuộc sống của chúng ta còn dành nhiều ký ức của chúng ta hơn mục đích của chúng ta . . . . . . . . . . . . . . từ đó . . . . . . . . . . . . từ cuộc sống này của chúng ta và đẻ đẻ tương tác của chúng ta . . . . . cuộc sống của chúng ta sống sống này ảnh hưởng từ cuộc sống này của chúng ta . . . . . . . . . . . . . .\n", "12 actual: Nhưng cuộc đời ta nhiều hơn những gì ta lưu trong kí ức nhiều .\n", "\n", - "13 predict: Người bà tôi không bao giờ quên đời ông ấy . Hãy sửa cuộc sống của ông ta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . thì hãy hãy để tôi đang quên . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "13 predict: Em không bao giờ để tôi quên đời . . . . . . . . . . . . . . . . . . . . . nhận thức của tôi về đời tôi . . . . . . . . . . đừng đừng đừng đừng đừng quên việc đời của tôi . . . . . . . . . . tôi không bao đừng đừng đừng đừng đừng đừng đừng đừng đừng quên quên đời đời đời tôi . . . . . . . . . . . . . . .\n", "13 actual: Bà tôi chưa bao giờ cho phép tôi quên cuộc đời của ông .\n", "\n", - "14 predict: Bảo tôi không cho phép điều đó , bài học của tôi được kiểm tra tấn , và vâng , vâng , vâng , vâng , vâng , chúng ta . \" chúng ta có thể tiếp tục . . \" nhưng chúng ta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "14 predict: Chân tôi không cho phép ta đánh giá , và cũng đang học hỏi chúng ta nhưng chúng ta đã cố gắn thời gian . . . . . . . . nhưng chúng ta đang hướng tới . . . . . . . . . . . . . . . . . . . . chúng ta càng đùa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "14 actual: Nhiệm vụ của tôi là không để cuộc đời ấy qua trong vô vọng , và bài học của tôi là nhận ra rằng , vâng , lịch sử đã cố quật ngã chúng tôi , nhưng chúng tôi đã chịu đựng được .\n", "\n", - "15 predict: Sau điểm màu tiếp theo là sự biến đổi trong một cái tổ chức nào đó buổi diễn chú . Hãy sửa nó . Hãy bận tâm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "15 predict: Tiếp theo là của một công việc có hành động đầu tiên ngay từ đầu tới mực nước biển hút mực nước biển . Tiếp đi xuyên đi nước biển . Quả là đi săn mồi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "15 actual: Mảnh ghép tiếp theo của tấm hình là một con thuyền trong sớm hoàng hôn lặng lẽ trườn ra biển .\n", "\n", - "16 predict: Mẹ tôi , thật hạn , lúc tuổi khi cô ấy mất hai cuộc hôn nhân của mình trong cuộc hôn nhân hai cô bé nhỏ , với hai em gái nhỏ rồi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "16 predict: Mẹ tôi lúc tuổi đã qua đời . . . . . . . . . . . . với hai cô gái nhỏ . . . . . . . . . . . . . . . . . . . . . . . . hai cô gái . . . . . . . . . . . . . . . . . . . . của mẹ tôi . . . . . . . . . . . . . hai chữ lời lời lời lời tiên này của cô\n", "16 actual: Mẹ tôi , Mai , mới tuổi khi ba của mẹ mất - - đã lập gia đình , một cuộc hôn nhân sắp đặt trước , đã có hai cô con gái nhỏ .\n", "\n", - "17 predict: Đối với cô ấy , sự sống của chính nó có một nhiệm vụ : Một gia đình và gia đình mới trong cuộc sống gia đình bà ấy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "17 predict: Đối với cuộc đời mình , cuộc sống thành một công : cuộc đời và gia đình mới ở Úc . . . . . . . . . . . trong Úc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lịch sử nước Úc . . . . . . . . . . . . . . . . . . . . .\n", "17 actual: Với mẹ , cuộc đời cô đọng vào nhiệm vụ duy nhất : để gia đình mẹ trốn thoát và bắt đầu cuộc sống mới ở Úc .\n", "\n", - "18 predict: Nó có thể khiến cô ấy không thành công . Nó sẽ không thành công . . . . . . . . . . . . . cô ấy không thể hiểu biết cô ấy sẽ đi theo . . . . . . . . . . . . . cô ấy có thể sẽ thành công . . . . . . . . . . . . . . . . . . . cô ấy có thể thành công việc . . . . . . . . . . . . . .\n", + "18 predict: Đó là việc cô ấy sẽ không thành công . thành công . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . từ nó đến việc việc hối bao nhiêu . . . . . . . . . . . . . . . . . . . . .\n", "18 actual: Mẹ không bao giờ chấp nhận được là mẹ sẽ không thành công .\n", "\n", - "19 predict: Một năm sau - bốt tái sinh ra ma trận ngoại bào sắt ra đại dương như một con cá voi như một chiếc Syria . Những đánh cá voi đánh cá mồi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", + "19 predict: Sau năm tin sinh ra phân tử Việt Nam Cực như con Hạ rủi ro với rủi ro như . . . . . . . . . . . . . . . . . ngày tháng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", "19 actual: Thế là sau bốn năm , một trường thiên đằng đẵng hơn cả trong truyện , một chiếc thuyền trườn ra biển nguỵ trang là thuyền đánh cá .\n", "\n" ]