Deadline: January 20, 9pm.
Late Penalty: See Syllabus
TAs: Andrew Jung
Welcome to the first assignment of APS360! This assignment is a warm up to get you used to the programming environment used in the course, and also to help you review and renew your knowledge of Python and relevant Python libraries. The assignment must be done individually. Please recall that the University of Toronto plagarism rules apply.
By the end of this assignment, you should be able to:
numpy.matplotlib.Submit a PDF file containing all your code, outputs, and write-up from parts 1-4. Do not submit any other files produced by your code.
Completing this assignment using Jupyter Notebook is highly recommended
(though not necessarily for all subsequent assignments). If you are using
Jupyter Notebook, you can export a PDF file using the menu option
File -> Download As -> PDF via LaTeX (pdf)
Your first step is to set up your development environment. We'll be using the Anaconda distribution of Python 3.6. Following the instructions to install Python3.6, PyCharm, Jupyter Notebook:
https://www.cs.toronto.edu/~lczhang/360/files/install.pdf
To prepare for the rest of the assignment, the preparatory readings in section 2 of the installation instructions are very helpful.
The purpose of this section is to get you used to the basics of Python, including working with functions, numbers, lists, and strings.
Write a function sum_of_squares that computes the sum of squares up to n.
def sum_of_squares(n):
"""Return the sum (1 + 2^2 + 3^2 + ... + n^2)
Precondition: n > 0, type(n) == int
>>> sum_of_squares(3)
14
>>> sum_of_squares(1)
1
"""
Write a function word_lengths that takes a sentence (string), computes the length of each word in that sentence, and returns the length of each word in a list. You can
assume that words are always separated by a space character " ".
Hint: recall the str.split function in Python.
If you arenot sure how this function works, try
typing help(str.split) into a Python shell, or checkout https://docs.python.org/3.6/library/stdtypes.html#str.split
help(str.split)
def word_lengths(sentence):
"""Return a list containing the length of each word in
sentence.
>>> word_lengths("welcome to APS360!")
[7, 2, 7]
>>> word_lengths("machine learning is so cool")
[7, 8, 2, 2, 4]
"""
In this part of the assignment, you'll be manipulating arrays
usign NumPy. Normally, we use the shorter name np to represent
the package numpy.
import numpy as np
Load the file matrix.csv into a variable called matrix using the function np.loadtxt. Make sure that matrix.csv is in the same file folder as this notebook.
matrix = None
matrix
Load the file vector.npy into a variable called vector using the function np.load. As before, make sure that vector.npy is in the same file folder as this notebook.
vector = None
vector
Perform matrix multiplication output = matrix x vector by using
for loops to iterate through the columns and rows.
Do not use any builtin NumPy functions.
Hint: be mindful of the dimension of output
output = None
output
Save the output variable into a csv
file called output_forloop.csv using the function numpy.savetxt.
Perform matrix multiplication output2 = matrix x vector by using
the function numpy.dot.
We will never actually write code as in
part(c), not only because numpy.dot is more concise and easier to read/write, but also performance-wise numpy.dot is much faster (it is written in C and highly optimized).
In general, we will avoid for loops in our code.
output2 = None
output2
Save the output2 variable into a csv
file called output_dot.npy using the function numpy.save.
As a way to test for consistency, show that the two outputs match.
A callable object is any object that can be called like a function.
In Python, any object whose class has a __call__ method will be callable.
For example, we can define an AddBias class that is initialized with a value val. When the object of the Adder class is called with input, it will return the sum of val and input:
class AddBias(object):
def __init__(self, val):
self.val = val
def __call__(self, input):
return self.val + input
add4 = AddBias(4)
add4(3)
# AddBias works with numpy arrays as well
add1 = AddBias(1)
add1(np.array([3,4,5]))
Create a callable object class ElementwiseMultiply that is initialized with weight, which is a numpy array (with 1-dimension).
When called on input of the same shape as weight, the object will output an elementwise product of input and weight. For example, the 1st element in the output will be a product of the first element of input and first element of weight. If the input and weight have different shape, do not return anything.
Create a callable object class LeakyRelu that is initialized
with alpha, which is a scalar value.
When called on input, which may be a NumPy array,
the object will output:
To obtain full marks, do not use any for-loops to implement this class.
Create a callable object class Compose that is initialized with layers, which is a list of callable objects each taking in one argument when called. For example, layers can be something like [add1, add4] that we created above. Each add1 and add4 take in one argument. When Compose object is called on a single argument, the object will output a composition of object calls in layers, in the order given in layers (e.g. add1 will be called first and then add4 will be called after using the result from add1 call)
Run the below code and include the output in your report.
weight_1 = np.array([1, 2, 3, 4])
weight_2 = np.array([-1, -2, -3, -4])
bias_1 = 3
bias_2 = -2
alpha = 0.1
elem_mult_1 = ElementwiseMultiply(weight_1)
add_bias_1 = AddBias(bias_1)
leaky_relu = LeakyRelu(alpha)
elem_mult_2 = ElementwiseMultiply(weight_2)
add_bias_2 = AddBias(bias_2)
layers = Compose([elem_mult_1,
add_bias_1,
leaky_relu,
elem_mult_2,
add_bias_2,
leaky_relu])
input = np.array([10, 5, -5, -10])
print("Input: ", input)
output = layers(input)
print("Output:", output)
A picture or image can be represented as a NumPy array of “pixels”, with dimensions H × W × C, where H is the height of the image, W is the width of the image, and C is the number of colour channels. Typically we will use an image with channels that give the the Red, Green, and Blue “level” of each pixel, which is referred to with the short form RGB.
You will write Python code to load an image, and perform several array manipulations to the image and visualize their effects. You’ll need the file dog_mochi.png from the same place you downloaded this assignment. Save the output images in the same directory as the Jupyter Notebook.
import matplotlib.pyplot as plt
Load the image dog_mochi.png into the variable img using the pyplot.imread function.
This is a photograph of a dog whose name is Mochi.
img = None
Use the function plt.imshow to visualize img.
This function will also show the coordinate system used to identify pixels. The origin is at the top left corner, and the first dimension indicates the Y (row) direction, and the second dimension indicates the X (column) dimension.
What is the pixel coordinate of Mochi's eye? Show the value of each of the 3 channels on a pixel cooresponding to Mochi's eye.
The value for each channel in the original image ranges from 0 (darkest) to 255 (lightest). However, when loading an image through Matplotlib, this range will be scaled to be from 0 (darkest) to 1 (brightest) instead, and will be a real number, rather than an integer.
Modify the image by adding a constant value of 0.25 to each pixel in the img and
store the result in the variable img_add. Note that, since the range for the pixels
needs to be between [0, 1], you will also need to clip img_add to be in the range [0, 1]
using numpy.clip. Clipping sets any value that is outside of the desired range to the
closest endpoint. Display the image using plt.imshow.
img_add = None
From the original image, create three images that separate out the three colour channels (red, green and blue).
Hint: First create an array initialized with zeros, then copy over the specific channel’s 2D content from img.
Crop the image to only show Mochis face. Your image should be square. Display the image.
Finally, save the image from part (f) using plt.imsave as the filename dog_name.png.