{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# default_exp models.dnn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DNNs\n",
    "> Deep Neural Networks (DNNs) based Recommender systems."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Multi_Layer_Perceptron(nn.Module):\n",
    "    def __init__(self, args, num_users, num_items):\n",
    "        super(Multi_Layer_Perceptron, self).__init__()\n",
    "        self.num_users = num_users\n",
    "        self.num_items = num_items\n",
    "        self.factor_num = args.factor_num\n",
    "        self.layers = args.layers\n",
    "\n",
    "        self.embedding_user = nn.Embedding(num_embeddings=self.num_users, embedding_dim=self.factor_num)\n",
    "        self.embedding_item = nn.Embedding(num_embeddings=self.num_items, embedding_dim=self.factor_num)\n",
    "\n",
    "        self.fc_layers = nn.ModuleList()\n",
    "        for idx, (in_size, out_size) in enumerate(zip(self.layers[:-1], self.layers[1:])):\n",
    "            self.fc_layers.append(nn.Linear(in_size, out_size))\n",
    "\n",
    "        self.affine_output = nn.Linear(in_features=self.layers[-1], out_features=1)\n",
    "        self.logistic = nn.Sigmoid()\n",
    "\n",
    "    def forward(self, user_indices, item_indices):\n",
    "        user_embedding = self.embedding_user(user_indices)\n",
    "        item_embedding = self.embedding_item(item_indices)\n",
    "        vector = torch.cat([user_embedding, item_embedding], dim=-1)  # the concat latent vector\n",
    "        for idx, _ in enumerate(range(len(self.fc_layers))):\n",
    "            vector = self.fc_layers[idx](vector)\n",
    "            vector = nn.ReLU()(vector)\n",
    "            # vector = nn.BatchNorm1d()(vector)\n",
    "            # vector = nn.Dropout(p=0.5)(vector)\n",
    "        logits = self.affine_output(vector)\n",
    "        rating = self.logistic(logits)\n",
    "        return rating\n",
    "\n",
    "    def init_weight(self):\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class CollabFNet(nn.Module):\n",
    "    def __init__(self, num_users, num_items, emb_size=100, n_hidden=10):\n",
    "        super(CollabFNet, self).__init__()\n",
    "        self.user_emb = nn.Embedding(num_users, emb_size)\n",
    "        self.item_emb = nn.Embedding(num_items, emb_size)\n",
    "        self.lin1 = nn.Linear(emb_size*2, n_hidden)\n",
    "        self.lin2 = nn.Linear(n_hidden, 1)\n",
    "        self.drop1 = nn.Dropout(0.1)\n",
    "        \n",
    "    def forward(self, u, v):\n",
    "        U = self.user_emb(u)\n",
    "        V = self.item_emb(v)\n",
    "        x = F.relu(torch.cat([U, V], dim=1))\n",
    "        x = self.drop1(x)\n",
    "        x = F.relu(self.lin1(x))\n",
    "        x = self.lin2(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Author: Sparsh A.\n",
      "\n",
      "Last updated: 2021-12-18 06:03:37\n",
      "\n",
      "Compiler    : GCC 7.5.0\n",
      "OS          : Linux\n",
      "Release     : 5.4.104+\n",
      "Machine     : x86_64\n",
      "Processor   : x86_64\n",
      "CPU cores   : 2\n",
      "Architecture: 64bit\n",
      "\n",
      "torch  : 1.10.0+cu111\n",
      "IPython: 5.5.0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "!pip install -q watermark\n",
    "%reload_ext watermark\n",
    "%watermark -a \"Sparsh A.\" -m -iv -u -t -d"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
