{"cells":[{"metadata":{"_uuid":"1269d0481484736312ea010b46218dbc9dd4ac94"},"cell_type":"markdown","source":"# Materials used for this notebook\n- Preprocessing: https://www.kaggle.com/theoviel/improve-your-score-with-some-text-preprocessing\n- Sliced RNN: https://github.com/zepingyu0512/srnn\n- Embedding mean: https://www.kaggle.com/shujian/single-rnn-with-4-folds-clr\n- OneCycle:  https://github.com/titu1994/keras-one-cycle\n-  https://www.kaggle.com/strideradu/word2vec-and-gensim-go-go-go\n- Bi-GRU-ATT model: https://www.kaggle.com/rasvob/let-s-try-clr-v3"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\nimport time\nstartTime = time.time()\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport operator \nimport re\nimport gc\nimport pickle\n\nfrom keras.preprocessing.text import Tokenizer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"38d688e434b5f9da7e111caab6d21229044e8774"},"cell_type":"code","source":"np.random.seed(42)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a2f22c60a4ae33007fabfc892bd68d472fc51164"},"cell_type":"markdown","source":"# Embeddings - methods"},{"metadata":{"trusted":true,"_uuid":"50a7e53ea6dec85b5a0df42b0411ede4a491f2a9"},"cell_type":"code","source":"def load_embed(file):\n    def get_coefs(word, *arr):\n        return word, np.asarray(arr, dtype='float32')\n\n    if file == '../input/embeddings/wiki-news-300d-1M/wiki-news-300d-1M.vec':\n        embeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(file) if len(o) > 100)\n    else:\n        embeddings_index = dict(get_coefs(*o.split(\" \")) for o in open(file, encoding='latin'))\n        \n    return embeddings_index","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"20333b0ebe78575291fe3baadd0453b4212905b5"},"cell_type":"code","source":"def index_embs(embeddings_index, word_index, NUM_WORDS, fileName):\n    \n    all_embs = np.stack(embeddings_index.values())\n    emb_mean, emb_std = all_embs.mean(), all_embs.std()\n    embed_size = all_embs.shape[1]\n\n    # word_index = tokenizer.word_index\n    embedding_matrix = np.random.normal(emb_mean, emb_std, (NUM_WORDS, embed_size))\n\n    for word, i in word_index.items():\n        if i >= NUM_WORDS: continue\n        embedding_vector = embeddings_index.get(word)\n        if embedding_vector is not None: embedding_matrix[i] = embedding_vector\n    \n    np.save(fileName, embedding_matrix)\n    print(fileName + \" embedding matrix saved!\")\n    \n    del(embeddings_index)\n    del(word_index)\n    del(embedding_matrix)\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"03fe8724352817c10d7bf65054ca879d4f625430"},"cell_type":"code","source":"def check_coverage(vocab, embeddings_index):\n    known_words = {}\n    unknown_words = {}\n    nb_known_words = 0\n    nb_unknown_words = 0\n    for word in vocab.keys():\n        try:\n            known_words[word] = embeddings_index[word]\n            nb_known_words += vocab[word]\n        except:\n            unknown_words[word] = vocab[word]\n            nb_unknown_words += vocab[word]\n            pass\n\n    print('Found embeddings for {:.2%} of vocab'.format(len(known_words) / len(vocab)))\n    print('Found embeddings for  {:.2%} of all text'.format(nb_known_words / (nb_known_words + nb_unknown_words)))\n    unknown_words = sorted(unknown_words.items(), key=operator.itemgetter(1))[::-1]\n\n    return unknown_words","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d01e30b9e7d6163cab80563f5f7ad8a707d4cebb"},"cell_type":"code","source":"def build_vocab(texts, num_words):\n#     sentences = texts.apply(lambda x: x.split()).values\n#     vocab = {}\n#     for sentence in sentences:\n#         for word in sentence:\n#             try:\n#                 vocab[word] += 1\n#             except KeyError:\n#                 vocab[word] = 1\n    tokenizer = Tokenizer(num_words=NUM_WORDS, filters=\"\")\n    tokenizer.fit_on_texts(texts)\n    \n    # saving\n    with open('tokenizer.pickle', 'wb') as handle:\n        pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)\n    \n    print(\"\\nKeras text tokenizer has been saved as tokenizer.pickle\")\n    \n    return tokenizer.word_index","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eddcb2d64e893b281bff6d87444867a72b97a1e9"},"cell_type":"code","source":"def add_lower(embedding, vocab):\n    \"\"\"\n    Therer are words that are known with upper letters and unknown without. This method saves both variants of the word\n    \n    \"\"\"\n\n    count = 0\n    for word in vocab:\n        if word in embedding and word.lower() not in embedding:  \n            embedding[word.lower()] = embedding[word]\n            count += 1\n    print(f\"Added {count} words to embedding\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f73a57ca72feb1870bb15f40ef59b400e8eda2f2"},"cell_type":"code","source":"def known_contractions(embed):\n    \n    known = []\n    for contract in contraction_mapping:\n        if contract in embed:\n            known.append(contract)\n    return known","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f93b5fcf9099f78880e8673d0cda4baa700a3801"},"cell_type":"code","source":"def clean_contractions(text, mapping):\n    specials = [\"’\", \"‘\", \"´\", \"`\"]\n    for s in specials:\n        text = text.replace(s, \"'\")\n    text = ' '.join([mapping[t] if t in mapping else t for t in text.split(\" \")])\n    return text","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"443b46203179107bf74c28e54e5f6f6b21b38aae"},"cell_type":"code","source":"def unknown_punct(embed, punct):\n    unknown = ''\n    for p in punct:\n        if p not in embed:\n            unknown += p\n            unknown += ' '\n    return unknown","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"567cd85bacd35fecb2714af834b8fcfa4abde6b1"},"cell_type":"code","source":"def clean_special_chars(text, punct):\n#     for p in mapping:\n#         text = text.replace(p, mapping[p])\n    \n    for p in punct:\n        text = text.replace(p, f' {p} ')\n    \n    specials = {'\\u200b': ' ', '…': ' ... ', '\\ufeff': '', 'करना': '', 'है': ''}  # Other special characters that I have to deal with in last\n    for s in specials:\n        text = text.replace(s, specials[s])\n    \n    return text","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2779f1eb74ecdf9ae893f6d5555026a7d486c9e2"},"cell_type":"code","source":"def get_mappings():\n    \"\"\"\n    returns: \n    mispell_dict: mapping from mispelled word to correct word\n    contraction_mapping: mapping from contraction to full word(s)\n    punct_mapping: mapping from punctuation/special char to proper punctuation\n    \"\"\"\n    mispell_dict = {'colour': 'color', 'centre': 'center', 'favourite': 'favorite', 'travelling': 'traveling', 'counselling': 'counseling', 'theatre': 'theater', 'cancelled': 'canceled', 'labour': 'labor', 'organisation': 'organization', 'wwii': 'world war 2', 'citicise': 'criticize', 'youtu ': 'youtube ', 'Qoura': 'Quora', 'sallary': 'salary', 'Whta': 'What', 'narcisist': 'narcissist', 'howdo': 'how do', 'whatare': 'what are', 'howcan': 'how can', 'howmuch': 'how much', 'howmany': 'how many', 'whydo': 'why do', 'doI': 'do I', 'theBest': 'the best', 'howdoes': 'how does', 'mastrubation': 'masturbation', 'mastrubate': 'masturbate', \"mastrubating\": 'masturbating', 'pennis': 'penis', 'Etherium': 'Ethereum', 'narcissit': 'narcissist', 'bigdata': 'big data', '2k17': '2017', '2k18': '2018', 'qouta': 'quota', 'exboyfriend': 'ex boyfriend', 'airhostess': 'air hostess', \"whst\": 'what', 'watsapp': 'whatsapp', 'demonitisation': 'demonetization', 'demonitization': 'demonetization', 'demonetisation': 'demonetization'}\n    punct = \":)(-!?|;\\'$&/[]>%=#*+\\\\•~@£·_{}©^®`<→°€™›♥←×§″′Â█½à…“★”–●â►−¢²¬░¶↑±¿▾═¦║―¥▓—‹─▒：¼⊕▼▪†■’▀¨▄♫☆é¯♦¤▲è¸¾Ã⋅‘∞∙）↓、│（»，♪╩╚³・╦╣╔╗▬❤ïØ¹≤‡√\"\n#     punct = \"/-'?!.,#$%\\'()*+-/:;<=>@[\\\\]^_`{|}~\" + '\"\"“”’' + '∞θ÷α•à−β∅³π‘₹´°£€\\×™√²—–&'\n#     punct_mapping = {\"‘\": \"'\", \"₹\": \"e\", \"´\": \"'\", \"°\": \"\", \"€\": \"e\", \"™\": \"tm\", \"√\": \" sqrt \", \"×\": \"x\", \"²\": \"2\", \"—\": \"-\", \"–\": \"-\", \"’\": \"'\", \"_\": \"-\", \"`\": \"'\", '“': '\"', '”': '\"', '“': '\"', \"£\": \"e\", '∞': 'infinity', 'θ': 'theta', '÷': '/', 'α': 'alpha', '•': '.', 'à': 'a', '−': '-', 'β': 'beta', '∅': '', '³': '3', 'π': 'pi', }\n    contraction_mapping = {\"ain't\": \"is not\", \"aren't\": \"are not\",\"can't\": \"cannot\", \"'cause\": \"because\", \"could've\": \"could have\", \"couldn't\": \"could not\", \"didn't\": \"did not\",  \"doesn't\": \"does not\", \"don't\": \"do not\", \"hadn't\": \"had not\", \"hasn't\": \"has not\", \"haven't\": \"have not\", \"he'd\": \"he would\",\"he'll\": \"he will\", \"he's\": \"he is\", \"how'd\": \"how did\", \"how'd'y\": \"how do you\", \"how'll\": \"how will\", \"how's\": \"how is\",  \"I'd\": \"I would\", \"I'd've\": \"I would have\", \"I'll\": \"I will\", \"I'll've\": \"I will have\",\"I'm\": \"I am\", \"I've\": \"I have\", \"i'd\": \"i would\", \"i'd've\": \"i would have\", \"i'll\": \"i will\",  \"i'll've\": \"i will have\",\"i'm\": \"i am\", \"i've\": \"i have\", \"isn't\": \"is not\", \"it'd\": \"it would\", \"it'd've\": \"it would have\", \"it'll\": \"it will\", \"it'll've\": \"it will have\",\"it's\": \"it is\", \"let's\": \"let us\", \"ma'am\": \"madam\", \"mayn't\": \"may not\", \"might've\": \"might have\",\"mightn't\": \"might not\",\"mightn't've\": \"might not have\", \"must've\": \"must have\", \"mustn't\": \"must not\", \"mustn't've\": \"must not have\", \"needn't\": \"need not\", \"needn't've\": \"need not have\",\"o'clock\": \"of the clock\", \"oughtn't\": \"ought not\", \"oughtn't've\": \"ought not have\", \"shan't\": \"shall not\", \"sha'n't\": \"shall not\", \"shan't've\": \"shall not have\", \"she'd\": \"she would\", \"she'd've\": \"she would have\", \"she'll\": \"she will\", \"she'll've\": \"she will have\", \"she's\": \"she is\", \"should've\": \"should have\", \"shouldn't\": \"should not\", \"shouldn't've\": \"should not have\", \"so've\": \"so have\",\"so's\": \"so as\", \"this's\": \"this is\",\"that'd\": \"that would\", \"that'd've\": \"that would have\", \"that's\": \"that is\", \"there'd\": \"there would\", \"there'd've\": \"there would have\", \"there's\": \"there is\", \"here's\": \"here is\",\"they'd\": \"they would\", \"they'd've\": \"they would have\", \"they'll\": \"they will\", \"they'll've\": \"they will have\", \"they're\": \"they are\", \"they've\": \"they have\", \"to've\": \"to have\", \"wasn't\": \"was not\", \"we'd\": \"we would\", \"we'd've\": \"we would have\", \"we'll\": \"we will\", \"we'll've\": \"we will have\", \"we're\": \"we are\", \"we've\": \"we have\", \"weren't\": \"were not\", \"what'll\": \"what will\", \"what'll've\": \"what will have\", \"what're\": \"what are\",  \"what's\": \"what is\", \"what've\": \"what have\", \"when's\": \"when is\", \"when've\": \"when have\", \"where'd\": \"where did\", \"where's\": \"where is\", \"where've\": \"where have\", \"who'll\": \"who will\", \"who'll've\": \"who will have\", \"who's\": \"who is\", \"who've\": \"who have\", \"why's\": \"why is\", \"why've\": \"why have\", \"will've\": \"will have\", \"won't\": \"will not\", \"won't've\": \"will not have\", \"would've\": \"would have\", \"wouldn't\": \"would not\", \"wouldn't've\": \"would not have\", \"y'all\": \"you all\", \"y'all'd\": \"you all would\",\"y'all'd've\": \"you all would have\",\"y'all're\": \"you all are\",\"y'all've\": \"you all have\",\"you'd\": \"you would\", \"you'd've\": \"you would have\", \"you'll\": \"you will\", \"you'll've\": \"you will have\", \"you're\": \"you are\", \"you've\": \"you have\" }\n\n    return mispell_dict, contraction_mapping, punct #punct_mapping, punct","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b1e899f9789eb3660ad0586eb266a9f5dde8556e"},"cell_type":"code","source":"def correct_spelling(x, dic):\n    for word in dic.keys():\n        x = x.replace(word, dic[word])\n    return x","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2559a80fdce5bc5fb5dbf1eb8bc888bb7f33cf79"},"cell_type":"markdown","source":"# Embeddings - cleaning"},{"metadata":{"trusted":true,"_uuid":"b7aacecda6b4170ca5422675a4f7612d13aba89d"},"cell_type":"code","source":"def run_text_preprocessing(df, textCol, outputFileName):\n    mispell_map, contraction_map, punct = get_mappings()\n    \n#     print(\"\\nWorking on: \" + outputFileName)\n#     print(\"\\n****** WORD COVERAGE BEFORE PREPROCESSING ******\")\n#     vocab = build_vocab(df[textCol])\n#     print(\"Glove : \")\n#     oov_glove = check_coverage(vocab, embed_glove)\n#     print(\"Paragram : \")\n#     oov_paragram = check_coverage(vocab, embed_paragram)\n#     print(\"FastText : \")\n#     oov_fasttext = check_coverage(vocab, embed_fasttext)\n      \n    # To lower char\n    df['lowered_question'] = df[textCol].apply(lambda x: x.lower())\n    # Contractions\n    df['treated_question'] = df['lowered_question'].apply(lambda x: clean_contractions(x, contraction_map))\n    # Punct + Special chars\n    df['treated_question'] = df['treated_question'].apply(lambda x: clean_special_chars(x, punct))\n    # Mispelling\n    #df['treated_question'] = df['treated_question'].apply(lambda x: correct_spelling(x, mispell_map))\n    \n#     print(\"\\n****** FINAL WORD COVERAGE AFTER PREPROCESSING ******\")\n#     vocab = build_vocab(df[\"treated_question\"])\n#     print(\"Glove : \")\n#     oov_glove = check_coverage(vocab, embed_glove)\n#     print(\"Paragram : \")\n#     oov_paragram = check_coverage(vocab, embed_paragram)\n#     print(\"FastText : \")\n#     oov_fasttext = check_coverage(vocab, embed_fasttext)\n    \n    print(\"\\nDATAFRAME SAVED TO:\")\n    print(\"{0}_processed_text.csv\".format(outputFileName))\n    df.to_csv(\"{0}_processed_text.csv\".format(outputFileName))\n    \n    del(df)\n    del(mispell_map)\n    del(contraction_map) \n    del(punct)\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72e631ea4b49e3589cffc1834eb5093601e85974"},"cell_type":"code","source":"train = pd.read_csv(\"../input/train.csv\")\ntest = pd.read_csv(\"../input/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a938d1b5da352c1346dcc5873b28206afd42fb4"},"cell_type":"code","source":"run_text_preprocessing(train, \"question_text\", \"train\")\nrun_text_preprocessing(test, \"question_text\", \"test\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ac16f2f29a06042a571f88557c7425b16f4db776"},"cell_type":"code","source":"df_texts = pd.concat([train.drop('target', axis=1),test])\ndf_texts.to_csv(\"texts_processed.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7bbc8e943962ebd7a1be389f96b7c908570706da"},"cell_type":"code","source":"del(train)\ndel(test)\ngc.collect()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0285e1dd96bae050fbbbd8d3bd2aef8f3306ba69"},"cell_type":"code","source":"glove = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt'\nparagram =  '../input/embeddings/paragram_300_sl999/paragram_300_sl999.txt'\nwiki_news = '../input/embeddings/wiki-news-300d-1M/wiki-news-300d-1M.vec'\n\nNUM_WORDS = None\nword_idx = build_vocab(df_texts[\"treated_question\"], NUM_WORDS)\nNUM_WORDS = len(word_idx) + 1\nprint(\"\\n\\n****** LOAD EMBEDDINGS ******\")\n\nprint(\"\\n---Extracting GloVe embedding---\")\nembed_glove = load_embed(glove)\nindex_embs(embed_glove, word_idx, NUM_WORDS, fileName=\"glove\")\ndel(embed_glove)\ngc.collect()\n\n# print(\"\\n---Extracting Paragram embedding---\")\n# embed_paragram = load_embed(paragram)\n# index_embs(embed_paragram, word_idx, NUM_WORDS, fileName=\"paragram\")\n# del(embed_paragram)\n# gc.collect()\n\nprint(\"\\n---Extracting FastText embedding---\")\nembed_fasttext = load_embed(wiki_news)\nindex_embs(embed_fasttext, word_idx, NUM_WORDS, fileName=\"fasttext\")\ndel(embed_fasttext)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0f8803a3d595218ddf672c986cab758240f16e2b"},"cell_type":"code","source":"print(os.listdir())\n(time.time() - startTime)/ 60","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3853b566dbd20dd3aefeeb95c54ac9fe649702c8"},"cell_type":"code","source":"# dump all variables\nimport gc\ngc.collect()\n%reset -f","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9e53a3296a2c70e1058be8ab9e3b2879b5480cc0"},"cell_type":"markdown","source":"# Data preparation"},{"metadata":{"trusted":true,"_uuid":"24084d74b9746fe5ab26da610bade25eacb83067"},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport gc\nimport time\nimport pickle\nimport six\nimport copy\nfrom six.moves import zip\nimport warnings\n\nfrom tensorflow import set_random_seed\n\nfrom sklearn.model_selection import StratifiedShuffleSplit, StratifiedKFold\nfrom sklearn.metrics import classification_report, f1_score\n\nfrom keras.engine.topology import Layer\nfrom keras.utils.generic_utils import serialize_keras_object\nfrom keras.utils.generic_utils import deserialize_keras_object\nfrom keras.legacy import interfaces\nfrom keras.preprocessing.text import Tokenizer, text_to_word_sequence\nfrom keras.preprocessing.sequence import pad_sequences\nfrom keras.models import Model\nfrom keras import backend as K\nfrom keras.layers import Input, Embedding, GRU, TimeDistributed, Dense, CuDNNGRU, Bidirectional, Dropout, SpatialDropout1D\nfrom keras.layers import concatenate, GlobalMaxPooling1D, GlobalAveragePooling1D, BatchNormalization, CuDNNLSTM\nfrom keras import initializers, regularizers, constraints, optimizers, layers\nfrom keras.callbacks import Callback\nfrom keras.optimizers import Optimizer\nfrom keras import initializers\nfrom keras import regularizers\n\nimport matplotlib.pyplot as plt\n\nimport time\nstartTimePt2 = time.time()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7637da938524f4e4c30c23ebd768b97135678dcc"},"cell_type":"code","source":"NUM_WORDS = None\nEMBEDDING_DIM = 300\nNUM_FILTERS = 50\nMAX_LEN = 64 #256\nBATCH_SIZE = 2560\nRANDOM_STATE = 42\nNUM_EPOCH = 11\nLR = 0.001 # 3e-4\nLR_MAX = LR * 6 # 7e-2\nWD = 0.011 * (BATCH_SIZE / 979591 / NUM_EPOCH)**0.5\nSTEP_SIZE_CLR = 2 * (979591 / BATCH_SIZE)\n\n# Suggested weight decay factor from the paper: w = w_norm * (b/B/T)**0.5\n# b: batch size\n# B: total number of training points per epoch\n# T: total number of epochs\n# w_norm: designed weight decay factor (w is the normalized one).","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a5b8e8af76d61c1431605f53e62945453778d1a2"},"cell_type":"code","source":"np.random.seed(RANDOM_STATE)\nset_random_seed(RANDOM_STATE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"995197d120e6d142155703178f876d98a9bb2edb"},"cell_type":"code","source":"df_train = pd.read_csv(\"train_processed_text.csv\")\ndf_test = pd.read_csv(\"test_processed_text.csv\")\nprint(\"Train shape : \", df_train.shape)\nprint(\"Test shape : \", df_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9c4938db1d527de5737246e1a3316a8206e8910d"},"cell_type":"code","source":"## fill up the missing values\nX_train = df_train[\"treated_question\"].fillna(\"_na_\").values\nX_test = df_test[\"treated_question\"].fillna(\"_na_\").values\n\ny_train = df_train['target'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"152a5692b8a99a42f5b1e53919825230a2756698"},"cell_type":"code","source":"# loading\nwith open('tokenizer.pickle', 'rb') as handle:\n    tokenizer = pickle.load(handle)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f964197834fcdefe52507cbd05c4102b39096f06"},"cell_type":"code","source":"X_train = tokenizer.texts_to_sequences(X_train)\nX_test = tokenizer.texts_to_sequences(X_test)\nprint(\"hello word\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"abecdc2b6fb0300e44a3699540e71aafde8ced05"},"cell_type":"code","source":"NUM_WORDS = len(tokenizer.word_index)\nNUM_WORDS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1665707bf366b3214e87291d894be092696e99ad"},"cell_type":"code","source":"import sys\ndef sizeof_fmt(num, suffix='B'):\n    ''' By Fred Cirera, after https://stackoverflow.com/a/1094933/1870254'''\n    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:\n        if abs(num) < 1024.0:\n            return \"%3.1f%s%s\" % (num, unit, suffix)\n        num /= 1024.0\n    return \"%.1f%s%s\" % (num, 'Yi', suffix)\n\nfor name, size in sorted(((name, sys.getsizeof(value)) for name,value in locals().items()),\n                         key= lambda x: -x[1])[:10]:\n    print(\"{:>30}: {:>8}\".format(name,sizeof_fmt(size)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5faa252e4d2de4b3162059ace24b193e0aefa720"},"cell_type":"code","source":"## Pad the sentences \nX_train = pad_sequences(X_train, maxlen=MAX_LEN)\nX_test = pad_sequences(X_test, maxlen=MAX_LEN)\nprint(\"hello word\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"daab9bee7701865ac5cfb1e14b06010d4bce1f0c"},"cell_type":"code","source":"X_train[0].shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0cd53d3b907b7178f26b0870895c84a2d052c616"},"cell_type":"code","source":"del(df_train)\ndel(df_test)\ndel(tokenizer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1eff697fe5c2aed29fa210edf5811d26f42b12a7"},"cell_type":"code","source":"embedding_matrix_1 = np.load(\"glove.npy\")\nembedding_matrix_2 = np.load(\"fasttext.npy\")\n#embedding_matrix_3 = np.load(\"paragram.npy\")\nprint(\"Done...\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"88573e2ac6b4c78766d521694b1fae075b4c6d84"},"cell_type":"code","source":"embedding_matrix = np.mean([embedding_matrix_1, embedding_matrix_2], axis = 0)\nnp.shape(embedding_matrix)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0ab636ca8b9ab7c27f01e4e7c96f458cf285484a"},"cell_type":"code","source":"del(embedding_matrix_1)\ndel(embedding_matrix_2)\n#del(embedding_matrix_3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"711ddca533b84d0559d9de1bf6942950df2bfa23"},"cell_type":"code","source":"gc.collect()\nprint(\"done\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8bc9880163dae7c28bede2ad527483ac06ae049c"},"cell_type":"markdown","source":"# Data preparation - SRNN specific"},{"metadata":{"trusted":true,"_uuid":"3bd01203e205e1fb29c899b77bbcac5d4ae75b67"},"cell_type":"code","source":"#slice sequences into many subsequences\ndef SliceDataSRNN(data):\n    slicedData = []\n    \n    for i in range(data.shape[0]):\n        split1 = np.split(data[i], 2)\n        a=[]\n        \n        for j in range(2):\n            s=np.split(split1[j], 2)\n            a.append(s)\n        slicedData.append(a)\n    \n    arr = np.array(slicedData, dtype=np.int32)\n    \n    del(slicedData)\n    del(a)\n    del(s)\n    del(split1)    \n    gc.collect()\n    \n    return arr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6ce747c6cc2494c80d7e483c5d9343fcdb1f0759"},"cell_type":"code","source":"x_train_padded_seqs_split = SliceDataSRNN(X_train)\nx_test_padded_seqs_split = SliceDataSRNN(X_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"017ce67ad7e32b8910741bcc78ef59b19663a423"},"cell_type":"code","source":"x_test_padded_seqs_split[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"023f64ff62021c671c4c76daab962fed76860dcb"},"cell_type":"code","source":"del(X_test)\ndel(X_train)\n\ngc.collect()\nprint(\"done\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"63cee59b85e720c1a50a87471f65d3b8aaaa9561"},"cell_type":"markdown","source":"\n# Model (SRNN)"},{"metadata":{"trusted":true,"_uuid":"a8e942029c240a8da749cd573ce62240c83f48c2"},"cell_type":"code","source":"class CyclicLR(Callback):\n    \"\"\"This callback implements a cyclical learning rate policy (CLR).\n    The method cycles the learning rate between two boundaries with\n    some constant frequency, as detailed in this paper (https://arxiv.org/abs/1506.01186).\n    The amplitude of the cycle can be scaled on a per-iteration or \n    per-cycle basis.\n    This class has three built-in policies, as put forth in the paper.\n    \"triangular\":\n        A basic triangular cycle w/ no amplitude scaling.\n    \"triangular2\":\n        A basic triangular cycle that scales initial amplitude by half each cycle.\n    \"exp_range\":\n        A cycle that scales initial amplitude by gamma**(cycle iterations) at each \n        cycle iteration.\n    For more detail, please see paper.\n    \n    # Example\n        ```python\n            clr = CyclicLR(base_lr=0.001, max_lr=0.006,\n                                step_size=2000., mode='triangular')\n            model.fit(X_train, Y_train, callbacks=[clr])\n        ```\n    \n    Class also supports custom scaling functions:\n        ```python\n            clr_fn = lambda x: 0.5*(1+np.sin(x*np.pi/2.))\n            clr = CyclicLR(base_lr=0.001, max_lr=0.006,\n                                step_size=2000., scale_fn=clr_fn,\n                                scale_mode='cycle')\n            model.fit(X_train, Y_train, callbacks=[clr])\n        ```    \n    # Arguments\n        base_lr: initial learning rate which is the\n            lower boundary in the cycle.\n        max_lr: upper boundary in the cycle. Functionally,\n            it defines the cycle amplitude (max_lr - base_lr).\n            The lr at any cycle is the sum of base_lr\n            and some scaling of the amplitude; therefore \n            max_lr may not actually be reached depending on\n            scaling function.\n        step_size: number of training iterations per\n            half cycle. Authors suggest setting step_size\n            2-8 x training iterations in epoch.\n        mode: one of {triangular, triangular2, exp_range}.\n            Default 'triangular'.\n            Values correspond to policies detailed above.\n            If scale_fn is not None, this argument is ignored.\n        gamma: constant in 'exp_range' scaling function:\n            gamma**(cycle iterations)\n        scale_fn: Custom scaling policy defined by a single\n            argument lambda function, where \n            0 <= scale_fn(x) <= 1 for all x >= 0.\n            mode paramater is ignored \n        scale_mode: {'cycle', 'iterations'}.\n            Defines whether scale_fn is evaluated on \n            cycle number or cycle iterations (training\n            iterations since start of cycle). Default is 'cycle'.\n    \"\"\"\n\n    def __init__(self, base_lr=0.001, max_lr=0.006, step_size=2000., mode='triangular',\n                 gamma=1., scale_fn=None, scale_mode='cycle'):\n        super(CyclicLR, self).__init__()\n\n        self.base_lr = base_lr\n        self.max_lr = max_lr\n        self.step_size = step_size\n        self.mode = mode\n        self.gamma = gamma\n        if scale_fn == None:\n            if self.mode == 'triangular':\n                self.scale_fn = lambda x: 1.\n                self.scale_mode = 'cycle'\n            elif self.mode == 'triangular2':\n                self.scale_fn = lambda x: 1/(2.**(x-1))\n                self.scale_mode = 'cycle'\n            elif self.mode == 'exp_range':\n                self.scale_fn = lambda x: gamma**(x)\n                self.scale_mode = 'iterations'\n        else:\n            self.scale_fn = scale_fn\n            self.scale_mode = scale_mode\n        self.clr_iterations = 0.\n        self.trn_iterations = 0.\n        self.history = {}\n\n        self._reset()\n\n    def _reset(self, new_base_lr=None, new_max_lr=None,\n               new_step_size=None):\n        \"\"\"Resets cycle iterations.\n        Optional boundary/step size adjustment.\n        \"\"\"\n        if new_base_lr != None:\n            self.base_lr = new_base_lr\n        if new_max_lr != None:\n            self.max_lr = new_max_lr\n        if new_step_size != None:\n            self.step_size = new_step_size\n        self.clr_iterations = 0.\n        \n    def clr(self):\n        cycle = np.floor(1+self.clr_iterations/(2*self.step_size))\n        x = np.abs(self.clr_iterations/self.step_size - 2*cycle + 1)\n        if self.scale_mode == 'cycle':\n            return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(cycle)\n        else:\n            return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(self.clr_iterations)\n        \n    def on_train_begin(self, logs={}):\n        logs = logs or {}\n\n        if self.clr_iterations == 0:\n            K.set_value(self.model.optimizer.lr, self.base_lr)\n        else:\n            K.set_value(self.model.optimizer.lr, self.clr())        \n            \n    def on_batch_end(self, epoch, logs=None):\n        \n        logs = logs or {}\n        self.trn_iterations += 1\n        self.clr_iterations += 1\n\n#         self.history.setdefault('lr', []).append(K.get_value(self.model.optimizer.lr))\n#         self.history.setdefault('iterations', []).append(self.trn_iterations)\n\n#         for k, v in logs.items():\n#             self.history.setdefault(k, []).append(v)\n        \n        K.set_value(self.model.optimizer.lr, self.clr())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e2035acd9e8370fdce617d4d840ae2b2ba8ba8ce"},"cell_type":"code","source":"def f1(y_true, y_pred):\n    '''\n    metric from here \n    https://stackoverflow.com/questions/43547402/how-to-calculate-f1-macro-in-keras\n    '''\n    def recall(y_true, y_pred):\n        \"\"\"Recall metric.\n\n        Only computes a batch-wise average of recall.\n\n        Computes the recall, a metric for multi-label classification of\n        how many relevant items are selected.\n        \"\"\"\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n        recall = true_positives / (possible_positives + K.epsilon())\n        \n        return recall\n    \n    def precision(y_true, y_pred):\n        \"\"\"Precision metric.\n\n        Only computes a batch-wise average of precision.\n\n        Computes the precision, a metric for multi-label classification of\n        how many selected items are relevant.\n        \"\"\"\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n        precision = true_positives / (predicted_positives + K.epsilon())\n        return precision\n    \n    precision = precision(y_true, y_pred)\n    recall = recall(y_true, y_pred)\n\n    return 2*((precision*recall)/(precision+recall+K.epsilon()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"af1718a594eed5083f89f04c35233aa501fc92b3"},"cell_type":"code","source":"class AdamW(Optimizer):\n    \"\"\"Adam optimizer.\n    Default parameters follow those provided in the original paper.\n    # Arguments\n        lr: float >= 0. Learning rate.\n        beta_1: float, 0 < beta < 1. Generally close to 1.\n        beta_2: float, 0 < beta < 1. Generally close to 1.\n        epsilon: float >= 0. Fuzz factor.\n        decay: float >= 0. Learning rate decay over each update.\n        weight_decay: float >= 0. Decoupled weight decay over each update.\n    # References\n        - [Adam - A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980v8)\n        - [Optimization for Deep Learning Highlights in 2017](http://ruder.io/deep-learning-optimization-2017/index.html)\n        - [Fixing Weight Decay Regularization in Adam](https://arxiv.org/abs/1711.05101)\n    \"\"\"\n\n    def __init__(self, lr=0.001, beta_1=0.9, beta_2=0.999, weight_decay=1e-4,  # decoupled weight decay (1/6)\n                 epsilon=1e-8, decay=0., **kwargs):\n        super(AdamW, self).__init__(**kwargs)\n        with K.name_scope(self.__class__.__name__):\n            self.iterations = K.variable(0, dtype='int64', name='iterations')\n            self.lr = K.variable(lr, name='lr')\n            self.init_lr = lr # decoupled weight decay (2/6)\n            self.beta_1 = K.variable(beta_1, name='beta_1')\n            self.beta_2 = K.variable(beta_2, name='beta_2')\n            self.decay = K.variable(decay, name='decay')\n            self.wd = K.variable(weight_decay, name='weight_decay') # decoupled weight decay (3/6)\n        self.epsilon = epsilon\n        self.initial_decay = decay\n\n    @interfaces.legacy_get_updates_support\n    def get_updates(self, loss, params):\n        grads = self.get_gradients(loss, params)\n        self.updates = [K.update_add(self.iterations, 1)]\n        wd = self.wd # decoupled weight decay (4/6)\n\n        lr = self.lr\n        if self.initial_decay > 0:\n            lr *= (1. / (1. + self.decay * K.cast(self.iterations,\n                                                  K.dtype(self.decay))))\n        eta_t = lr / self.init_lr # decoupled weight decay (5/6)\n\n        t = K.cast(self.iterations, K.floatx()) + 1\n        lr_t = lr * (K.sqrt(1. - K.pow(self.beta_2, t)) /\n                     (1. - K.pow(self.beta_1, t)))\n\n        ms = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]\n        vs = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]\n        self.weights = [self.iterations] + ms + vs\n\n        for p, g, m, v in zip(params, grads, ms, vs):\n            m_t = (self.beta_1 * m) + (1. - self.beta_1) * g\n            v_t = (self.beta_2 * v) + (1. - self.beta_2) * K.square(g)\n            p_t = p - lr_t * m_t / (K.sqrt(v_t) + self.epsilon) - eta_t * wd * p # decoupled weight decay (6/6)\n\n            self.updates.append(K.update(m, m_t))\n            self.updates.append(K.update(v, v_t))\n            new_p = p_t\n\n            # Apply constraints.\n            if getattr(p, 'constraint', None) is not None:\n                new_p = p.constraint(new_p)\n\n            self.updates.append(K.update(p, new_p))\n        return self.updates\n\n    def get_config(self):\n        config = {'lr': float(K.get_value(self.lr)),\n                  'beta_1': float(K.get_value(self.beta_1)),\n                  'beta_2': float(K.get_value(self.beta_2)),\n                  'decay': float(K.get_value(self.decay)),\n                  'weight_decay': float(K.get_value(self.wd)),\n                  'epsilon': self.epsilon}\n        base_config = super(AdamW, self).get_config()\n        return dict(list(base_config.items()) + list(config.items()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c58b0e050cc1001a2c9ed2a54dc0fff87025e5f5"},"cell_type":"code","source":"# Kernel\nglorotInit = initializers.glorot_uniform(seed=RANDOM_STATE)\n# Recurrent\northoInit = initializers.Orthogonal(seed=RANDOM_STATE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"16370faf5c434a7a5bb14409ee3065016a8ab7e7"},"cell_type":"code","source":"\nfrom keras import backend as K, initializers, regularizers, constraints\nfrom keras.engine.topology import Layer\n\n\ndef dot_product(x, kernel):\n    \"\"\"\n    Wrapper for dot product operation, in order to be compatible with both\n    Theano and Tensorflow\n    Args:\n        x (): input\n        kernel (): weights\n    Returns:\n    \"\"\"\n    if K.backend() == 'tensorflow':\n        # todo: check that this is correct\n        return K.squeeze(K.dot(x, K.expand_dims(kernel)), axis=-1)\n    else:\n        return K.dot(x, kernel)\n\n\nclass Attention(Layer):\n    def __init__(self,\n                 W_regularizer=None, b_regularizer=None,\n                 W_constraint=None, b_constraint=None,\n                 bias=True,\n                 return_attention=False,\n                 **kwargs):\n        \"\"\"\n        Keras Layer that implements an Attention mechanism for temporal data.\n        Supports Masking.\n        Follows the work of Raffel et al. [https://arxiv.org/abs/1512.08756]\n        # Input shape\n            3D tensor with shape: `(samples, steps, features)`.\n        # Output shape\n            2D tensor with shape: `(samples, features)`.\n        :param kwargs:\n        Just put it on top of an RNN Layer (GRU/LSTM/SimpleRNN) with return_sequences=True.\n        The dimensions are inferred based on the output shape of the RNN.\n\n\n        Note: The layer has been tested with Keras 1.x\n\n        Example:\n        \n            # 1\n            model.add(LSTM(64, return_sequences=True))\n            model.add(Attention())\n            # next add a Dense layer (for classification/regression) or whatever...\n\n            # 2 - Get the attention scores\n            hidden = LSTM(64, return_sequences=True)(words)\n            sentence, word_scores = Attention(return_attention=True)(hidden)\n\n        \"\"\"\n        self.supports_masking = True\n        self.return_attention = return_attention\n        self.init = glorotInit\n\n        self.W_regularizer = regularizers.get(W_regularizer)\n        self.b_regularizer = regularizers.get(b_regularizer)\n\n        self.W_constraint = constraints.get(W_constraint)\n        self.b_constraint = constraints.get(b_constraint)\n\n        self.bias = bias\n        super(Attention, self).__init__(**kwargs)\n\n    def build(self, input_shape):\n        assert len(input_shape) == 3\n\n        self.W = self.add_weight((input_shape[-1],),\n                                 initializer=self.init,\n                                 name='{}_W'.format(self.name),\n                                 regularizer=self.W_regularizer,\n                                 constraint=self.W_constraint)\n        if self.bias:\n            self.b = self.add_weight((input_shape[1],),\n                                     initializer='zero',\n                                     name='{}_b'.format(self.name),\n                                     regularizer=self.b_regularizer,\n                                     constraint=self.b_constraint)\n        else:\n            self.b = None\n\n        self.built = True\n\n    def compute_mask(self, input, input_mask=None):\n        # do not pass the mask to the next layers\n        return None\n\n    def call(self, x, mask=None):\n        eij = dot_product(x, self.W)\n\n        if self.bias:\n            eij += self.b\n\n        eij = K.tanh(eij)\n\n        a = K.exp(eij)\n\n        # apply mask after the exp. will be re-normalized next\n        if mask is not None:\n            # Cast the mask to floatX to avoid float64 upcasting in theano\n            a *= K.cast(mask, K.floatx())\n\n        # in some cases especially in the early stages of training the sum may be almost zero\n        # and this results in NaN's. A workaround is to add a very small positive number ε to the sum.\n        # a /= K.cast(K.sum(a, axis=1, keepdims=True), K.floatx())\n        a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())\n\n        weighted_input = x * K.expand_dims(a)\n\n        result = K.sum(weighted_input, axis=1)\n\n        if self.return_attention:\n            return [result, a]\n        return result\n\n    def compute_output_shape(self, input_shape):\n        if self.return_attention:\n            return [(input_shape[0], input_shape[-1]),\n                    (input_shape[0], input_shape[1])]\n        else:\n            return input_shape[0], input_shape[-1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8b7a4afb027d6436580b690ade61bb8f98c10de1"},"cell_type":"code","source":"def threshold_search(y_true, y_proba):\n    best_threshold = 0\n    best_score = 0\n    \n    for threshold in [i * 0.01 for i in range(100)]:\n        score = f1_score(y_true=y_true, y_pred=y_proba > threshold)\n        if score > best_score:\n            best_threshold = threshold\n            best_score = score\n    search_result = {'threshold': best_threshold, 'f1': best_score}\n    return search_result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cee2598a315f2d12df71e5f4f09a6ba1a3f7b9a1"},"cell_type":"code","source":"# Kernel\nglorotInit = initializers.glorot_uniform(seed=RANDOM_STATE)\n# Recurrent\northoInit = initializers.Orthogonal(seed=RANDOM_STATE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"703d777c814865375daa4afadcae0b516e65db52"},"cell_type":"code","source":" def srnn_model():\n    embedding_layer = Embedding(NUM_WORDS,\n                                EMBEDDING_DIM,\n                                weights=[embedding_matrix],\n                                input_length=16,\n                                trainable=False)\n    ## ENCODER 1\n    input1 = Input(shape=(16, ), dtype='int32')\n    embed = embedding_layer(input1)\n    drop1 = SpatialDropout1D(0.2)(embed)\n    gru1 = Bidirectional(CuDNNLSTM(NUM_FILTERS, return_sequences=True, kernel_initializer=glorotInit,\n                                  recurrent_initializer=glorotInit))(drop1)\n    gru1_2 = Bidirectional(CuDNNLSTM(NUM_FILTERS, return_sequences=True, kernel_initializer=glorotInit,\n                                  recurrent_initializer=glorotInit))(gru1)\n    atten_1 = Attention()(gru1)\n    atten_1_2 = Attention()(gru1_2)\n    max_pool1 = GlobalMaxPooling1D()(gru1_2)\n    avg_pool1 = GlobalAveragePooling1D()(gru1_2)\n    conc1 = concatenate([atten_1, atten_1_2, max_pool1, avg_pool1])    \n    \n    Encoder1 = Model(input1, conc1)\n\n    ## ENCODER 2\n    input2 = Input(shape=(2, 16, ), dtype='int32')\n    embed2 = TimeDistributed(Encoder1)(input2)\n    gru2 = Bidirectional(CuDNNGRU(NUM_FILTERS, return_sequences=False, kernel_initializer=glorotInit,\n                                  recurrent_initializer=glorotInit))(embed2)\n#     atten_2 = Attention(2)(gru2)\n#     max_pool2 = GlobalMaxPooling1D()(gru2)    \n#     conc2 = concatenate([atten_2, max_pool2])    \n    Encoder2 = Model(input2, gru2)\n\n    ## ENCODER 3\n    input3 = Input(shape=(2, 2, 16), dtype='int32')\n    embed3 = TimeDistributed(Encoder2)(input3)\n    gru3 = Bidirectional(CuDNNGRU(NUM_FILTERS, return_sequences=False, kernel_initializer=glorotInit,\n                                  recurrent_initializer=glorotInit))(embed3)\n#     atten_3 = Attention(2)(gru3)\n#     max_pool3 = GlobalMaxPooling1D()(gru3)    \n#     avg_pool3 = GlobalAveragePooling1D()(gru3)\n#     conc3 = concatenate([atten_3, max_pool3, avg_pool3])    \n\n    ## OUTPUT\n    dense = Dense(32, activation=\"relu\", kernel_initializer=glorotInit)(gru3)\n    drop2 = Dropout(0.1)(dense)\n    output = Dense(1, activation=\"sigmoid\")(drop2)      \n    \n    model = Model(input3, output)\n    #model.compile(loss='binary_crossentropy', optimizer=\"rmsprop\", metrics=['acc', f1])\n    model.compile(loss='binary_crossentropy', optimizer=AdamW(lr=LR, weight_decay=0.), metrics=[\"acc\", f1])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ca4d91b1dcec29c7f7b999aa94f5ab70fae3aa9a"},"cell_type":"code","source":"# def model_lstm_atten_bi():\n       \n#     embedding_layer = Embedding(NUM_WORDS,\n#                                 EMBEDDING_DIM,\n#                                 weights=[embedding_matrix],\n#                                 input_length=MAX_LEN,\n#                                 trainable=False)\n    \n#     input1 = Input(shape=(MAX_LEN,))\n#     embed = embedding_layer(input1)\n#     drop1 = SpatialDropout1D(0.2)\n#     gru1 = Bidirectional(CuDNNGRU(NUM_FILTERS, return_sequences=True, kernel_initializer=glorotInit,\n#                                recurrent_initializer=glorotInit))(embed)    \n# #    batch_norm1 = BatchNormalization(momentum=0.2, center=False, scale=False)(gru1)\n    \n#     gru2 = Bidirectional(CuDNNGRU(NUM_FILTERS, return_sequences=True, kernel_initializer=glorotInit,\n#                                recurrent_initializer=glorotInit))(gru1)    \n# #    batch_norm2 = BatchNormalization(momentum=0.2, center=False, scale=False)(gru2)\n    \n#     atten_1 = Attention(MAX_LEN)(gru1) # skip connect\n#     atten_2 = Attention(MAX_LEN)(gru2)\n#     avg_pool = GlobalAveragePooling1D()(gru2)\n#     max_pool = GlobalMaxPooling1D()(gru2)\n    \n#     conc = concatenate([atten_1, atten_2, avg_pool, max_pool])\n#     dense1 = Dense(32, activation=\"relu\", kernel_initializer=glorotInit)(conc)\n#     drop1 = Dropout(0.1)(dense1)\n#     outp = Dense(1, activation=\"sigmoid\")(drop1)    \n\n#     model = Model(inputs=input1, outputs=outp)\n#     #model.compile(loss='binary_crossentropy', optimizer=\"rmsprop\", metrics=[\"acc\", f1])\n#     model.compile(loss='binary_crossentropy', optimizer=AdamW(lr=LR, weight_decay=WD), metrics=[\"acc\", f1])\n    \n#     return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"944f5a4589ef2a23eb58e358e3abaabaf5b5b9dc"},"cell_type":"code","source":"# def model_lstm_test():\n#     maxlen =  MAX_LEN\n#     max_features = NUM_FILTERS\n    \n#     inp = Input(shape=(maxlen,))\n#     x = Embedding(NUM_WORDS, 300, weights=[embedding_matrix], trainable=False)(inp)\n#     x = SpatialDropout1D(0.2)(x)\n#     x = Bidirectional(CuDNNLSTM(40, return_sequences=True))(x)\n#     y = Bidirectional(CuDNNLSTM(40, return_sequences=True))(x)\n    \n#     atten_1 = Attention(maxlen)(x) # skip connect\n#     atten_2 = Attention(maxlen)(y)\n#     avg_pool = GlobalAveragePooling1D()(y)\n#     max_pool = GlobalMaxPooling1D()(y)\n    \n#     conc = concatenate([atten_1, atten_2, avg_pool, max_pool])\n#     conc = Dense(32, activation=\"relu\")(conc)\n#     conc = Dropout(0.1)(conc)\n#     outp = Dense(1, activation=\"sigmoid\")(conc)    \n\n#     model = Model(inputs=inp, outputs=outp)\n#     model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=[\"acc\", f1])\n    \n#     return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"690eebda00f0d0a852c1565aa4ad40695de50b84"},"cell_type":"code","source":"# clr = CyclicLR(base_lr=LR, max_lr=LR_MAX,\n#                step_size=STEP_SIZE_CLR, mode='exp_range',\n#                gamma=0.99994)\nclr = CyclicLR(base_lr=0.001, max_lr=0.004,\n               step_size=300., mode='exp_range',\n               gamma=0.99994)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f04076c4eacb49aa36820e2ebebb251a8cf79109"},"cell_type":"code","source":"# https://www.kaggle.com/strideradu/word2vec-and-gensim-go-go-go\ndef train_pred(model, train_X, train_y, val_X, val_y, test_data, callbacks=None):\n    st = time.time()      \n    model.fit(np.array(train_X), train_y, batch_size=BATCH_SIZE, epochs=NUM_EPOCH, validation_data=(np.array(val_X), val_y), \n              callbacks = callbacks, verbose=2)\n    \n    pred_val_y = model.predict([val_X], batch_size=1024, verbose=0)\n\n    best_thresh = threshold_search(val_y, pred_val_y)\n    \n    print(\"\\tVal F1 Score: {:.4f}\\tThresh: {:.2f}\".format(best_thresh[\"f1\"], best_thresh[\"threshold\"]))\n    best_score = best_thresh[\"f1\"]\n    pred_test_y = model.predict(test_data, batch_size=1024, verbose=0)\n    print(\"Training time was: \" + str(time.time() - st))\n    print('=' * 60)\n    \n    return pred_val_y, pred_test_y, best_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9a6fccba86f2776c1f99ecf8e37bdcf040b88993","scrolled":true},"cell_type":"code","source":"# Normal Bi-LSTM\n\n# train_meta = np.zeros(y_train.shape)\n# test_meta = np.zeros(len(X_test))\n\n# splits = list(StratifiedKFold(n_splits=4, shuffle=True, random_state=RANDOM_STATE).split(X_train, y_train))\n\n# for idx, (train_idx, valid_idx) in enumerate(splits):\n#     X_train_tmp = X_train[train_idx]\n#     y_train_tmp = y_train[train_idx]\n#     X_val_tmp =  X_train[valid_idx]\n#     y_val_tmp = y_train[valid_idx]\n    \n#     #model = srnn_model()\n#     #model = model_lstm_atten_bi()\n#     model = model_lstm_test()\n#     pred_val_y, pred_test_y, best_score = train_pred(model, X_train_tmp, y_train_tmp, X_val_tmp, y_val_tmp, X_test, \n#                                                      callbacks=[clr])\n    \n#     train_meta[valid_idx] = pred_val_y.reshape(-1)\n#     test_meta += pred_test_y.reshape(-1) / len(splits)\n\n#     del(X_train_tmp)\n#     del(y_train_tmp)\n#     del(X_val_tmp)\n#     del(y_val_tmp)\n#     gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7c545f61f44c3d2b8bc3cebe905b94baa72f9292","scrolled":true},"cell_type":"code","source":"# Sliced RNN with Attention\n\ntrain_meta = np.zeros(y_train.shape)\ntest_meta = np.zeros(len(x_test_padded_seqs_split))\n\nsplits = list(StratifiedKFold(n_splits=4, shuffle=True, random_state=RANDOM_STATE).split(x_train_padded_seqs_split, y_train))\n\nfor idx, (train_idx, valid_idx) in enumerate(splits):\n    X_train_tmp = x_train_padded_seqs_split[train_idx]\n    y_train_tmp = y_train[train_idx]\n    X_val_tmp =  x_train_padded_seqs_split[valid_idx]\n    y_val_tmp = y_train[valid_idx]\n    \n    model = srnn_model()\n    #model = model_lstm_atten_bi()\n    #model = model_lstm_test()\n    pred_val_y, pred_test_y, best_score = train_pred(model, X_train_tmp, y_train_tmp, X_val_tmp, y_val_tmp, x_test_padded_seqs_split, \n                                                     callbacks=[clr])\n    \n    train_meta[valid_idx] = pred_val_y.reshape(-1)\n    test_meta += pred_test_y.reshape(-1) / len(splits)\n\n    del(X_train_tmp)\n    del(y_train_tmp)\n    del(X_val_tmp)\n    del(y_val_tmp)\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"46727204154d58fd1e0fbe4006718aa3947df8c0"},"cell_type":"markdown","source":"# Prediction"},{"metadata":{"trusted":true,"_uuid":"524d4ef5518c4969f26ac15ccc39dbf2fc9d8f65"},"cell_type":"code","source":"search_result = threshold_search(y_train, train_meta)\nprint(search_result)\n\nsub = pd.read_csv('../input/sample_submission.csv')\nsub.prediction = test_meta > search_result['threshold']\nsub.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"830d167b93a76e24832d727511c845a1c265e315"},"cell_type":"code","source":"(time.time() - startTimePt2) / 60\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dc1d4f2cc024231963ab551da2b8b1fb50719a8a","scrolled":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4e68fbd01fd6f79703cfb6f0a924ec61f3d4a886"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}