Introduction to AI and Neural Networks
NOTE: Import the following statements before running any of the other cells
import numpy as np
import matplotlib.pyplot as plt
Activation Functions (Slide 14)
Rectified Linear Unit (ReLU)
x = np.linspace(-5,5,1000)
y = np.maximum(0,x)
plt.plot(x,y)
plt.title("ReLu");
Sigmoid
x = np.linspace(-5,5,1000)
y = 1/(1+np.exp(-x))
plt.plot(x,y)
plt.title("Sigmoid");
tanh
x = np.linspace(-2,2,200)
y = np.tanh(x)
plt.plot(x,y)
plt.title("tanh");
Code Example: One input - One output (Slide 17)
def one_input_output(x, weight_1, weight_2):
return weight_1*x+weight_2
# Feel free to change the numbers as needed
w1 = 3
w2 = 5
x = 1
print(f"When x={x}, the output is {one_input_output(x,w1,w2)}")
Code Example: OR Gate (Slide 18)
# 2 layer NN for implementation of OR gate
def linear_activation(z):
return z
def orgate(input1, input2):
bias = -1
weighted_input = 2*input1 + 2*input2 + bias
y = linear_activation(weighted_input)
if y<0:
return False
else:
return True
def boolToBinary(bool1,bool2):
binary = []
if bool1:
binary.append(1)
else:
binary.append(0)
if bool2:
binary.append(1)
else:
binary.append(0)
return binary[0], binary[1]
## Feel free to experiment with the inputs bool1, bool2
bool1 = True
bool2 = True
input1, input2 = boolToBinary(bool1,bool2)
print(f"The output when the input is {bool1} and {bool2}: {orgate(input1,input2)}")
Code example: Average of 3 Numbers (Slide 19)
def linear_activation(z):
return z
def average_nn(input1, input2, input3):
w1 = 1.0 / 3.0
w2 = 1.0 / 3.0
w3 = 1.0 / 3.0
bias = 0
z = input1 * w1 + input2 * w2 + input3 * w3 + bias
y = linear_activation(z)
return y
input1 = 2 # change array as need be
input2 = 3
input3 = 4
print("The average of [{},{},{}] is {})".format(input1, input2, input3, average_nn(input1, input2, input3)))
Code Example: Multiple input - one output + Nonlinear activation (Slide 20)
def param_relu(a,x):
if x > 0:
return x
else:
return a*x
def abs_difference(x1,x2):
w1 = 1
w2 = -1
return param_relu(-1,w1*x1+w2*x2)
print(abs_difference(4,5))
Code example: Power of multiple layers together (Slide 21)
def param_relu(a,x):
if x > 0:
return x
else:
return a*x
def tanh_activation(x):
return np.tanh(x)
# 4 layer NN for computing whether absolute difference is between 1 and 3
# if between 1 and 3 outputs >0 else output <=0
def multilayer(x):
# layer 2
w1 = np.array([1,-1])
b1 = 0
weighted_input1 = np.matmul(w1,x) + b1
# output of layer 2
output2 = param_relu(-1, weighted_input1)
# layer 3
w2 = np.array([1])
b2 = -2
weighted_input2 = np.matmul(w2, [output2]) + b2
# output of layer 3
output3 = param_relu(-1, weighted_input2)
# final layer!
w3 = np.array([-1])
b3 = 1
weighted_input3 = np.matmul(w3, [output3]) + b3
y = tanh_activation(weighted_input3)
return y
x1 = np.random.rand()*10
x2 = np.random.rand()*10
print(f"For x1 = {x1:.5f} and x2 = {x2:.5f}, we have output {multilayer([x1,x2]):.5f}")
Code example: Average of 3 Numbers (Vectorized) (Slide 23)
# Simple 2 layer neural network that returns the average of a 3 numbers given as a 3x1 column vector
# this function does a "forward pass" of the input x through the 2 layer network and returns the results
def average_nn_vectorized(x):
weights = np.array(
[1/3, 1/3, 1/3] # a weights matrix of size 1 x 3
)
bias = 0
# we perform wx + b, using np.matmul to multiply matrices w and x
weighted_input = np.matmul(weights, x) + bias
y = linear_activation(weighted_input)
return y
array_input = [2, 3, 4] # change array as need be
x = np.array(array_input) # a column vector of size 3 x 1
print(f"The average is : {average_nn_vectorized(x)}")
Extra Example: Randomized 2 layer network
Below is an example of a neural network with randomly initialized weights.
np.random.seed(0)
w_2 = np.random.rand(10, 3) - 0.5 # 10 x 3 matrix
b_2 = np.random.rand() - 0.5
w_3 = np.random.rand(2, 10) - 0.5 # 2 x 10 matrix
b_3 = np.random.rand() - 0.5
def random_nn_activation(z):
# try defining different activations here given weighted input z, they will impact the results of our neural network
# the one given here is Relu - Rectified Linear Unit. See if you can understand what res[res < 0] = 0 means!
res = z.copy()
res[res < 0] = 0
return res
# this is a random neural network with slightly more layers and does the same thing, performs a forward pass of x through the network
# Architecturally, the network has 3 layers of sizes 3, 10, 2.
# see if you can understand whats happening with the matrix multiplications and why our architecture is 3, 10, 2!
def random_nn(x):
# typically, z represents our "weighted" input to the next layers, a is our activation
a_1 = x
z_2 = np.matmul(w_2, a_1) + b_2
a_2 = random_nn_activation(z_2)
z_3 = np.matmul(w_3, a_2) + b_3
a_3 = random_nn_activation(z_3)
return a_3
x = [1,2,3] # Feel free to change (1x3 vector)
y = random_nn(x) # Output is a 1x2 vector
print(f"We have input {x} give output {y}")
Practice Problems
Square of 2 inputs
Fill in the following code cell below. Complete the neural network and activation function to calculate the square of the sum of 2 inputs.
For example, When x1 = 1 and x2 = 1, the output is 4. (Square of 1+1)
# fill in this neural network and activation function to calculate the square of the sum of 2 inputs
def activation(z):
raise NotImplementedError
def squareNN(x1, x2):
# this should be a simple 2 layer network, one input layer and one output layer, figure out how many neurons are in each layer, the weights, and biases!
# This should take x1 and x2 and return the square of the sum of the 2 inputs, but obviously in neural network style!
raise NotImplementedError
Run the tests below to verify your network works!
# Your network works if you don't get any errors!
assert squareNN(1, 1) == 4
assert squareNN(-1, 1) == 0
assert squareNN(10, 2.5) == 156.25
assert squareNN(0, 0) == 0
Average of 5 values
Fill in the following code cell below. Complete the neural network and activation function to calculate the square of the sum of 2 inputs.
For example, When x = [1,2,3,4,5], the output is 3.
# fill in this neural network and activation function to calculate the of average of 5 values using numpy and vectorization
def activation(z):
raise NotImplementedError
def average5NN(x):
# this should be a simple 2 layer network, one input layer and one output layer, figure out how many neurons are in each layer, the weights, and biases!
# This should take input column vector x and apply an appropriate weight matrix and add a bias, apply the activation and then return the result
weights = np.array([]) # fill me in!
bias = 100 # fix me!
weighted_input = 0 # fill me in!
raise NotImplementedError
Run the tests below to verify your network works!
# Your network works if you don't get any errors!
assert average5NN(np.array([1, 1, 1, 1, 1])) == 1.0
assert average5NN(np.array([1, -1, 1, -1, 0])) == 0.0
assert average5NN(np.array([1, 2, 3, 4, 5])) == 3.0
assert average5NN(np.array([100, 200, 300, 400, -400])) == 1.2