{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\n",
    "from tensorflow.keras.models import Model\n",
    "from tensorflow.keras.optimizers import SGD\n",
    "from tensorflow.keras.layers import Input, Dense\n",
    "from tensorflow.keras.initializers import glorot_normal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Classifier:\n",
    "\n",
    "    ###############\n",
    "    # Constructor #\n",
    "    ###############\n",
    "\n",
    "    def __init__(self, num_features, cls_params, seed=0):\n",
    "\n",
    "        # fixed parameters\n",
    "        self.seed = seed\n",
    "        self.weight_init = glorot_normal\n",
    "\n",
    "        # required parameters (more below)\n",
    "        self.num_features = num_features\n",
    "        self.cls = cls_params['cls_name']\n",
    "        self.learning_rate = cls_params['learning_rate']\n",
    "        self.momentum = cls_params['momentum']\n",
    "\n",
    "        # create model\n",
    "        if self.cls == 'logistic_regression':\n",
    "            self.model = self.create_lg()\n",
    "        elif self.cls == 'neural_network':\n",
    "            self.hidden_units = cls_params['hidden_units']\n",
    "            self.hidden_activation_fun = cls_params['hidden_activation_fun']\n",
    "            self.model = self.create_nn()\n",
    "        # self.model.summary()\n",
    "\n",
    "        # prepare model for training\n",
    "        self.model.compile(\n",
    "            optimizer=SGD(lr=self.learning_rate, momentum=self.momentum),\n",
    "            loss='binary_crossentropy',\n",
    "            metrics=['accuracy']\n",
    "        )\n",
    "\n",
    "    #######################\n",
    "    # Logistic regression #\n",
    "    #######################\n",
    "\n",
    "    def create_lg(self):\n",
    "        # Input layer\n",
    "        x_input = Input(shape=(self.num_features,))\n",
    "\n",
    "        # Output layer\n",
    "        y_out = Dense(\n",
    "            units=1,\n",
    "            activation=\"sigmoid\",\n",
    "            use_bias=True,\n",
    "            kernel_initializer=self.weight_init(seed=self.seed),\n",
    "            bias_initializer='zeros'\n",
    "        )(x_input)\n",
    "\n",
    "        # Model\n",
    "        return Model(inputs=x_input, outputs=y_out)\n",
    "\n",
    "    ##################\n",
    "    # Neural network #\n",
    "    ##################\n",
    "\n",
    "    def create_nn(self):\n",
    "        # Input layer\n",
    "        x_input = Input(shape=(self.num_features,))\n",
    "\n",
    "        #  Hidden layer\n",
    "        x = Dense(\n",
    "            units=self.hidden_units,\n",
    "            activation=self.hidden_activation_fun,\n",
    "            use_bias=True,\n",
    "            kernel_initializer=self.weight_init(seed=self.seed),\n",
    "            bias_initializer='zeros'\n",
    "        )(x_input)\n",
    "\n",
    "        # Output layer\n",
    "        y_out = Dense(\n",
    "            units=1,\n",
    "            activation=\"sigmoid\",\n",
    "            use_bias=True,\n",
    "            kernel_initializer=self.weight_init(seed=self.seed),\n",
    "            bias_initializer='zeros'\n",
    "        )(x)\n",
    "\n",
    "        # Model\n",
    "        return Model(inputs=x_input, outputs=y_out)\n",
    "\n",
    "    ####################\n",
    "    # Train classifier #\n",
    "    ####################\n",
    "\n",
    "    def train_cls(self, x, y):\n",
    "        self.model.fit(\n",
    "            x=x,\n",
    "            y=y.astype('int'),  # cast class to integer\n",
    "            epochs=1,\n",
    "            batch_size=1,\n",
    "            verbose=0\n",
    "        )\n"
   ]
  }
 ],
 "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.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
