DatStorm

Untitled

Sep 26th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.70 KB | None | 0 0
  1. import numpy as np
  2. from h1_util import numerical_grad_check
  3.  
  4.  
  5. def softmax(X):
  6.     """
  7.    Compute the softmax of each row of an input matrix (2D numpy array).
  8.    
  9.    the numpy functions amax, log, exp, sum may come in handy as well as the keepdims=True option and the axis option.
  10.    Remember to handle the numerical problems as discussed in the description.
  11.    You should compute lg softmax first and then exponentiate
  12.    
  13.    More precisely this is what you must do.
  14.    
  15.    For each row x do:
  16.    compute max of x
  17.    compute the log of the denominator sum for softmax but subtracting out the max i.e (log sum exp x-max) + max
  18.    compute log of the softmax: x - logsum
  19.    exponentiate that
  20.    
  21.    You can do all of it without for loops using numpys vectorized operations.
  22.  
  23.    Args:
  24.        X: numpy array shape (n, d) each row is a data point
  25.    Returns:
  26.        res: numpy array shape (n, d)  where each row is the softmax transformation of the corresponding row in X i.e res[i, :] = softmax(X[i, :])
  27.    """
  28.     res = np.zeros(X.shape)
  29.     toAssert = res
  30.     ### YOUR CODE HERE no for loops please
  31.     # max = np.amax(X, keepdims=True)
  32.     # logsum = (np.log(np.sum(np.exp(X - max), keepdims=True))) + max  # TODO: FEJLER!!!
  33.     # res = np.exp(X - logsum)
  34.  
  35.     max = np.amax(X, axis=1, keepdims=True)
  36.     exp = np.exp(X - max)
  37.     np_sum = np.sum(exp, axis=1, keepdims=True)
  38.     logsum = np.log(np_sum) + max
  39.     res = np.exp(X - logsum)
  40.  
  41.     # res = res / np.sum(res, axis=1).reshape(res.shape[0], 1)
  42.  
  43.     # e_x = np.exp(X - np.max(X))
  44.     # res = e_x / e_x.sum(axis=0)
  45.  
  46.     assert toAssert.shape == res.shape, "Shapes mitch match in softmax. Expected {0} - Got {1}".format(toAssert, res)
  47.     ### END CODE
  48.     return res
  49.  
  50.  
  51. def one_in_k_encoding(vec, k):
  52.     """ One-in-k encoding of vector to k classes
  53.    
  54.    Args:
  55.       vec: numpy array - data to encode
  56.       k: int - number of classes to encode to (0,...,k-1)
  57.    """
  58.     n = vec.shape[0]
  59.     enc = np.zeros((n, k))
  60.     enc[np.arange(n), vec] = 1
  61.     return enc
  62.  
  63.  
  64. class SoftmaxClassifier():
  65.  
  66.     def __init__(self, num_classes):
  67.         self.num_classes = num_classes
  68.         self.W = None
  69.  
  70.     def cost_grad(self, X, y, W):
  71.         """
  72.                Compute the average cross entropy cost and the gradient under the softmax model
  73.                using data X, Y and weight vector W.
  74.  
  75.                the functions np.nonzero, np.sum, np.dot (@), may come in handy
  76.                Args:
  77.                   X: numpy array shape (n, d) float - the data each row is a data point
  78.                   y: numpy array shape (n, ) int - target values in 0,1,...,k-1
  79.                   W: numpy array shape (d x K) float - weight matrix
  80.                Returns:
  81.                    totalcost: Average Negative Log Likelihood of w
  82.                    gradient: The gradient of the average Negative Log Likelihood at w
  83.        """
  84.         cost = np.nan
  85.         grad = np.zeros(W.shape) * np.nan
  86.         toAssert = grad
  87.         Yk = one_in_k_encoding(y, self.num_classes)  # may help - otherwise you may remove it
  88.         ### YOUR CODE HERE
  89.         # np.argmax(x.T @ W)
  90.  
  91.         d = np.ma.size(X, axis=1)
  92.         N = len(X)
  93.         grad = -(1 / N) * X.T @ (Yk - softmax(X @ W))
  94.         # gradTest = np.array(- (1 / N) * X.T * (Yk - softmax(X @ W)))
  95.  
  96.         assert toAssert.shape == grad.shape, "Shapes mitch match in cost_grad. Expected {0} - Got {1}".format(toAssert,
  97.                                                                                                               grad)
  98.         sum = 0
  99.         for i in range(N):
  100.             # test += y.T[i] * np.log(softmax(np.dot(X.T[i], W)))
  101.             resSoftmax = softmax(X[i].reshape(d, 1).T @ W)
  102.             sum += Yk[i].T * np.log(resSoftmax)
  103.             # test += np.mean(y.T @ np.log(softmax(X @ W)))  # TODO: FEJLEN LIGGER BLANDT ANDET I SOFTMAX
  104.  
  105.             # FIXME: Skal det være X[i].T eller X.T[i]
  106.             # test = 10
  107.  
  108.         cost = - sum
  109.         ### END CODE
  110.         return cost.mean(), grad
  111.  
  112.     def fit(self, X, Y, W=None, lr=0.01, epochs=10, batch_size=16):
  113.         """
  114.        Run Mini-Batch Gradient Descent on data X,Y to minimize the in sample error (1/n)NLL for softmax regression.
  115.        Printing the performance every epoch is a good idea to see if the algorithm is working
  116.  
  117.        Args:
  118.           X: numpy array shape (n, d) - the data each row is a data point
  119.           Y: numpy array shape (n,) int - target labels numbers in {0, 1,..., k-1}
  120.           W: numpy array shape (d x K)
  121.           lr: scalar - initial learning rate
  122.           batchsize: scalar - size of mini-batch
  123.           epochs: scalar - number of iterations through the data to use
  124.  
  125.        Sets:
  126.           W: numpy array shape (d, K) learned weight vector matrix  W
  127.           history: list/np.array len epochs - value of cost function after every epoch. You know for plotting
  128.        """
  129.         if W is None:
  130.             W = np.zeros((X.shape[1], self.num_classes))
  131.         history = []
  132.         ### YOUR CODE HERE
  133.  
  134.         b = batch_size
  135.         for i in range(1, epochs):
  136.             perm = np.random.permutation(len(X))
  137.  
  138.             # Split into buckets of size b
  139.             batches = [perm[i:i + b] for i in range(0, len(perm), b)]
  140.  
  141.             cost = 0
  142.             for _, batch in enumerate(batches):
  143.                 xs = np.array([X[index] for index in batch])
  144.                 ys = np.array([Y[index] for index in batch])
  145.                 # print(xs)
  146.                 cost, grad = self.cost_grad(xs, ys, W)
  147.  
  148.                 W = W - lr * (1 / len(batch)) * grad
  149.                 # print("w after", w)
  150.  
  151.             # Calculate the cost over all datapoints, to get a better history
  152.             # Remove for better effeciency
  153.             cost, grad = self.cost_grad(X, Y, W)  # TODO: remove?
  154.             history.append(cost)
  155.  
  156.         ### END CODE
  157.         self.W = W
  158.         self.history = history
  159.  
  160.     def score(self, X, Y):
  161.         """ Compute accuracy of classifier on data X with labels Y
  162.  
  163.        Args:
  164.           X: numpy array shape (n, d) - the data each row is a data point
  165.           Y: numpy array shape (n,) int - target labels numbers in {0, 1,..., k-1}
  166.        Returns:
  167.           out: float - accuracy
  168.        """
  169.         out = 0
  170.         # print("S", self.predict(X))
  171.         ### YOUR CODE HERE 1-4 lines
  172.         classPrediction = np.argmax(self.predict(X), axis=1)
  173.         out = np.equal(classPrediction, Y).mean()
  174.         # print("S", self.predict(X))
  175.         ### END CODE
  176.         return out
  177.  
  178.     def predict(self, X):
  179.         """ Compute classifier prediction on each data point in X
  180.  
  181.        Args:
  182.           X: numpy array shape (n, d) - the data each row is a data point
  183.        Returns
  184.           out: np.array shape (n, ) - prediction on each data point (number in 0,1,..., num_classes
  185.        """
  186.         out = np.zeros(X.shape[0])
  187.         ### YOUR CODE HERE - 1-4 lines
  188.         out = softmax(X @ self.W)
  189.         ### END CODE
  190.         return out
  191.  
  192.  
  193. def test_encoding():
  194.     print('*' * 10, 'Test one-in-k Encoding\n')
  195.     labels = np.array([0, 2, 1, 1])
  196.     m = one_in_k_encoding(labels, 3)
  197.     res = np.array([[1, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 0]])
  198.     assert res.shape == m.shape, 'encoding shape mismatch'
  199.     assert np.allclose(m, res), m - res
  200.     print('Test Passed - Encoding')
  201.  
  202.  
  203. def test_softmax():
  204.     print('*' * 5, 'Test softmax\n')
  205.     X = np.zeros((3, 2))
  206.     X[0, 0] = np.log(4)
  207.     X[1, 1] = np.log(2)
  208.     print('Input to Softmax: \n', X)
  209.     sm = softmax(X)
  210.     expected = np.array([[4.0 / 5.0, 1.0 / 5.0], [1.0 / 3.0, 2.0 / 3.0], [0.5, 0.5]])
  211.     print('Result of softmax: \n', sm)
  212.     assert np.allclose(expected, sm), 'Expected {0} - got {1}'.format(expected, sm)
  213.     print('Test complete SOFTMAX')
  214.  
  215.  
  216. def test_grad():
  217.     print('*' * 5, 'Testing  Gradient\n')
  218.     X = np.array([[1.0, 0.0], [1.0, 1.0], [1.0, -1.0]])
  219.     w = np.ones((2, 3))
  220.     y = np.array([0, 1, 2])
  221.     scl = SoftmaxClassifier(num_classes=3)
  222.     f = lambda z: scl.cost_grad(X, y, W=z)
  223.     numerical_grad_check(f, w)
  224.     print('Test Success - GRAD')
  225.  
  226.  
  227. if __name__ == "__main__":
  228.     test_encoding()  # 1
  229.     test_softmax()  # 2
  230.     test_grad()  # 3
  231.  
  232. """ FRAKLIP
  233. # np.argmax(x.T @ W)
  234. # gradTest = np.array(- (1 / N) * X.T * (Yk - softmax(X @ W)))
  235. # assert grad.shape == gradTest.shape # OWN TEST
  236. # test += y.T[i] * np.log(softmax(np.dot(X.T[i], W)))  # TODO: FEJLEN LIGGER BLANDT ANDET I SOFTMAX
  237. # resSoftmax = softmax(X[i].T @ W)
  238. # print(resSoftmax)
  239. # print()
  240. # test += np.mean(y.T @ np.log(softmax(X @ W)))  # TODO: FEJLEN LIGGER BLANDT ANDET I SOFTMAX
  241.  
  242. # FIXME: Skal det være X[i].T eller X.T[i]
  243. # test = 10
  244.  
  245.  
  246.  
  247. """
Advertisement
Add Comment
Please, Sign In to add comment