Informatics


Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due


Assignment1

March 23, 2025

1 Informatics 

1 Cognitive Science 2024/25
2 Assignment 1

2.0.1 How to use this notebook

File name: You must not change the name of the assignment file. Doing so is likely to lead to your assignment not being marked properly. Read-only cells: You may notice that there are some cells which you cannot edit (usually cells which explain the question) - these cells are read only. Your answer: Cells which are left blank for your responses will either require a text response or a code response. This will be clear from the question, but you should check that a text responseis written in a markdown cell, and a code response is written in a code cell (as indicated in thetoolbar). Code answers: In questions that require you to write code, there will usually be a codecell containing:
# YOUR CODE HERE raise NotImplementedError()
When you are ready to write your answer, delete or comment out raise NotImplementedError() and write your code.

Text answers: For questions with a text answer, there will be a markdown cell following thequestion. There will usually be an indication that the cell is intended for your answer such as “YOUR ANSWER HERE”, which you can replace with your response.

Assert statements: You may notice that some lines of code starting with assert cause errors whenrun multiple times. If your answer is correct, these tests should pass when you restart your notebookand run all cells in order.

2.0.2 Submitting your work

Before you submit, ensure that the notebook can be run from start to finish by pressing the “Restart & Run All” option in the “Kernel” menu above.

You should run your notebook and save your work before you submit.

Once you are ready, go to the assignments tab on the Noteable landing page and click “Submit” on the relevant assignment.

You are allowed to submit multiple times. Please be aware that we will mark your lastsubmission even if this is after the deadline. Therefore to avoid late penalties, you should notsubmit after the deadline. It may take a few minutes to submit your assignment so please bear thisin mind when timing your submission. If you have not previously submitted an assignment through

Noteable, we recommend you submit an early version of your assignment so that you can ensureyou understand this process. You can also walk through this process with a lab demonstrator ifyou are unsure.

Note: The Noteable system has undergone a substantial update this year. As such, there may be changes which we have not yet seen. If you have issues with using the assignment, please let thecourse teaching assistants know so that we can provide support.

If you have any issues submitting: Download your notebook by right-clicking on the file name inthe file tree on the left and selecting “Download”. You can then email this file to the course staff as evidence of a timely submission. You may still need to submit via Noteable so please pay closeattention to any updated instructions from course staff.

[2]: # this is to plot inside the notebook
%matplotlib inline
# these are the libraries we are going to use
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from scipy.signal import convolve2d
# we are also going to use helper functions from the RM1985.py file
from RM1985 import *
matplotlib.style.use('seaborn-v0_8-notebook')
import warnings
warnings.filterwarnings('ignore')
np.random.seed(2222)

3 PART 1

In this part of the assignment, we’re going to replicate Rumelhart and McClelland’s (1985) model of the past tense (pictured below). If you’re itching to read the source paper, it’s included in the

Assignment 1 directory and may be a handy reference. We’re going to walk through the necessary components here.

Most of the functions we need for the RM model are already implemented for us: Have a look at the file RM1985.py if you want to know the details.


3.1 Encoding the input

Recall from lecture, the model uses a phonological representation called wickelfeatures.

Words (e.g., came) are translated into phonemes (e.g., kAm).

Phonemes are converted into a binary code based on their articulatory features (see below). Remember that in RM’s model we use wickelphones (triplets of phonemes; e.g., #kA, kAm, Am#).

[3]: word_to_wickelphone('kAm')
[3]: [['0000000000', '1001000101', '0010110010'],
['1001000101', '0010110010', '1000110010'],
['0010110010', '1000110010', '0000000000']]

In practice, we also add a bit representing if a wickelphone touches a word boundary, resulting inan 11 bit code for each phoneme. You will not need the specifics of the code for this assignment.

Wickelphones are converted into wickelfeatures by taking one of the bits from the first phoneme in awickelphone, one of the bits from the second phoneme, and one of the bits from the third. In theorythen, there are 11 * 11 * 11 possible wickelfeatures. However, in practice a lot of these combinationsare redundant and we can represent all informative combinations with just 460 wickelfeatures. Ifyou’re really itching for the details they’re in the paper.

Luckily, we have a helper function that will do all of this encoding for us: activate_word

[ ]: activate_word('kAm')

We should check some properties of our encoding function.

In order to do this we first have to translate some words (e.g., came) into phonemes (e.g. kAm).

A lot of letters in English map directly onto their phoneme (e.g., b -> b) however, there are a few that don’t (e.g., c as in car is represented by a k). The table below should help you translate wordsinto phonemes (particularly the caption helps with vowels):


Exercise 1a)

Let’s translate the ten high frequency words used in the paper: come/came, look/looked, feel/felt, have/had, make/made, get/got, give/gave, take/took, go/went, like/liked (Points 2)
[ ]: # save the phoneme representations of the base verb and past tense verb here
# keep the order in the quetion above: come, look, feel, have, make, get, give,␣
take, go, like
# high_frequency_verbs = ['come', 'look', 'feel', 'have', 'make', 'get',␣
'give', 'take', 'go', 'like']
# base_high_frequency_verbs = ['k*m', 'luk', ...]
# past_high_frequency_verbs = ['kAm', 'lukt', ...]
high_frequency_verbs = ['come', 'look', 'feel', 'have', 'make', 'get', 'give',␣
'take', 'go', 'like']
# YOUR CODE HERE
raise NotImplementedError()
[ ]: """Check that translation was correct"""
for i, w in enumerate(high_frequency_verbs):
print(w, 'Base:', activate_word(base_high_frequency_verbs[i]) ==␣
base_HF_activations[i])
print(w, 'Past:', activate_word(past_high_frequency_verbs[i]) ==␣
past_HF_activations[i])

Now let’s check some properties of our encoding function: activate_word

As mentioned above, there should be 460 wickelfeatures for each word. We can check this using np.shape

For a three phoneme word like came, we expect there to be at most 16 active wickelfeatures.

Exercise 1b)

Store the shape of the wickelfeature represetation for came and the number of wickelfeatures acti vated (i.e., set to 1). (Points 2)

[ ]: # compute the shape and the number of active wickelfeatures here
# came_activation = np.array(activate_word('kAm'))
# came_shape = ...
# came_number_active_wickelfeatures = ...
came_activation = np.array(activate_word('kAm'))
# YOUR CODE HERE
raise NotImplementedError()
[ ]: """Check the shape and number of active wickelfeatures is correct"""
assert(came_shape == (460,))
assert(came_number_active_wickelfeatures == 16)

## The Model

Now that we have our input representations, we can work on the model implementation.

The goal of RM’s model is to output a wickelfeature representation for the past tense of the input verb. To do this, they build a perceptron for each of the 460 possible wickelfeatures. Each perceptron receieves the entire phonological representation of the base verb as input and decides ifa single wickelfeature should be present in the output.

We have implemented the standard percepton model for you in the file RM1985.py; however, there is one difference between a standard perceptron and the one’s used by RM.

In the standard perceptron, a unit fires if the weighted activation net is greater than a threshold theta; otherwise it does not fire.

In RM’s perceptron, a unit fires probabilistically according to the activation function:

Exercise 2a)
Translate this function into code. (Points 2)

Hint: the exponential function can be calculated using np.exp()

[ ]: # translate the function here
#
# def rm_activation_function(net, theta, T=1.0):
# # YOUR CODE HERE
# # probability = ...
# return probability
# YOUR CODE HERE
raise NotImplementedError()
[ ]: """Check the functions output"""
assert(rm_activation_function(0, 0.0) == 0.5)
assert(rm_activation_function(1., 0., 1.0) == 0.7310585786300049)
assert(rm_activation_function(2., 1., T=2.) == 0.6224593312018546)

RM’s activation function looks quite similar to the sigmoid function we discussed in lecture 6.

However, what does the T parameter do?

Let’s vizualize it.
Exercise 2b)

Let’s set theta = 0.0 and plot the probability of firing as a function of the the weighted activation net at T=1.0, T=0.5 and T=2.0 in one figure. We should consider weighted activation values between -5 and 5.

(Points 4)
For full credit you should:
  • Plot the probability of firing (Y-axis) as a function of weighted activation, net, (X-axis) on the same plot (choose distinguishable colors please).
  • Set labels for both axes.
  • Set a title for the figure.
  • Set the plot to span (0, 1) for the y-axis and and (-5, 5) for the x-axis
  • Set a legend indicating how colors map to values of T

Please have a look at lab 3 if you need a reminder on how to do plotting in Python!

[ ]: # calculate and plot the probability of firing at different T values
#
# net_activation = np.arange(-5, 6)
# p_T1 = rm_activation_function(net_activation, theta=0.0, T=1.0)
# p_T05 = ...
# p_T2 = ...
#
# YOUR CODE HERE
raise NotImplementedError()
Exercise 2c)
Discuss how this activation function differs from the standard perceptron activation function. (max 5 sentences)
(Points 2)

YOUR ANSWER HERE

4 U Shaped Curves

Recall from lecture that RM used this model to demonstrate a developmental U-shape curve.

First they trained the model on ten high frequency words (8 irregular, 2 regular), then medium frequency verbs, then low frequency verbs. They then plotted the percent of wickelfeatures themodel correctly predicted for irregular and regular verbs as the model saw more data.

Let’s replicate this step by step :)

First, let’s load in a corpus of English verbs.

[ ]: # read in the corpus
verbs = []
with open('verbs.csv') as f:
for i, line in enumerate(f.readlines()):
if i == 0:
print(line.strip('\n').split(','))
else:
verbs.append(line.strip('\n').split(','))
print(verbs[-1])
# add in the high frequency verbs you translated for us earlier
for i, word in enumerate(high_frequency_verbs):
if word in ['look', 'like']:
verbs.append([word, 'Regular', base_high_frequency_verbs[i],␣
past_high_frequency_verbs[i], 'H'])
else:
verbs.append([word, 'Irregular', base_high_frequency_verbs[i],␣
past_high_frequency_verbs[i], 'H'])
print(verbs[-1])
  • The first column denotes the verb.
  • The second column denotes whether the verb is regular or irregular.
  • The third column denotes the phoneme representation of the base verb.
  • The fourth column denotes the phoneme representation of the past tense verb.
  • The last column denotes the verb’s frequency (M: Medium or L: Low)
4.1 First Stage: High Frequency Verbs

In the first stage, RM trained the model on the high frequency verbs.

Let’s do that.

First we need to convert the phonemes into wickelfeatures.

[ ]: base_wickel_HF = np.array([activate_word(w) for w in␣
base_high_frequency_verbs]).T
past_wickel_HF = np.array([activate_word(w) for w in␣
past_high_frequency_verbs]).T

Next we initialize a perceptron with our custom activation function

[ ]: percept = Perceptron(active=rm_activation_function)
Now let’s do the perceptron learning algorithm for each high frequency word (i.e. one epoch).

The function Perceptron.learn() does one epoch of weight updates and then returns the model accuracy on the data. This is the percentage of the wickelfeatures the model correctly predicts.

[ ]: percept.learn(base_wickel_HF, past_wickel_HF)

We can also score the perceptron, using Perceptron.score(). This just returns the accuracy, without updating the weights.

[ ]: percept.score(base_wickel_HF, past_wickel_HF)

So after one epoch, the perceptron performs well on the verbs it has seen already.

How will the perceptron perform on all the irregular and regular verbs, including the ones it has not seen yet?
Exercise 3a)
Now let’s divide the corpus verbs into two lists: one for regular verbs and one for irregular verbs. (Points 2)
Hint: You may want to use a for loop over verbs
[ ]: # store the two sets here
#
# regular_verbs = ...
# irregular_verbs = ...
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(len(regular_verbs) == 96)
assert(len(irregular_verbs) == 96)
Now let’s score the perceptron’s performance on both the regular and irregular verbs.
Exercise 3b)
First convert the phonemes for base and past tense into wickelfeatures. Then calculate the mean score of the model on irregular and regular verbs.
(Points 3)
Hint: Look back to how we coverted phonemes into wickelfeatures above.
[ ]: # convert irregular and regular verbs into wickelfeatures
#
# base_wickel_irregular = ...
# past_wickel_irregular = ...
# base_wickel_regular = ...
# past_wickel_regular = ...
#
# irregular_score = np.mean(percept.score(base_wickel_irregular,␣
past_wickel_irregular))
# regular_score = np.mean(percept.score(base_wickel_irregular,␣
past_wickel_irregular))
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(irregular_score == 0.9142889492753623)
assert(regular_score == 0.8748188405797102)

So far we’ve trained the model in batch, which means it has seen all the data once before we score it.

Let’s train the model one data point at a time and score it after each datapoint
[ ]: # Let's initialize a new perceptron with our custom activation function
percept = Perceptron(active=rm_activation_function)
# Now let's loop through each data point to train and score
9scores_regular = []
scores_irregular = []
for i in range(len(high_frequency_verbs)):
percept.learn(base_wickel_HF[:,i, np.newaxis], past_wickel_HF[:,i,np.
newaxis])
scores_regular.append(np.mean(percept.score(base_wickel_regular,␣
past_wickel_regular)))
scores_irregular.append(np.mean(percept.score(base_wickel_irregular,␣
past_wickel_irregular)))
print(scores_regular[-1], scores_irregular[-1])
Exercise 3c)
Explain the model output. So far, do we replicate RM? Do we expect to get the same result if we rerun the model? (7 sentences max)
(Points 3)
YOUR ANSWER HERE

4.2 Second Stage: Medium Frequency Verbs

Recall, in the second stage of the U-Shape curve, RM train the model with medium frequency verbs. Let’s do it!
Exercise 4a)
First, we need to extract the medium frequency verbs from the corpus verbs.
(Points 1)
[ ]: # store the medium frequency verbs here
#
# base_med_frequency_verbs = ...
# past_med_frequency_verbs = ...
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(len(base_med_frequency_verbs) == 150)
assert(len(past_med_frequency_verbs) == 150)
Exercise 4b)
Second, we need to convert those those verbs into wickelfeatures.
(Points 2)
[ ]: # convert the verbs into wickelfeatures
#
# base_wickel_MF = ...
# past_wickel_MF = ...
10# YOUR CODE HERE
raise NotImplementedError()
Now, we need to loop through each data point to train and score, like we just did for the high
frequency verbs.
Exercise 4c)
Calculate and store the scores for regular and irregular verbs in the variables scores_irregular_md
and scores_regular_md.
(Points 2)
[ ]: # loop through the medium frequency verbs to train and score the model here
#
# scores_regular_md = []
# scores_irregular_md = []
# for i in range(len(base_med_frequency_verbs)):
# # YOUR CODE HERE
# print(scores_regular_md[-1], scores_irregular_md[-1])
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(scores_regular_md[-1] == 0.9333333333333332 )
assert(scores_irregular_md[-1] == 0.9447690217391305)
4.3 Third Stage: Low Frequency Verbs
In the third stage of the U-Shape curve, RM train the model with low frequency verbs. One last time then :)
Exercise 4d)
First, we need to extract the low frequency verbs from the corpus verbs.
(Points 1)
[ ]: # store the low frequency verbs here
#
# base_low_frequency_verbs = ...
# past_low_frequency_verbs = ...
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(len(base_low_frequency_verbs) == 32)
assert(len(past_low_frequency_verbs) == 32)
Exercise 4e)
Second, we need to convert those those verbs into wickelfeatures.
(Points 2)
[ ]: # convert the verbs into wickelfeatures
#
# base_wickel_LF = ...
# past_wickel_LF = ...
# YOUR CODE HERE
raise NotImplementedError()
Finally, we need to loop through each data point to train and score.
Exercise 4f)
Calculate and store the scores for regular and irregular verbs in the variables
scores_irregular_low and scores_regular_low.
(Points 2)
[ ]: # loop through the medium frequency verbs to train and score the model here
#
# scores_regular_low = []
# scores_irregular_low = []
# for i in range(len(base_low_frequency_verbs)):
# # YOUR CODE HERE
# print(scores_regular_low[-1], scores_irregular_low[-1])
# YOUR CODE HERE
raise NotImplementedError()
[ ]: assert(scores_regular_low[0] == 0.9320652173913043)
assert(scores_irregular_low[0] == 0.9478940217391304)
assert(scores_regular_low[-1] == 0.9432065217391304)
assert(scores_irregular_low[-1] == 0.9518795289855072)

4.4 Putting it all together

Exercise 5a)
Let’s see how well we replicated the U-Shape pattern by plotting the simulation output.
(Points 4)
For full credit your code should:
  • Plot the percent of correct wickelfeatures (Y-axis) as a function of the amount of datapointstrained on for both regular and irregular verbs (use distinct colors please).
  • Plot dashed vertical lines at 10 and 160 data points to demarcate the three different timeperiods.
  • Set labels for both axes.
  • Set a title for the figure.
  • Set the plot to span (0.5, 1) for the y-axis and and (0, 192) for the x-axis
  • Set a legend indicating how colors map to verb type
Hint: to concatenate two lists into a bigger list you can use the following syntax: big_list =
one_list + another_list
[ ]: # YOUR CODE HERE
# YOUR CODE HERE
raise NotImplementedError()
Exercise 5b)
1) Did we replicate RM’s U-shaped curve? Why or why not? Be specific.
2) Do you believe this model is a fair model of children’s acquisition? Why or why not? Be specific.
(Points 6)
For each question make no more than three specific arguments. We will only mark the first three.
Feel free to bullet your points. This is not an essay.
YOUR ANSWER HERE

5 Extension: Error Analysis

If you have recieved full marks on everything up to here in Part 1 of this assignment, then youwould have a high A (40 out of 50 points). If you struggled to make it this far, you might considerskipping the final question and focusing on the previous questions (and on Part 2!).

The next question is less structured and will be marked harder. To reiterate, you can get an Awithout even attempting this question.

Exercise 6)
In this exercise, you need to conduct a more thorough error analysis of RM’s model. On page 22 of the RM paper, they describe eight different classes of irregular verb. The goal of this questionis to create a similar graph to the one you just made but with individual lines for every type of irregular verb.
(Points 10)
In order to recieve full marks you must, - Annotate the types of irregular verbs (important: thismust be done within this notebook file). - Run a new instance of the RM perceptron followingthe same training regime. - Score the model on each type of irregular verb. - Plot the learningtrajectory for each type of irregular verb. - Discuss your findings, which means STATE the modeloutput, STATE why the model does it, STATE whether or not you believe it, and STATE why youdo/don’t believe it (500 words max).
Above all else clarity is imperative. Comment all your code so that we can understand what youare doing. Make sure all your plots are legible. Just as in the real world, if it’s brilliant but nobodycan understand it, it won’t get you anywhere.
13[ ]: # YOUR CODE HERE
raise NotImplementedError()
[ ]: # YOUR CODE HERE
raise NotImplementedError()
YOUR ANSWER HERE
PART 2
In this part you will study models of receptive fields in the visual system. You will look at thespatial filtering neurons perform but ignore the temporal aspects. In this case the receptive field ofa neuron can be defined as a matrix of weights that scale each pixel, before the output is computedby summing the weighted pixels.

Some of the following questions will require you to write code, in this case use the relevant cells labelled # YOUR CODE HERE for question xxx. For text answers use the cell labelled YOUR ANSWERHERE for question xxx. For some questions it is helpful to experiment with the provided code.

You can modify it where it’s provided or add extra code cells to experiment. You are permitted toadd additional cells in order to add written explanations or code if needed.

Exercise 7a)
The code below prepares the coordinates for the receptive field models.
Answer the following questions below: 1) How many pixels does this receptive field span. 2) Is therean even or odd number of pixels along each axis? Why? 3) Write the code to create coordinatesfor a receptive field with 13 pixels along each axis.
(Points 4)
[ ]: x = np.tile(np.arange(-8,9),(17,1))
y = x.T
YOUR ANSWER HERE for questions 7a parts 1, 2
[ ]: # YOUR CODE HERE for question 7a part 3
# YOUR CODE HERE
raise NotImplementedError()
Exercise 7b)
Next we create a receptive field model, the code is given below.
1) Describe the receptive field (you may want to plot it, the plt.imshow function is useful forthis purpose, use the code cell below for this).<br?
2) State which cell type the receptive field best matches, and where in the visual system suchcells are found.
3) Which feature in an image most strongly excites each cell type, and which features yield the weakest response?
(Points 8)
[ ]: x = np.tile(np.arange(-8,9),(17,1))
y = x.T
s1=3
s2=4
w=0.5
receptive_field = np.exp(-(x*x+y*y)/(2*s1**2)) - w*np.exp(-(x*x+y*y)/(2*s2**2))
YOUR ANSWER HERE for question 7b
Exercise 7c)
Let’s create a second receptive field, the code is below.
1) State which cell type the receptive field best matches, and where in the visual system such cells are found.
2) Describe the roles of the three parameters s, sf and angle. To investigate this, you can change these parameters and visualise the receptive field.
3) Change the provided code to create a receptive field that best responds to horizontalbars/contours and plot the result. Attempt to create a plot that clearly highlights positiveand negative areas (use a diverging colourmap).
(Points 10)
[ ]: x = np.tile(np.arange(-8,9),(17,1))
y = x.T
s = 3.0
sf = 0.8
angle = 0.25*np.pi
receptive_field = np.exp(-(x*x + y*y) / (2 * s**2)) * np.cos(sf * (np.
cos(angle) * x + np.sin(angle) * y))
YOUR ANSWER HERE for questions 7c parts 1-2
[ ]: # YOUR CODE HERE for question 7c part 3
# YOUR CODE HERE
raise NotImplementedError()
Exercise 8a)

Now we will analyse the effect of the receptive fields we considered in question 6 using an image. To this end, we select an image from the ImageNet dataset and convert it to grey scale.

Examine the code below and describe how the image is manipulated. Explain what effect we can simulate with this manipulation (see lectures).

(Points 4)
[ ]: # load the image and convert it to grey scale
import matplotlib.image as mpimg
image_original = mpimg.imread('mouse.jpg')
image_original = np.dot(image_original[...,:3], [0.2989, 0.5870, 0.1140])
plt.subplot(121)
plt.imshow(image_original, cmap=plt.cm.gray)
image = image_original + np.random.normal(scale=100, size=image_original.shape)
plt.subplot(122)
plt.imshow(image, cmap=plt.cm.gray)
YOUR ANSWER HERE for question 8a
Exercise 8b)
Now let’s see what effect the visual receptive fields have on representing the information in the distorted image. To see how a receptive field transforms an image, we use the 2D convolution function in scipy:
from scipy.signal import convolve2d
result = convolve2d(image, receptive_field)
You can then plot the result as usual:
plt.imshow(result, cmap=plt.cm.gray)
Your tasks:
1. First use the receptive field from question 6b above and filter the distorted image with it.
2. What do you observe?
3. As we have seen in the lectures, receptive fields can change depending on context. Change the parameters of the model to obtain a better reconstruction of the original image. Whatstrategy do you follow to achieve this? Now there is not a single good solution, but it ispossible to improve the result over the default model.
(Points 12)
[ ]: # YOUR CODE HERE for question 8b part 1
# YOUR CODE HERE
raise NotImplementedError()
YOUR ANSWER HERE for question 8b part 2
[ ]: # YOUR CODE HERE for question 8b part 3

# YOUR CODE HERE

raise NotImplementedError()

Exercise 8c)
Finally, we simulate two successive stages of image filtering in the visual system. Use the model you found in question 7b to remove noise from the image and use the output of this first neuronpopulation as input for another stage in the visual system:

1. Filter the output of the first convolution (preferably use the parameters you obtained in theprevious question) with the receptive field from question 6c. Show each stage of this process, from raw distorted image to the twice filtered image.

2. Compare a convolution of the distorted image with the second receptive field directly to the two-stage model. What does the two-stage model achieve?
(Points 12)
[ ]: # YOUR CODE HERE for question 8c part 1
# YOUR CODE HERE
raise NotImplementedError()
[ ]: # YOUR CODE HERE for question 8c part 2
# YOUR CODE HERE
raise NotImplementedError()
17

发表评论

电子邮件地址不会被公开。 必填项已用*标注