Advertisement
Guest User

Untitled

a guest
Apr 20th, 2018
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.62 KB | None | 0 0
  1. import numpy as np
  2. import random
  3. import math
  4.  
  5.  
  6. def l2_loss(Y, predictions):
  7. '''
  8. Computes L2 loss (sum squared loss) between true values, Y, and predictions.
  9.  
  10. :param Y A 1D Numpy array with real values (float64)
  11. :param predictions A 1D Numpy array of the same size of Y
  12. :return L2 loss using predictions for Y.
  13. '''
  14. return np.linalg.norm(Y - predictions) ** 2
  15.  
  16. def sigmoid(x):
  17. '''
  18. Sigmoid function f(x) = 1/(1 + exp(-x))
  19. :param x A scalar or Numpy array
  20. :return Sigmoid function evaluated at x (applied element-wise if it is an array)
  21. '''
  22. return np.where(x > 0, 1 / (1 + np.exp(-x)), np.exp(x) / (np.exp(x) + 1))
  23.  
  24. def sigmoid_derivative(x):
  25. '''
  26. First derivative of the sigmoid function with respect to x.
  27. :param x A scalar or Numpy array
  28. :return Derivative of sigmoid evaluated at x (applied element-wise if it is an array)
  29. '''
  30. return sigmoid(x) * (1 - sigmoid(x))
  31. # return np.where(x > 0, np.exp(-x) / ((1 + np.exp(-x)) ** 2), np.exp(x) / ((np.exp(x) + np.exp(0)) ** 2))
  32.  
  33. class LinearRegression:
  34. '''
  35. LinearRegression model that minimizes squared error using matrix inversion.
  36. '''
  37. def __init__(self):
  38. '''
  39. @attrs:
  40. weights The weights of the linear regression model.
  41. '''
  42. self.weights = None
  43.  
  44. def train(self, X, Y):
  45. '''
  46. Trains the LinearRegression model by finding the optimal set of weights
  47. using matrix inversion.
  48.  
  49. :param X 2D Numpy array where each row contains an example
  50. :param Y 1D Numpy array containing the corresponding values for each example
  51. :return None
  52. '''
  53. A = sum([np.outer(x, x) for x in X])
  54. self.weights = np.matmul(np.linalg.inv(A), sum([x*y for x, y in zip(X, Y)]))
  55.  
  56. def predict(self, X):
  57. '''
  58. Returns predictions of the model on a set of examples X.
  59.  
  60. :param X 2D Numpy array where each row contains an example.
  61. :return A 1D Numpy array with one element for each row in X containing the predicted value.
  62. '''
  63. return np.array([np.dot(self.weights, x) for x in X])
  64.  
  65. def loss(self, X, Y):
  66. '''
  67. Returns the total squared error on some dataset (X, Y).
  68.  
  69. :param X 2D Numpy array where each row contains an example
  70. :param Y 1D Numpy array containing the corresponding values for each example
  71. :return A float which is the squared error of the model on the dataset
  72. '''
  73. predictions = self.predict(X)
  74. return l2_loss(predictions, Y)
  75.  
  76. def average_loss(self, X, Y):
  77. '''
  78. Returns the mean squared error on some dataset (X, Y).
  79.  
  80. MSE = Total squared error/# of examples
  81.  
  82. :param X 2D Numpy array where each row contains an example
  83. :param Y 1D Numpy array containing the corresponding values for each example
  84. :return A float which is the mean squared error of the model on the dataset
  85. '''
  86. return self.loss(X, Y)/X.shape[0]
  87.  
  88. class OneLayerNN:
  89. '''
  90. One layer neural network trained with Stocastic Gradient Descent (SGD)
  91. '''
  92. def __init__(self):
  93. '''
  94. @attrs:
  95. weights The weights of the neural network model.
  96. '''
  97. self.weights = None
  98.  
  99. def train(self, X, Y, learning_rate=0.001, epochs=250, print_loss=True):
  100. '''
  101. Trains the OneLayerNN model using SGD.
  102.  
  103. :param X 2D Numpy array where each row contains an example
  104. :param Y 1D Numpy array containing the corresponding values for each example
  105. :param learning_rate The learning rate to use for SGD
  106. :param epochs The number of times to pass through the dataset
  107. :param print_loss If True, print the loss after each epoch.
  108. :return None
  109. '''
  110. m = len(X)
  111. n = len(X[0])
  112. batch_size = 1
  113. num_batches = int(math.ceil(m / batch_size))
  114.  
  115. zipped = list(zip(X, Y))
  116.  
  117. # X -> (batch_size, n)
  118. # w -> (n, 10)
  119. # dScores -> (batch_size, 10)
  120. # scores -> (batch_size, 10)
  121. self.weights = np.zeros((n, 1))
  122.  
  123. for e in range(epochs):
  124. # print("Epoch " + str(e))
  125. np.random.shuffle(zipped)
  126. batched_X = np.array(np.array_split(np.array([i[0] for i in zipped]), num_batches))
  127. batched_Y = np.array(np.array_split(np.array([i[1] for i in zipped]), num_batches))
  128. for i in range(len(batched_X)):
  129. X_ = batched_X[i]
  130. Y_ = batched_Y[i]
  131. scores = np.matmul(X_, self.weights)
  132. Y_scores = np.array([np.array([y]) for y in Y_], dtype=float)
  133. errors = (scores - Y_scores)
  134. dW = np.matmul(X_.T, errors)
  135. self.weights += (-learning_rate * dW)
  136.  
  137. def predict(self, X):
  138. '''
  139. Returns predictions of the model on a set of examples X.
  140.  
  141. :param X 2D Numpy array where each row contains an example.
  142. :return A 1D Numpy array with one element for each row in X containing the predicted value.
  143. '''
  144. return np.array([row[0] for row in np.matmul(X, self.weights)])
  145.  
  146. def loss(self, X, Y):
  147. '''
  148. Returns the total squared error on some dataset (X, Y).
  149.  
  150. :param X 2D Numpy array where each row contains an example
  151. :param Y 1D Numpy array containing the corresponding values for each example
  152. :return A float which is the squared error of the model on the dataset
  153. '''
  154. predictions = self.predict(X)
  155. return l2_loss(predictions, Y)
  156.  
  157. def average_loss(self, X, Y):
  158. '''
  159. Returns the mean squared error on some dataset (X, Y).
  160.  
  161. MSE = Total squared error/# of examples
  162.  
  163. :param X 2D Numpy array where each row contains an example
  164. :param Y 1D Numpy array containing the corresponding values for each example
  165. :return A float which is the mean squared error of the model on the dataset
  166. '''
  167. return self.loss(X, Y)/X.shape[0]
  168.  
  169. def accuracy(self, X, Y):
  170. cnt = 0.0
  171. test_Y = Y
  172. pred = self.predict(X)
  173. for i in range(0, len(test_Y)):
  174. if test_Y[i] == pred[i]:
  175. cnt += 1
  176. return float(cnt/len(X))
  177.  
  178.  
  179. class TwoLayerNN:
  180.  
  181. def __init__(self, hidden_size, activation=sigmoid, activation_derivative=sigmoid_derivative):
  182. '''
  183. @attrs:
  184. activation: the activation function applied after the first layer
  185. activation_derivative: the derivative of the activation function. Used for training.
  186. hidden_size: The hidden size of the network (an integer)
  187. output_neurons: The number of outputs of the network
  188. '''
  189. self.activation = activation
  190. self.activation_derivative = activation_derivative
  191. self.hidden_size = hidden_size
  192.  
  193. # In this assignment, we will only use output_neurons = 1.
  194. self.output_neurons = 1
  195.  
  196. # These are the learned parameters for the 2-Layer NN you will implement
  197. self.hidden_weights = None
  198. self.hidden_bias = None
  199. self.output_weights = None
  200. self.output_bias = None
  201.  
  202. def train(self, X, Y, learning_rate=0.01, epochs=1000, print_loss=True):
  203. '''
  204. Trains the TwoLayerNN with SGD using Backpropagation.
  205.  
  206. :param X 2D Numpy array where each row contains an example
  207. :param Y 1D Numpy array containing the corresponding values for each example
  208. :param learning_rate The learning rate to use for SGD
  209. :param epochs The number of times to pass through the dataset
  210. :param print_loss If True, print the loss after each epoch.
  211. :return None
  212. '''
  213. m = len(X)
  214. n = len(X[0])
  215. batch_size = 1
  216. num_batches = int(math.ceil(m / batch_size))
  217.  
  218. zipped = list(zip(X, Y))
  219.  
  220. self.hidden_weights = .1 * np.random.randn(n, self.hidden_size) # (n, hs)
  221. self.hidden_bias = .1 * np.random.randn(1, self.hidden_size) # (1, hs)
  222. self.output_weights = .1 * np.random.randn(self.hidden_size, self.output_neurons) # (hs, 1)
  223. self.output_bias = .1 * np.random.randn(self.output_neurons, 1) # (1, 1)
  224.  
  225. for e in range(epochs):
  226. # print("Epoch " + str(e))
  227. np.random.shuffle(zipped)
  228. batched_X = np.array(np.array_split(np.array([i[0] for i in zipped]), num_batches))
  229. batched_Y = np.array(np.array_split(np.array([i[1] for i in zipped]), num_batches))
  230. for i in range(len(batched_X)):
  231. X_ = batched_X[i] # (bs, n)
  232. Y_ = batched_Y[i] # (bs)
  233. bs = len(X_)
  234.  
  235. # (bs, hs)
  236. hidden_outputs = np.matmul(X_, self.hidden_weights) + np.matmul(np.ones((bs, 1)), self.hidden_bias)
  237. # (bs, hs)
  238. hidden_activation = self.activation(hidden_outputs)
  239. # (bs, 1)
  240. scores = np.matmul(hidden_activation, self.output_weights) + np.matmul(np.ones((bs, 1)), self.output_bias)
  241.  
  242. labels = np.array([np.array([y]) for y in Y_], dtype=float) # (bs, 1)
  243.  
  244. errors = (scores - labels) # (bs, 1)
  245. dWo = np.matmul(hidden_activation.T, errors) # (hs, bs) * (bs, 1) => (hs, 1)
  246. dbo = np.sum(errors, axis=0, keepdims=True) # (1, 1)
  247.  
  248. hidden_dsigmoid = self.activation_derivative(hidden_outputs) # (bs, hs)
  249. hidden_errors = np.multiply(np.matmul(errors, self.output_weights.T), hidden_dsigmoid) # (bs, hs)
  250. dWh = np.matmul(X_.T, hidden_errors) # (n, hs)
  251. dbh = np.sum(hidden_errors, axis=0, keepdims=True) # (1, hs)
  252.  
  253. self.hidden_weights += 2 * (-learning_rate * dWh)
  254. self.hidden_bias += 2 * (-learning_rate * dbh)
  255. self.output_weights += 2 * (-learning_rate * dWo)
  256. self.output_bias += 2 * (-learning_rate * dbo)
  257.  
  258. def predict(self, X):
  259. '''
  260. Returns predictions of the model on a set of examples X.
  261.  
  262. :param X 2D Numpy array where each row contains an example.
  263. :return A 1D Numpy array with one element for each row in X containing the predicted value.
  264. '''
  265.  
  266. hidden_outputs = np.matmul(X, self.hidden_weights) + np.matmul(np.ones((len(X), 1)), self.hidden_bias)
  267. hidden_activation = self.activation(hidden_outputs)
  268. scores = np.matmul(hidden_activation, self.output_weights) + np.matmul(np.ones((len(X), 1)), self.output_bias)
  269.  
  270. return scores.flatten()
  271.  
  272. def loss(self, X, Y):
  273. '''
  274. Returns the total squared error on some dataset (X, Y).
  275.  
  276. :param X 2D Numpy array where each row contains an example
  277. :param Y 1D Numpy array containing the corresponding values for each example
  278. :return A float which is the squared error of the model on the dataset
  279. '''
  280. predictions = self.predict(X)
  281.  
  282. # print(predictions[:10], Y[:10])
  283. # print(l2_loss(predictions, Y))
  284. return l2_loss(predictions, Y)
  285.  
  286. def average_loss(self, X, Y):
  287. '''
  288. Returns the mean squared error on some dataset (X, Y).
  289.  
  290. MSE = Total squared error/# of examples
  291.  
  292. :param X 2D Numpy array where each row contains an example
  293. :param Y 1D Numpy array containing the corresponding values for each example
  294. :return A float which is the mean squared error of the model on the dataset
  295. '''
  296. return self.loss(X, Y)/X.shape[0]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement