├── data ├── test_test.pkl ├── big_train_main.pkl ├── test_oneshot_a.pkl ├── test_oneshot_b.pkl ├── test_oneshot_c.pkl ├── train_oneshot_a.pkl ├── train_oneshot_b.pkl ├── train_oneshot_c.pkl └── train_oneshot_d.pkl ├── README.md └── code └── example-MovieLens.ipynb /data/test_test.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/test_test.pkl -------------------------------------------------------------------------------- /data/big_train_main.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/big_train_main.pkl -------------------------------------------------------------------------------- /data/test_oneshot_a.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/test_oneshot_a.pkl -------------------------------------------------------------------------------- /data/test_oneshot_b.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/test_oneshot_b.pkl -------------------------------------------------------------------------------- /data/test_oneshot_c.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/test_oneshot_c.pkl -------------------------------------------------------------------------------- /data/train_oneshot_a.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/train_oneshot_a.pkl -------------------------------------------------------------------------------- /data/train_oneshot_b.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/train_oneshot_b.pkl -------------------------------------------------------------------------------- /data/train_oneshot_c.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/train_oneshot_c.pkl -------------------------------------------------------------------------------- /data/train_oneshot_d.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Feiyang/MetaEmbedding/HEAD/data/train_oneshot_d.pkl -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MetaEmbedding 2 | Codes for our SIGIR-2019 paper: 3 | 4 | **[Warm Up Cold-start Advertisements: Improving CTR Predictions via Learning to Learn ID Embeddings](https://dl.acm.org/citation.cfm?id=3331268)** 5 | 6 | This repo includes an example for training Meta-Embedding upon a deepFM model on the binarized MovieLens-1M dataset. The dataset is preprocessed and splitted already. 7 | 8 | Requirements: Python 3 and TensorFlow. 9 | 10 | ### Bibtex 11 | 12 | ``` 13 | @inproceedings{pan2019warm, 14 | author = {Pan, Feiyang and Li, Shuokai and Ao, Xiang and Tang, Pingzhong and He, Qing}, 15 | title = {Warm Up Cold-start Advertisements: Improving CTR Predictions via Learning to Learn ID Embeddings}, 16 | booktitle = {Proceedings of the 42Nd International ACM SIGIR Conference on Research and Development in Information Retrieval}, 17 | series = {SIGIR'19}, 18 | year = {2019}, 19 | isbn = {978-1-4503-6172-9}, 20 | location = {Paris, France}, 21 | pages = {695--704}, 22 | numpages = {10}, 23 | url = {http://doi.acm.org/10.1145/3331184.3331268}, 24 | doi = {10.1145/3331184.3331268}, 25 | acmid = {3331268}, 26 | publisher = {ACM}, 27 | address = {New York, NY, USA}, 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /code/example-MovieLens.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2020-03-31T15:38:21.707234Z", 9 | "start_time": "2020-03-31T15:38:18.947959Z" 10 | } 11 | }, 12 | "outputs": [ 13 | { 14 | "name": "stderr", 15 | "output_type": "stream", 16 | "text": [ 17 | "Using TensorFlow backend.\n" 18 | ] 19 | } 20 | ], 21 | "source": [ 22 | "import numpy as np\n", 23 | "import pandas as pd\n", 24 | "from sklearn.metrics import log_loss\n", 25 | "from sklearn.metrics import roc_auc_score\n", 26 | "from tqdm import tqdm\n", 27 | "import os, pickle\n", 28 | "\n", 29 | "# specify the GPU device\n", 30 | "# os.environ['CUDA_DEVICE_ORDER']=\"PCI_BUS_ID\"\n", 31 | "# os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n", 32 | "\n", 33 | "import tensorflow as tf\n", 34 | "from tensorflow.layers import Dense\n", 35 | "import keras\n", 36 | "from keras.preprocessing.sequence import pad_sequences" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": { 43 | "ExecuteTime": { 44 | "end_time": "2020-03-31T15:38:21.715617Z", 45 | "start_time": "2020-03-31T15:38:21.709757Z" 46 | } 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "'''\n", 51 | "Config\n", 52 | "'''\n", 53 | "# batch size per iteration\n", 54 | "BATCHSIZE = 200\n", 55 | "# mini-batch size for few-shot learning\n", 56 | "MINIBATCHSIZE = 20 \n", 57 | "# learning rate\n", 58 | "LR = 1e-3 \n", 59 | "# coefficient to balance `cold-start' and `warm-up'\n", 60 | "ALPHA = 0.1\n", 61 | "# length of embedding vectors\n", 62 | "EMB_SIZE = 128\n", 63 | "# model\n", 64 | "MODEL = 'deepFM'\n", 65 | "# log file\n", 66 | "LOG = \"logs/{}.csv\".format(MODEL)\n", 67 | "# path to save the model\n", 68 | "saver_path =\"saver/model-\"+LOG.split(\"/\")[-1][:-4]" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 3, 74 | "metadata": { 75 | "ExecuteTime": { 76 | "end_time": "2020-03-31T15:38:21.725157Z", 77 | "start_time": "2020-03-31T15:38:21.718241Z" 78 | } 79 | }, 80 | "outputs": [], 81 | "source": [ 82 | "def read_pkl(path):\n", 83 | " with open(path, \"rb\") as f:\n", 84 | " t = pickle.load(f)\n", 85 | " return t" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 4, 91 | "metadata": { 92 | "ExecuteTime": { 93 | "end_time": "2020-03-31T15:38:29.003436Z", 94 | "start_time": "2020-03-31T15:38:21.727628Z" 95 | }, 96 | "code_folding": [] 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "# training data of big ads\n", 101 | "train = read_pkl(\"../data/big_train_main.pkl\")\n", 102 | "# some pre-processing\n", 103 | "num_words_dict = {\n", 104 | " 'MovieID': 4000,\n", 105 | " 'UserID': 6050,\n", 106 | " 'Age': 7,\n", 107 | " 'Gender': 2,\n", 108 | " 'Occupation': 21,\n", 109 | " 'Year': 83,\n", 110 | "}\n", 111 | "ID_col = 'MovieID'\n", 112 | "item_col = ['Year']\n", 113 | "context_col = ['Age', 'Gender', 'Occupation', 'UserID']\n", 114 | "train_y = train['y']\n", 115 | "train_x = train[[ID_col]+item_col+context_col]\n", 116 | "train_t = pad_sequences(train.Title, maxlen=8)\n", 117 | "train_g = pad_sequences(train.Genres, maxlen=4)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 5, 123 | "metadata": { 124 | "ExecuteTime": { 125 | "end_time": "2020-03-31T15:38:30.925695Z", 126 | "start_time": "2020-03-31T15:38:29.005891Z" 127 | } 128 | }, 129 | "outputs": [], 130 | "source": [ 131 | "# few-shot data for the small ads\n", 132 | "test_a = read_pkl(\"../data/test_oneshot_a.pkl\")\n", 133 | "test_b = read_pkl(\"../data/test_oneshot_b.pkl\")\n", 134 | "test_c = read_pkl(\"../data/test_oneshot_c.pkl\")\n", 135 | "test_test = read_pkl(\"../data/test_test.pkl\")\n", 136 | "\n", 137 | "test_x_a = test_a[[ID_col]+item_col+context_col]\n", 138 | "test_y_a = test_a['y'].values\n", 139 | "test_t_a = pad_sequences(test_a.Title, maxlen=8)\n", 140 | "test_g_a = pad_sequences(test_a.Genres, maxlen=4)\n", 141 | "\n", 142 | "test_x_b = test_b[[ID_col]+item_col+context_col]\n", 143 | "test_y_b = test_b['y'].values\n", 144 | "test_t_b = pad_sequences(test_b.Title, maxlen=8)\n", 145 | "test_g_b = pad_sequences(test_b.Genres, maxlen=4)\n", 146 | "\n", 147 | "test_x_c = test_c[[ID_col]+item_col+context_col]\n", 148 | "test_y_c = test_c['y'].values\n", 149 | "test_t_c = pad_sequences(test_c.Title, maxlen=8)\n", 150 | "test_g_c = pad_sequences(test_c.Genres, maxlen=4)\n", 151 | "\n", 152 | "test_x_test = test_test[[ID_col]+item_col+context_col]\n", 153 | "test_y_test = test_test['y'].values\n", 154 | "test_t_test = pad_sequences(test_test.Title, maxlen=8)\n", 155 | "test_g_test = pad_sequences(test_test.Genres, maxlen=4)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 6, 161 | "metadata": { 162 | "ExecuteTime": { 163 | "end_time": "2020-03-31T15:38:30.972485Z", 164 | "start_time": "2020-03-31T15:38:30.927469Z" 165 | }, 166 | "code_folding": [ 167 | 82 168 | ] 169 | }, 170 | "outputs": [], 171 | "source": [ 172 | "class Meta_Model(object):\n", 173 | " def __init__(self, ID_col, item_col, context_col, nb_words, model='FM',\n", 174 | " emb_size=128, alpha=0.1,\n", 175 | " warm_lr=1e-3, cold_lr=1e-4, ME_lr=1e-3):\n", 176 | " \"\"\"\n", 177 | " ID_col: string, the column name of the item ID\n", 178 | " item_col: list, the columns of item features\n", 179 | " context_col: list, the columns of other features\n", 180 | " nb_words: dict, nb of words in each of these columns\n", 181 | " \"\"\"\n", 182 | " columns = [ID_col] + item_col + context_col\n", 183 | " def get_embeddings():\n", 184 | " inputs, tables = {}, []\n", 185 | " item_embs, other_embs = [], []\n", 186 | " for col in columns:\n", 187 | " inputs[col] = tf.placeholder(tf.int32, [None])\n", 188 | " table = tf.get_variable(\n", 189 | " \"table_{}\".format(col), [nb_words[col], emb_size],\n", 190 | " initializer=tf.random_normal_initializer(stddev=0.01))\n", 191 | " emb = tf.nn.embedding_lookup(table, inputs[col])\n", 192 | " if col==ID_col:\n", 193 | " ID_emb = emb\n", 194 | " ID_table = table\n", 195 | " elif col in item_col:\n", 196 | " item_embs.append(emb)\n", 197 | " else:\n", 198 | " other_embs.append(emb)\n", 199 | "\n", 200 | " inputs[\"title\"] = tf.placeholder(tf.int32, [None, 8])\n", 201 | " inputs[\"genres\"] = tf.placeholder(tf.int32, [None, 4])\n", 202 | "\n", 203 | " title_emb = tf.contrib.layers.embed_sequence(\n", 204 | " inputs[\"title\"], 20001, emb_size, scope=\"word_emb\")\n", 205 | " genre_emb = tf.contrib.layers.embed_sequence(\n", 206 | " inputs[\"genres\"], 21, emb_size, scope=\"genre_table\")\n", 207 | " item_embs.append(tf.reduce_mean(title_emb, axis=1))\n", 208 | " item_embs.append(tf.reduce_mean(genre_emb, axis=1))\n", 209 | " \n", 210 | " return inputs, ID_emb, item_embs, other_embs, ID_table\n", 211 | " \n", 212 | " def generate_meta_emb(item_embs):\n", 213 | " \"\"\"\n", 214 | " This is the simplest architecture of the embedding generator,\n", 215 | " with only a dense layer.\n", 216 | " You can customize it if you want have a stronger performance, \n", 217 | " for example, you can add an l2 regularization term or alter \n", 218 | " the pooling layer. \n", 219 | " \"\"\"\n", 220 | " embs = tf.stop_gradient(tf.stack(item_embs, 1))\n", 221 | " item_h = tf.layers.flatten(embs)\n", 222 | " emb_pred_Dense = tf.layers.Dense(\n", 223 | " emb_size, activation=tf.nn.tanh, use_bias=False,\n", 224 | " name='emb_predictor') \n", 225 | " emb_pred = emb_pred_Dense(item_h) / 5.\n", 226 | " ME_vars = emb_pred_Dense.trainable_variables\n", 227 | " return emb_pred, ME_vars\n", 228 | "\n", 229 | " def get_yhat_deepFM(ID_emb, item_embs, other_embs, **kwargs):\n", 230 | " embeddings = [ID_emb] + item_embs + other_embs\n", 231 | " sum_of_emb = tf.add_n(embeddings)\n", 232 | " diff_of_emb = [sum_of_emb - x for x in embeddings]\n", 233 | " dot_of_emb = [tf.reduce_sum(embeddings[i]*diff_of_emb[i], \n", 234 | " axis=1, keepdims=True) \n", 235 | " for i in range(len(columns))]\n", 236 | " h = tf.concat(dot_of_emb, 1)\n", 237 | " h2 = tf.concat(embeddings, 1)\n", 238 | " for i in range(2):\n", 239 | " h2 = tf.nn.relu(tf.layers.dense(h2, emb_size, name='deep-{}'.format(i)))\n", 240 | " h = tf.concat([h,h2], 1)\n", 241 | " y = tf.nn.sigmoid(tf.layers.dense(h, 1, name='out'))\n", 242 | " return y\n", 243 | " def get_yhat_PNN(ID_emb, item_embs, other_embs, **kwargs):\n", 244 | " embeddings = [ID_emb] + item_embs + other_embs\n", 245 | " sum_of_emb = tf.add_n(embeddings)\n", 246 | " diff_of_emb = [sum_of_emb - x for x in embeddings]\n", 247 | " dot_of_emb = [tf.reduce_sum(embeddings[i]*diff_of_emb[i], \n", 248 | " axis=1, keepdims=True)\n", 249 | " for i in range(len(columns))]\n", 250 | " dots = tf.concat(dot_of_emb, 1)\n", 251 | " h2 = tf.concat(embeddings, 1)\n", 252 | " h = tf.concat([dots,h2], 1)\n", 253 | " w = tf.get_variable('MLP_1/kernel', shape=(h.shape[1],emb_size))\n", 254 | " b = tf.get_variable('MLP_1/bias', shape=(emb_size,), \n", 255 | " initializer=tf.initializers.zeros)\n", 256 | " h = tf.nn.relu(tf.matmul(h,w)+b)\n", 257 | " w = tf.get_variable('MLP_2/kernel', shape=(h.shape[1],1))\n", 258 | " b = tf.get_variable('MLP_2/bias', shape=(1,), \n", 259 | " initializer=tf.initializers.constant(0.))\n", 260 | " y = tf.nn.sigmoid(tf.matmul(h,w)+b)\n", 261 | " return y\n", 262 | " '''\n", 263 | " *CHOOSE THE BASE MODEL HERE*\n", 264 | " '''\n", 265 | " get_yhat = {\n", 266 | " \"PNN\": get_yhat_PNN, \n", 267 | " \"deepFM\": get_yhat_deepFM\n", 268 | " }[model]\n", 269 | " \n", 270 | " with tf.variable_scope(\"model\"):\n", 271 | " # build the base model\n", 272 | " inputs, ID_emb, item_embs, other_embs, ID_table = get_embeddings()\n", 273 | " label = tf.placeholder(tf.float32, [None, 1])\n", 274 | " # outputs and losses of the base model\n", 275 | " yhat = get_yhat(ID_emb, item_embs, other_embs)\n", 276 | " warm_loss = tf.losses.log_loss(label, yhat)\n", 277 | " # Meta-Embedding: build the embedding generator\n", 278 | " meta_ID_emb, ME_vars = generate_meta_emb(item_embs)\n", 279 | "\n", 280 | " with tf.variable_scope(\"model\", reuse=True):\n", 281 | " # Meta-Embedding: step 1, cold-start, \n", 282 | " # use the generated meta-embedding to make predictions\n", 283 | " # and calculate the cold-start loss_a\n", 284 | " cold_yhat_a = get_yhat(meta_ID_emb, item_embs, other_embs)\n", 285 | " cold_loss_a = tf.losses.log_loss(label, cold_yhat_a)\n", 286 | " # Meta-Embedding: step 2, apply gradient descent once\n", 287 | " # get the adapted embedding\n", 288 | " cold_emb_grads = tf.gradients(cold_loss_a, meta_ID_emb)[0]\n", 289 | " meta_ID_emb_new = meta_ID_emb - cold_lr * cold_emb_grads\n", 290 | " # Meta-Embedding: step 3, \n", 291 | " # use the adapted embedding to make prediction on another mini-batch \n", 292 | " # and calculate the warm-up loss_b\n", 293 | " inputs_b, _, item_embs_b, other_embs_b, _ = get_embeddings()\n", 294 | " label_b = tf.placeholder(tf.float32, [None, 1])\n", 295 | " cold_yhat_b = get_yhat(meta_ID_emb_new, item_embs_b, other_embs_b)\n", 296 | " cold_loss_b = tf.losses.log_loss(label_b, cold_yhat_b) \n", 297 | " \n", 298 | " # build the optimizer and update op for the original model\n", 299 | " warm_optimizer = tf.train.AdamOptimizer(warm_lr)\n", 300 | " warm_update_op = warm_optimizer.minimize(warm_loss)\n", 301 | " warm_update_emb_op = warm_optimizer.minimize(warm_loss, var_list=[ID_table])\n", 302 | " # build the optimizer and update op for meta-embedding\n", 303 | " # Meta-Embedding: step 4, calculate the final meta-loss\n", 304 | " ME_loss = cold_loss_a * alpha + cold_loss_b * (1-alpha)\n", 305 | " ME_optimizer = tf.train.AdamOptimizer(ME_lr)\n", 306 | " ME_update_op = ME_optimizer.minimize(ME_loss, var_list=ME_vars)\n", 307 | " \n", 308 | " ID_table_new = tf.placeholder(tf.float32, ID_table.shape)\n", 309 | " ME_assign_op = tf.assign(ID_table, ID_table_new)\n", 310 | " \n", 311 | " def predict_warm(sess, X, Title, Genres):\n", 312 | " feed_dict = {inputs[col]: X[col] for col in columns}\n", 313 | " feed_dict = {inputs[\"title\"]: Title,\n", 314 | " inputs[\"genres\"]: Genres,\n", 315 | " **feed_dict}\n", 316 | " return sess.run(yhat, feed_dict)\n", 317 | " def predict_ME(sess, X, Title, Genres):\n", 318 | " feed_dict = {inputs[col]: X[col] for col in columns}\n", 319 | " feed_dict = {inputs[\"title\"]: Title,\n", 320 | " inputs[\"genres\"]: Genres,\n", 321 | " **feed_dict}\n", 322 | " return sess.run(cold_yhat_a, feed_dict)\n", 323 | " def get_meta_embedding(sess, X, Title, Genres):\n", 324 | " feed_dict = {inputs[col]: X[col] for col in columns}\n", 325 | " feed_dict = {inputs[\"title\"]: Title,\n", 326 | " inputs[\"genres\"]: Genres,\n", 327 | " **feed_dict}\n", 328 | " return sess.run(meta_ID_emb, feed_dict)\n", 329 | " def assign_meta_embedding(sess, ID, emb):\n", 330 | " # take the embedding matrix\n", 331 | " table = sess.run(ID_table)\n", 332 | " # replace the ID^th row by the new embedding\n", 333 | " table[ID, :] = emb\n", 334 | " return sess.run(ME_assign_op, feed_dict={ID_table_new: table})\n", 335 | " def train_warm(sess, X, Title, Genres, y, embedding_only=False):\n", 336 | " # original training on batch\n", 337 | " feed_dict = {inputs[col]: X[col] for col in columns}\n", 338 | " feed_dict = {inputs[\"title\"]: Title,\n", 339 | " inputs[\"genres\"]: Genres,\n", 340 | " **feed_dict}\n", 341 | " feed_dict[label] = y.reshape((-1,1))\n", 342 | " return sess.run([\n", 343 | " warm_loss, warm_update_emb_op if embedding_only else warm_update_op \n", 344 | " ], feed_dict=feed_dict)\n", 345 | " def train_ME(sess, X, Title, Genres, y, \n", 346 | " X_b, Title_b, Genres_b, y_b):\n", 347 | " # train the embedding generator\n", 348 | " feed_dict = {inputs[col]: X[col] for col in columns}\n", 349 | " feed_dict = {inputs[\"title\"]: Title,\n", 350 | " inputs[\"genres\"]: Genres,\n", 351 | " **feed_dict}\n", 352 | " feed_dict[label] = y.reshape((-1,1))\n", 353 | " feed_dict_b = {inputs_b[col]: X_b[col] for col in columns}\n", 354 | " feed_dict_b = {inputs_b[\"title\"]: Title_b,\n", 355 | " inputs_b[\"genres\"]: Genres_b,\n", 356 | " **feed_dict_b}\n", 357 | " feed_dict_b[label_b] = y_b.reshape((-1,1))\n", 358 | " return sess.run([\n", 359 | " cold_loss_a, cold_loss_b, ME_update_op\n", 360 | " ], feed_dict={**feed_dict, **feed_dict_b})\n", 361 | " self.predict_warm = predict_warm\n", 362 | " self.predict_ME = predict_ME\n", 363 | " self.train_warm = train_warm\n", 364 | " self.train_ME = train_ME\n", 365 | " self.get_meta_embedding = get_meta_embedding\n", 366 | " self.assign_meta_embedding = assign_meta_embedding" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": 7, 372 | "metadata": { 373 | "ExecuteTime": { 374 | "end_time": "2020-03-31T15:38:36.053130Z", 375 | "start_time": "2020-03-31T15:38:30.974006Z" 376 | }, 377 | "scrolled": false 378 | }, 379 | "outputs": [ 380 | { 381 | "name": "stdout", 382 | "output_type": "stream", 383 | "text": [ 384 | "WARNING:tensorflow:\n", 385 | "The TensorFlow contrib module will not be included in TensorFlow 2.0.\n", 386 | "For more information, please see:\n", 387 | " * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n", 388 | " * https://github.com/tensorflow/addons\n", 389 | " * https://github.com/tensorflow/io (for I/O related ops)\n", 390 | "If you depend on functionality not listed there, please file an issue.\n", 391 | "\n", 392 | "WARNING:tensorflow:From /home/panfy/anaconda3/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", 393 | "Instructions for updating:\n", 394 | "Call initializer instance with the dtype argument instead of passing it to the constructor\n", 395 | "WARNING:tensorflow:From :68: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", 396 | "Instructions for updating:\n", 397 | "Use keras.layers.dense instead.\n", 398 | "WARNING:tensorflow:From /home/panfy/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/losses/losses_impl.py:121: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", 399 | "Instructions for updating:\n", 400 | "Use tf.where in 2.0, which has the same broadcast rule as np.where\n", 401 | "WARNING:tensorflow:From :50: flatten (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n", 402 | "Instructions for updating:\n", 403 | "Use keras.layers.flatten instead.\n" 404 | ] 405 | } 406 | ], 407 | "source": [ 408 | "model = Meta_Model(ID_col, item_col, context_col, num_words_dict, model=MODEL,\n", 409 | " emb_size=EMB_SIZE, alpha=ALPHA,\n", 410 | " warm_lr=LR, cold_lr=LR/10., ME_lr=LR)" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 8, 416 | "metadata": { 417 | "ExecuteTime": { 418 | "end_time": "2020-03-31T15:38:36.065886Z", 419 | "start_time": "2020-03-31T15:38:36.055626Z" 420 | }, 421 | "code_folding": [ 422 | 0 423 | ] 424 | }, 425 | "outputs": [], 426 | "source": [ 427 | "def predict_on_batch(sess, predict_func, test_x, test_t, test_g, batchsize=800):\n", 428 | " n_samples_test = test_x.shape[0]\n", 429 | " n_batch_test = n_samples_test//batchsize\n", 430 | " test_pred = np.zeros(n_samples_test)\n", 431 | " for i_batch in range(n_batch_test):\n", 432 | " batch_x = test_x.iloc[i_batch*batchsize:(i_batch+1)*batchsize]\n", 433 | " batch_t = test_t[i_batch*batchsize:(i_batch+1)*batchsize]\n", 434 | " batch_g = test_g[i_batch*batchsize:(i_batch+1)*batchsize]\n", 435 | " _pred = predict_func(sess, batch_x, batch_t, batch_g)\n", 436 | " test_pred[i_batch*batchsize:(i_batch+1)*batchsize] = _pred.reshape(-1)\n", 437 | " if n_batch_test*batchsize=len(batch_x):\n", 852 | " break\n", 853 | " ID = batch_x[ID_col].values[k*minibatchsize]\n", 854 | " embeddings = model.get_meta_embedding(\n", 855 | " sess, batch_x[k*minibatchsize:(k+1)*minibatchsize],\n", 856 | " batch_t[k*minibatchsize:(k+1)*minibatchsize],\n", 857 | " batch_g[k*minibatchsize:(k+1)*minibatchsize],\n", 858 | " )\n", 859 | " emb = embeddings.mean(0)\n", 860 | " model.assign_meta_embedding(sess, ID, emb)\n", 861 | " model.train_warm(sess, \n", 862 | " batch_x, batch_t, batch_g, batch_y, \n", 863 | " embedding_only=True)\n", 864 | "test_pred_test = predict_on_batch(sess, model.predict_warm, \n", 865 | " test_x_test, test_t_test, test_g_test)\n", 866 | "logloss_ME_batcha = test_loss_test = log_loss(test_y_test, test_pred_test)\n", 867 | "print(\"[Meta-Embedding]\\n\\ttest-test loss:\\t{:.4f}, improvement: {:.2%}\".format(\n", 868 | " test_loss_test, 1-test_loss_test/logloss_base_cold))\n", 869 | "auc_ME_batcha = test_auc_test = roc_auc_score(test_y_test, test_pred_test)\n", 870 | "print(\"[Meta-Embedding]\\n\\ttest-test auc:\\t{:.4f}, improvement: {:.2%}\".format(\n", 871 | " test_auc_test, test_auc_test/auc_base_cold-1))\n", 872 | "\n", 873 | "for i in tqdm(range(int(np.ceil(test_n_ID/batch_n_ID)))):\n", 874 | " batch_x = test_x_b[i*batchsize:(i+1)*batchsize]\n", 875 | " batch_t = test_t_b[i*batchsize:(i+1)*batchsize]\n", 876 | " batch_g = test_g_b[i*batchsize:(i+1)*batchsize]\n", 877 | " batch_y = test_y_b[i*batchsize:(i+1)*batchsize]\n", 878 | " model.train_warm(sess, batch_x, batch_t, batch_g, batch_y, \n", 879 | " embedding_only=True)\n", 880 | "test_pred_test = predict_on_batch(sess, model.predict_warm, \n", 881 | " test_x_test, test_t_test, test_g_test)\n", 882 | "logloss_ME_batchb = test_loss_test = log_loss(test_y_test, test_pred_test)\n", 883 | "print(\"[Meta-Embedding]\\n\\ttest-test loss:\\t{:.4f}, improvement: {:.2%}\".format(\n", 884 | " test_loss_test, 1-test_loss_test/logloss_base_cold))\n", 885 | "auc_ME_batchb = test_auc_test = roc_auc_score(test_y_test, test_pred_test)\n", 886 | "print(\"[Meta-Embedding]\\n\\ttest-test auc:\\t{:.4f}, improvement: {:.2%}\".format(\n", 887 | " test_auc_test, test_auc_test/auc_base_cold-1))\n", 888 | "for i in tqdm(range(int(np.ceil(test_n_ID/batch_n_ID)))):\n", 889 | " batch_x = test_x_c[i*batchsize:(i+1)*batchsize]\n", 890 | " batch_t = test_t_c[i*batchsize:(i+1)*batchsize]\n", 891 | " batch_g = test_g_c[i*batchsize:(i+1)*batchsize]\n", 892 | " batch_y = test_y_c[i*batchsize:(i+1)*batchsize]\n", 893 | " model.train_warm(sess, batch_x, batch_t, batch_g, batch_y, \n", 894 | " embedding_only=True)\n", 895 | "test_pred_test = predict_on_batch(sess, model.predict_warm, \n", 896 | " test_x_test, test_t_test, test_g_test)\n", 897 | "logloss_ME_batchc = test_loss_test = log_loss(test_y_test, test_pred_test)\n", 898 | "print(\"[Meta-Embedding]\\n\\ttest-test loss:\\t{:.4f}, improvement: {:.2%}\".format(\n", 899 | " test_loss_test, 1-test_loss_test/logloss_base_cold))\n", 900 | "auc_ME_batchc = test_auc_test = roc_auc_score(test_y_test, test_pred_test)\n", 901 | "print(\"[Meta-Embedding]\\n\\ttest-test auc:\\t{:.4f}, improvement: {:.2%}\".format(\n", 902 | " test_auc_test, test_auc_test/auc_base_cold-1))" 903 | ] 904 | }, 905 | { 906 | "cell_type": "code", 907 | "execution_count": 13, 908 | "metadata": { 909 | "ExecuteTime": { 910 | "end_time": "2020-03-31T15:39:24.037736Z", 911 | "start_time": "2020-03-31T15:39:24.032364Z" 912 | } 913 | }, 914 | "outputs": [], 915 | "source": [ 916 | "# write the scores into file.\n", 917 | "res = [logloss_base_cold, logloss_ME_cold, \n", 918 | " logloss_base_batcha, logloss_ME_batcha, \n", 919 | " logloss_base_batchb, logloss_ME_batchb, \n", 920 | " logloss_base_batchc, logloss_ME_batchc, \n", 921 | " auc_base_cold, auc_ME_cold, \n", 922 | " auc_base_batcha, auc_ME_batcha, \n", 923 | " auc_base_batchb, auc_ME_batchb, \n", 924 | " auc_base_batchc, auc_ME_batchc]\n", 925 | "with open(LOG, \"a\") as logfile:\n", 926 | " logfile.writelines(\",\".join([str(x) for x in res])+\"\\n\")" 927 | ] 928 | } 929 | ], 930 | "metadata": { 931 | "kernelspec": { 932 | "display_name": "Python 3", 933 | "language": "python", 934 | "name": "python3" 935 | }, 936 | "language_info": { 937 | "codemirror_mode": { 938 | "name": "ipython", 939 | "version": 3 940 | }, 941 | "file_extension": ".py", 942 | "mimetype": "text/x-python", 943 | "name": "python", 944 | "nbconvert_exporter": "python", 945 | "pygments_lexer": "ipython3", 946 | "version": "3.6.6" 947 | } 948 | }, 949 | "nbformat": 4, 950 | "nbformat_minor": 2 951 | } 952 | --------------------------------------------------------------------------------