changeset 31:fa7a51df0d90

[logistic regression] test gradient descent
author Jeff Hammel <k0scist@gmail.com>
date Mon, 04 Sep 2017 12:37:45 -0700
parents ae0c345ea09d
children 0f29b02f4806
files tests/test_logistic_regression.py tvii/logistic_regression.py
diffstat 2 files changed, 84 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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()
--- 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