pytorch-stuff/Numpy_NN.ipynb

295 lines
42 KiB
Plaintext
Executable File

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import sklearn.datasets\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"X,y = sklearn.datasets.make_moons(200, noise = 0.15)\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f0d41ee6e10>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.scatter(X[:,0],X[:,1], c=y)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(200, 2) (200,)\n"
]
}
],
"source": [
"print(X.shape, y.shape)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Hyperparameters\n",
"input_neurons = 2\n",
"output_neurons = 2\n",
"samples = X.shape[0]\n",
"learning_rate = 0.001\n",
"lambda_reg = 0.01\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def retreive(model_dict):\n",
" W1 = model_dict['W1']\n",
" b1 = model_dict['b1']\n",
" W2 = model_dict['W2']\n",
" b2 = model_dict['b2']\n",
" \n",
" return W1, b1, W2, b2\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def forward(x, model_dict):\n",
" W1, b1, W2, b2 = retreive(model_dict)\n",
" z1 = X.dot(W1) + b1\n",
" a1 = np.tanh(z1)\n",
" z2 = a1.dot(W2) + b2\n",
" exp_scores = np.exp(z2)\n",
" softmax = exp_scores / np.sum(exp_scores, axis = 1, keepdims = True) \n",
" \n",
" return z1, a1, softmax\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def loss(softmax, y, model_dict):\n",
" W1, b1, W2, b2 = retreive(model_dict)\n",
" m = np.zeros(200)\n",
" for i,correct_index in enumerate(y):\n",
" predicted = softmax[i][correct_index]\n",
" m[i] = predicted\n",
" log_prob = -np.log(m)\n",
" loss = np.sum(log_prob)\n",
" reg_loss = lambda_reg / 2 * (np.sum(np.square(W1)) + np.sum(np.square(W2)))\n",
" loss+= reg_loss\n",
" \n",
" return float(loss / y.shape[0])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def predict(model_dict, x):\n",
" W1, b1, W2, b2 = retreive(model_dict)\n",
" z1 = x.dot(W1) + b1\n",
" a1 = np.tanh(z1)\n",
" z2 = a1.dot(W2) + b2\n",
" exp_scores = np.exp(z2)\n",
" softmax = exp_scores / np.sum(exp_scores, axis = 1, keepdims = True) # (200,2)\n",
" \n",
" return np.argmax(softmax, axis = 1) # (200,)\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def backpropagation(x, y, model_dict, epochs):\n",
" for i in range(epochs):\n",
" W1, b1, W2, b2 = retreive(model_dict)\n",
" z1, a1, probs = forward(x, model_dict) # a1: (200,3), probs: (200,2)\n",
" delta3 = np.copy(probs)\n",
" delta3[range(x.shape[0]), y] -= 1 # (200,2)\n",
" dW2 = (a1.T).dot(delta3) # (3,2)\n",
" db2 = np.sum(delta3, axis=0, keepdims=True) # (1,2)\n",
" delta2 = delta3.dot(W2.T) * (1 - np.power(np.tanh(z1), 2))\n",
" dW1 = np.dot(x.T, delta2)\n",
" db1 = np.sum(delta2, axis=0)\n",
" \n",
" # Add regularization terms\n",
" dW2 += lambda_reg * np.sum(W2) \n",
" dW1 += lambda_reg * np.sum(W1) \n",
" \n",
" # Update Weights: W = W + (-lr*gradient) = W - lr*gradient\n",
" W1 += -learning_rate * dW1\n",
" b1 += -learning_rate * db1\n",
" W2 += -learning_rate * dW2\n",
" b2 += -learning_rate * db2\n",
" \n",
" # Update the model dictionary\n",
" model_dict = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}\n",
" \n",
" # Print the loss every 50 epochs\n",
" if i%50 == 0:\n",
" print(\"Loss at epoch {} is: {:.3f}\".format(i,loss(probs, y, model_dict)))\n",
" \n",
" return model_dict\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# Define Initial Weights\n",
"def init_network(input_dim, hidden_dim, output_dim):\n",
" model = {}\n",
" # Xavier Initialization \n",
" W1 = np.random.randn(input_dim, hidden_dim) / np.sqrt(input_dim)\n",
" b1 = np.zeros((1, hidden_dim))\n",
" W2 = np.random.randn(hidden_dim, output_dim) / np.sqrt(hidden_dim)\n",
" b2 = np.zeros((1, output_dim))\n",
" model['W1'] = W1\n",
" model['b1'] = b1\n",
" model['W2'] = W2\n",
" model['b2'] = b2\n",
" return model\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loss at epoch 0 is: 0.773\n",
"Loss at epoch 50 is: 0.330\n",
"Loss at epoch 100 is: 0.273\n",
"Loss at epoch 150 is: 0.262\n",
"Loss at epoch 200 is: 0.259\n",
"Loss at epoch 250 is: 0.258\n",
"Loss at epoch 300 is: 0.258\n",
"Loss at epoch 350 is: 0.258\n",
"Loss at epoch 400 is: 0.257\n",
"Loss at epoch 450 is: 0.257\n",
"Loss at epoch 500 is: 0.257\n",
"Loss at epoch 550 is: 0.256\n",
"Loss at epoch 600 is: 0.256\n",
"Loss at epoch 650 is: 0.256\n",
"Loss at epoch 700 is: 0.255\n",
"Loss at epoch 750 is: 0.255\n",
"Loss at epoch 800 is: 0.255\n",
"Loss at epoch 850 is: 0.255\n",
"Loss at epoch 900 is: 0.254\n",
"Loss at epoch 950 is: 0.254\n",
"Loss at epoch 1000 is: 0.254\n",
"Loss at epoch 1050 is: 0.254\n",
"Loss at epoch 1100 is: 0.253\n",
"Loss at epoch 1150 is: 0.253\n",
"Loss at epoch 1200 is: 0.253\n",
"Loss at epoch 1250 is: 0.253\n",
"Loss at epoch 1300 is: 0.252\n",
"Loss at epoch 1350 is: 0.252\n",
"Loss at epoch 1400 is: 0.252\n",
"Loss at epoch 1450 is: 0.252\n"
]
}
],
"source": [
"model_dict = init_network(input_dim=input_neurons,hidden_dim=3,output_dim=output_neurons)\n",
"\n",
"model = backpropagation(X,y,model_dict,epochs=1500)"
]
},
{
"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.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}