# Neural network from scratch in Python

So after watching week 5 of the machine learning course on Coursera by Andrew Ng, I decided to write a simple neural net from scratch using Python. Here's my code:

import numpy as np
import csv
global e
global epsilon
global a
global lam
global itr
e = 2.718281828
epsilon = 0.12
a = 1
lam = 1
itr = 1000

# The sigmoid function(and its derivative)
def sigmoid(x, derivative=False):
if derivative:
return sigmoid(x) * (1 - sigmoid(x))
return 1 / (1 + e**-x)

# The cost function
def J(X, theta1, theta2, y, lam, m):
j = 0
for i in range(m):
# The current case
currX = X[i].reshape(X[i].shape, 1)
z2 = theta1 @ currX
a2 = sigmoid(z2)
a2 = np.append(, a2).reshape(a2.shape + 1, 1)
z3 = theta2 @ a2
a3 = sigmoid(z3)
j += sum(-y[i] * np.log(a3) - (1 - y[i]) * np.log(1 - a3)) / m + (lam / (2 * m)) * (sum(sum(theta1[:, 1:] ** 2)) + sum(sum(theta2[:, 1:] ** 2)))
return j

def gradient(X, theta1, theta2, y, lam, m):
Delta1 = np.zeros(theta1.shape)
Delta2 = np.zeros(theta2.shape)
for i in range(m):
# The current case
currX = X[i].reshape(X[i].shape, 1)
z2 = theta1 @ currX
a2 = sigmoid(z2)
a2 = np.append(, a2).reshape(a2.shape + 1, 1)
z3 = theta2 @ a2
a3 = sigmoid(z3)
delta3 = a3 - y[i]
delta2 = theta2[:, 1:].T @ delta3 * sigmoid(z2, derivative=True)
Delta1 += delta2 @ currX.reshape(1, -1)
Delta2 += delta3 * a2.reshape(1, -1)
theta1Grad[:, 1:] += (lam / m) * theta1[:, 1:]
theta2Grad[:, 1:] += (lam / m) * theta2[:, 1:]

def gradientDescent(X, theta1, theta2, y, lam, m):
for i in range(itr):
theta1 = theta1 - a * theta1Grad
theta2 = theta2 - a * theta2Grad
return (theta1, theta2)

with open('data.csv', 'r') as f:
d = []
c = 0
for row in data:
# Don't add the first line(it's our features' labels)
if c == 0:
c += 1
continue
curr_row = []
k = 0
for j in row:
if j != '':
if k == 1:
# Add a 1 between the y and x values(for the bias)
curr_row.append(1)
curr_row.append(float(j))
k += 1
d.append(curr_row)
d = np.array(d)
x = d[:, 1:]
y = d[:, 0]
# Split the data into training cases(80%) and test cases(20%)
x_train = x[0:(d.shape//5) * 4, :]
y_train = y[0:(d.shape//5) * 4]
x_test = x[(d.shape//5) * 4 : d.shape, :]
y_test = y[(d.shape//5) * 4 : d.shape]
# Initialize theta(s)
theta1 = np.random.rand(5, x.shape) * 2 * epsilon - epsilon
theta2 = np.random.rand(1, 6) * 2 * epsilon - epsilon
print(J(x_train, theta1, theta2, y_train, lam, x_train.shape))
theta1, theta2 = gradientDescent(x_train, theta1, theta2, y_train, lam, x_train.shape)


Please note a that my data only has 2 possible outputs so no need for one-vs-all classification.

• You don't need to declare global var in global scope. This only needs to be done inside a function that might need to modify a global variable – C.Nivs Sep 22 '19 at 2:29