Homework 1: Python Basics with NumPy¶

In this assignment, you will review the basics of Python programming and learn how to work with NumPy for numerical computations. We will also implement the XOR logical operator using multilayer perceptrons. Complete the exercises below by following the provided instructions.

Basic Python Operations¶

Exercise 1 [10/10]: Create two variables x and y and assign them the values 5 and 10, respectively.

In [ ]:
### Code star here ###

### End code here ###

Exercise 2 [10/10]: Compute their sum and product. Print the result.

In [ ]:
### Code star here ###


### End code here ###
15
50

Exercise 3 [10/10]: Use an if-else statement to print 1 if x is greater than or equival to y, and print 0 otherwise.

In [ ]:
### Code star here ###

### End code here ###
0

Functions¶

Exercise 4 [10/10]:

  1. Write a function called step that returns 1 if the given number ( x ) is greater than or equal to 0, and 0 otherwise.
  2. Call the function to compute the values for 3 and -1.
  3. Print the results.
In [ ]:
def step(x):
    ### Code star here ###

    ### End code here ###

print(step(3))
print(step(-1))
1
0

Lists and Loops¶

Exercise 5 [10/10]:

  1. Define a list or 1D-array arr with the values [-1, -2, 3, 4, 5].
  2. Use a for loop to compute and print the result of the step function for each entry in the list.
In [ ]:
arr = [-1, -2, 3, 4, 5]
### Code star here ###

### End code here ###
0
0
1
1
1

NumPy Arrays¶

Exercise 6 [10/10]:

  1. Import the numpy library as np.
  2. Create a NumPy array arr containing integers from -5 to 5 (inclusive).
  3. Print the created array.
In [ ]:
import numpy as np
### Code star here ###

### End code here ###
print(arr)
[-5 -4 -3 -2 -1  0  1  2  3  4  5]

You will encounter an error in the following code

In [ ]:
step(arr)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-50-87446ac4172a> in <cell line: 1>()
----> 1 step(arr)

<ipython-input-46-47485f490005> in step(x)
      1 def step(x):
      2     ### Code star here ###
----> 3     if x >= 0:
      4         return 1
      5     else:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

It is because the step function expects a scalar input, but we provided a list. To handle this, we can use np.vectorize, which returns a vectorized version of the step function called vstep. This will apply the original step function to each element in the given array.

In [ ]:
vstep = np.vectorize(step)
vstep(arr)
Out[ ]:
array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

Class and Perceptron¶

Recall the definition of a single perceptron: $$ \hat{y}=\phi(w^{\top}x + b) $$

Exercise 7 [10/10]:

  1. Define a class Perceptron that takes input weights w and bias b.
  2. In its __init__ method, store the inputs w and b as self.w and self.b, respectively.
  3. Create another method __call__ that applies the function vstep to the sum of the dot product of x and self.w plus self.b.
In [ ]:
class Perceptron:
    def __init__(self, w, b):
        self.w = np.array(w)
        self.b = b

    def __call__(self, x):
        ### Code star here ###

        ### End code here ###

Exercise 8 [10/10]: Define the AND, OR, and NAND gates using the Perceptron class:

  1. and_perceptron: w=[1, 1] and b=-1.5.
  2. or_perceptron: w=[1, 1] and b=-0.5.
  3. nand_perceptron: w=[-1, -1] and b=1.5.
In [ ]:
and_perceptron = Perceptron([1, 1], -1.5)
or_perceptron = Perceptron([1, 1], -0.5)
### Code star here ###

### End code here ###

Exercise 9 [10/10]: Test the performance of the perceptrons

  1. Define the inputs as inputs = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]).
  2. For each input x in inputs, evaluate it using and_perceptron, or_perceptron, and nand_perceptron, and print the results.
In [ ]:
inputs = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])

for x in inputs:
    print(f"Input: {x}, AND Output: {and_perceptron(x)}")

for x in inputs:
    print(f"Input: {x}, OR Output: {or_perceptron(x)}")

for x in inputs:
    ### Code star here ###

    ### End code here ###
Input: [0 0], AND Output: 0
Input: [0 1], AND Output: 0
Input: [1 0], AND Output: 0
Input: [1 1], AND Output: 1
Input: [0 0], OR Output: 0
Input: [0 1], OR Output: 1
Input: [1 0], OR Output: 1
Input: [1 1], OR Output: 1
Input: [0 0], NAND Output: 1
Input: [0 1], NAND Output: 1
Input: [1 0], NAND Output: 1
Input: [1 1], NAND Output: 0

Multilayer Perceptrons¶

As discussed in the first week's lecture, we can implement xor using a two-layer MLP. This is possible because xor can be expressed in terms of or, and, and nand as follows: $$ x_1 \oplus x_2 = (x_1 \lor x_2) \land (x_1 \uparrow x_2). $$

Exercise 10 [10/10]:

  1. Define a function xor_mlp that takes an input x.
  2. In the first layer, compute the outputs out1 and out2 using or_perceptron and nand_perceptron, respectively.
  3. In the second layer, compute the final output final_output by passing the outputs [out1, out2] into the and_perceptron.
  4. Return the final_output.
In [ ]:
def xor_mlp(x):
    # First layer: we compute the outputs from or_perceptron and nand_perceptron
    out1 = or_perceptron(x)
    ### Code star here ###

    ### End code here ###

    # Second layer: we compute the final output from and_perceptron
    final_output = and_perceptron([out1, out2])
    return final_output

for x in inputs:
    print(f"Input: {x}, XOR Output: {xor_mlp(x)}")
Input: [0 0], XOR Output: 0
Input: [0 1], XOR Output: 1
Input: [1 0], XOR Output: 1
Input: [1 1], XOR Output: 0

Congratulations!!!¶

You have completed the basic exercises on Python programming and NumPy. Additionally, you have successfully implemented perceptrons and used them to solve the XOR problem. This has helped you build a solid understanding of multilayer perceptrons, which will serve as a strong foundation for more advanced neural network topics in the future.

In [ ]: