# HG changeset patch # User Jeff Hammel # Date 1504553865 25200 # Node ID fa7a51df0d90eab3160daaa6a74e43c4e666d3c1 # Parent ae0c345ea09d3b0e4b741bae91b4efc6c390a4d9 [logistic regression] test gradient descent diff -r ae0c345ea09d -r fa7a51df0d90 tests/test_logistic_regression.py --- a/tests/test_logistic_regression.py Mon Sep 04 12:04:58 2017 -0700 +++ b/tests/test_logistic_regression.py Mon Sep 04 12:37:45 2017 -0700 @@ -12,6 +12,13 @@ class LogisticRegresionTests(unittest.TestCase): + def compare_arrays(self, a, b): + assert a.shape == b.shape + for x, y in zip(a.flatten(), + b.flatten()): + self.assertAlmostEqual(x, y) + + def test_cost(self): """test cost function""" @@ -48,6 +55,28 @@ dw_expected.flatten()): self.assertAlmostEqual(a, b) + def test_optimize(self): + """test gradient descent method""" + + # test examples + w, b, X, Y = np.array([[1],[2]]), 2, np.array([[1,2],[3,4]]), np.array([[1,0]]) + + params, grads, costs = logistic_regression.optimize(w, b, X, Y, num_iterations= 100, learning_rate = 0.009, print_cost = False) + + # expected output + w_expected = np.array([[0.1124579 ], + [0.23106775]]) + dw_expected = np.array([[ 0.90158428], + [ 1.76250842]]) + b_expected = 1.55930492484 + db_expected = 0.430462071679 + + # compare output + self.assertAlmostEqual(params['b'], b_expected) + self.assertAlmostEqual(grads['db'], db_expected) + self.compare_arrays(w_expected, params['w']) + self.compare_arrays(dw_expected, grads['dw']) + if __name__ == '__main__': unittest.main() diff -r ae0c345ea09d -r fa7a51df0d90 tvii/logistic_regression.py --- a/tvii/logistic_regression.py Mon Sep 04 12:04:58 2017 -0700 +++ b/tvii/logistic_regression.py Mon Sep 04 12:37:45 2017 -0700 @@ -81,3 +81,58 @@ A = sigmoid(np.dot(w.T, X) + b) cost = np.sum(Y*np.log(A) + (1 - Y)*np.log(1 - A)) return (-1./m)*cost + + +def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False): + """ + This function optimizes w and b by running a gradient descent algorithm + + Arguments: + w -- weights, a numpy array of size (num_px * num_px * 3, 1) + b -- bias, a scalar + X -- data of shape (num_px * num_px * 3, number of examples) + Y -- true "label" vector (containing 0 if non-cat, 1 if cat), of shape (1, number of examples) + num_iterations -- number of iterations of the optimization loop + learning_rate -- learning rate of the gradient descent update rule + print_cost -- True to print the loss every 100 steps + + Returns: + params -- dictionary containing the weights w and bias b + grads -- dictionary containing the gradients of the weights and bias with respect to the cost function + costs -- list of all the costs computed during the optimization, this will be used to plot the learning curve. + + Tips: + You basically need to write down two steps and iterate through them: + 1) Calculate the cost and the gradient for the current parameters. Use propagate(). + 2) Update the parameters using gradient descent rule for w and b. + """ + + costs = [] + + for i in range(num_iterations): + + # Cost and gradient calculation + grads, cost = propagate(w, b, X, Y) + + # Retrieve derivatives from grads + dw = grads["dw"] + db = grads["db"] + + # gradient descent + w = w - learning_rate*dw + b = b - learning_rate*db + + # Record the costs + if i % 100 == 0: + costs.append(cost) + + # Print the cost every 100 training examples + if print_cost and not (i % 100): + print ("Cost after iteration %i: %f" %(i, cost)) + + # package data for return + params = {"w": w, + "b": b} + grads = {"dw": dw, + "db": db} + return params, grads, costs