Linear regression predicts a number as a weighted sum of the features plus a bias. Gradient descent finds the weights. It computes the gradient of the mean squared error and takes a small step against it, again and again. The same loop trains every model later in the course.
Task
Write four functions.
predict(X, w, b)returns the prediction \hat{y} = Xw + b for each row ofX.compute_cost(X, y, w, b)returns the mean squared error J = \frac{1}{n} \sum_i (\hat{y}_i - y_i)^2.compute_gradients(X, y, w, b)returns the pair(dw, db). Here dw = \frac{2}{n} X^\top (\hat{y} - y) and db = \frac{2}{n} \sum_i (\hat{y}_i - y_i).fit(X, y, learning_rate, epochs)runs batch gradient descent and returns(w, b, cost_history).
The rules for fit:
- Start with
was a vector of zeros andb = 0.0. - In each epoch, compute
dwanddbfrom the currentwandb. Then update both: w \leftarrow w - \eta \, dw and b \leftarrow b - \eta \, db, where \eta islearning_rate. - After the update, append the cost of the new
wandbtocost_history.
Input and output
| Name | Type | Shape | Meaning |
|---|---|---|---|
X |
float array | (n, d) |
one row of d features for each of the n samples |
y |
float array | (n,) |
the target of each sample |
w |
float array | (d,) |
the weights |
b |
float | scalar | the bias |
learning_rate |
float | scalar | the step size \eta, 0 or more |
epochs |
int | scalar | the number of updates, 0 or more |
predictreturns a float array of shape(n,).compute_costreturns a Pythonfloat.compute_gradientsreturns a tuple: a float arraydwof shape(d,)and a floatdb.fitreturns a tuple: a float arraywof shape(d,), a floatband a list ofepochsfloats.
Constraints
1 <= n <= 1000and1 <= d <= 50.0 <= epochs <= 5000.- Do not change the input arrays.
- Use numpy only. Do not use a closed form solution such as
np.linalg.lstsqinfit.
Examples
python
X = np.array([[1.0], [2.0], [3.0], [4.0]])
y = np.array([3.0, 5.0, 7.0, 9.0])
compute_cost(X, y, np.zeros(1), 0.0)
compute_gradients(X, y, np.zeros(1), 0.0)text
41.0
(array([-35.]), -12.0)python
w, b, cost_history = fit(X, y, 0.05, 500)
w, b, len(cost_history), cost_history[0]text
(array([2.00005173]), 0.9998479052895004, 500, 1.1287500000000006)The data lies on the line y = 2x + 1, so w moves close to 2 and b moves close to 1.