Guest User

Untitled

a guest
Mar 21st, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. import numpy as np
  2. import abc
  3.  
  4. class Operation(abc.ABC):
  5. def __init__(self, x, parameter=None):
  6. self.x = x
  7. self.parameter = parameter
  8. self.z = None
  9.  
  10. def f(self):
  11. self.z = self.o()
  12. return self.z
  13.  
  14. @abc.abstractmethod
  15. def o(self):
  16. pass
  17.  
  18. def gradient_by_parameter(self):
  19. pass
  20.  
  21. def gradient_by_input(self):
  22. pass
  23.  
  24.  
  25. class Dot(Operation):
  26. def __init__(self, x, parameter=None):
  27. super(Dot, self).__init__(x, parameter)
  28.  
  29. def o(self):
  30. return np.dot(self.parameter, self.x)
  31.  
  32. def gradient_by_input(self):
  33. return self.parameter
  34.  
  35. def gradient_by_parameter(self):
  36. m = self.parameter.shape[0]
  37. n = self.parameter.shape[1]
  38. gradient = np.empty((m, m, n))
  39. #print(gradient.shape)
  40. for i in range(0, m):
  41. gradient[i] = np.zeros((m, n))
  42. gradient[i, i] = self.x.T
  43. return gradient
  44.  
  45.  
  46. class Add(Operation):
  47. def __init__(self, x, parameter=None):
  48. super(Add, self).__init__(x, parameter)
  49.  
  50. def o(self):
  51. return np.add(self.x, self.parameter)
  52.  
  53. def gradient_by_input(self):
  54. n = self.x.shape[0]
  55. return np.eye(n)
  56.  
  57. def gradient_by_parameter(self):
  58. n = self.x.shape[0]
  59. return np.eye(n)
  60.  
  61.  
  62. class Relu(Operation):
  63. def __init__(self, x, parameter=None):
  64. super(Relu, self).__init__(x, parameter)
  65.  
  66. def o(self):
  67. return np.maximum(0, self.x)
  68.  
  69. def gradient_by_input(self):
  70. y = self.z
  71. y[y > 0] = 1
  72. y[y <= 0] = 0
  73. return y
  74.  
  75.  
  76. class Square(Operation):
  77. def __init__(self, x, parameter=None):
  78. super(Square, self).__init__(x, parameter)
  79.  
  80. def o(self):
  81. return np.dot(self.x, self.x)
  82.  
  83. def gradient_by_input(self):
  84. return 2 * self.x.T
  85.  
  86.  
  87. class Sub(Operation):
  88. def __init__(self, x, parameter=None):
  89. super(Sub, self).__init__(x, parameter)
  90.  
  91. def o(self):
  92. return np.subtract(self.x, self.parameter)
  93.  
  94. def gradient_by_input(self):
  95. n = self.x.shape[0]
  96. return np.eye(n)
  97.  
  98.  
  99. class CrossEntropyLoss(Operation):
  100. def __init__(self, x, parameter=None):
  101. super(CrossEntropyLoss, self).__init__(x, parameter)
  102.  
  103. def o(self):
  104. return - np.sum(np.multiply(self.parameter, np.log(self.x))
  105. + np.multiply((1 - self.parameter), np.log(1 - self.x)))
  106.  
  107. def gradient_by_input(self):
  108. return np.divide(np.subtract(self.x, self.parameter), np.multiply(y, 1-y))
  109.  
  110. X = np.array([[0, 0], [1, 1], [0, 1], [1, 0]])
  111. Y = np.array([0, 0, 1, 1])
  112.  
  113. W1 = np.random.random((1, 2))
  114. b1 = np.random.random((1,1))
  115. b2 = np.random.random((1,1))
  116.  
  117. for i in range(10):
  118.  
  119. x = X[i%4, :].reshape(X.shape[1], 1)
  120. y = Y[i%4]
  121.  
  122.  
  123. ## forward
  124. def forw_back(x, y, W1, b1):
  125. operations = []
  126. dot1 = Dot(x, W1)
  127. z1d = dot1.f()
  128.  
  129. operations.append(dot1)
  130.  
  131. add1 = Add(z1d, b1)
  132. operations.append(add1)
  133. z1a = add1.f()
  134.  
  135. relu1 = Relu(z1a)
  136. operations.append(relu1)
  137. y_ = relu1.f()
  138.  
  139. add2 = Add(y_, b2)
  140. operations.append(add2)
  141. y_2 = add2.f()
  142.  
  143. print(y, y_2[0])
  144. ## loss
  145. sub1 = Sub(y_2, y)
  146. operations.append(sub1)
  147. L = sub1.f()
  148. square1 = Square(L)
  149. operations.append(square1)
  150. L2 = square1.f()
  151.  
  152.  
  153.  
  154. ## backprop
  155. L2_g = square1.gradient_by_input()
  156. L_g = sub1.gradient_by_input()
  157. y_2g = add2.gradient_by_input()
  158. y_g = relu1.gradient_by_input()
  159. z1a_g = add1.gradient_by_input()
  160. z1a_gb = add1.gradient_by_parameter()
  161. z1d_g = dot1.gradient_by_parameter()
  162.  
  163. backprop_b = np.dot(np.dot(np.dot(L2_g, L_g), y_g), z1a_gb)
  164. backprop_w = np.dot(np.dot(np.dot(np.dot(L2_g, L_g), y_g), z1a_g), z1d_g)
  165.  
  166. ## weight update
  167. alpha = 1
  168. W1 = W1 - alpha*backprop_w
  169. b1 = b1 - alpha*backprop_b
  170. return W1[0], b1
  171.  
  172. W1, b1 = forw_back(x, y, W1, b1)
  173. print(W1)
  174.  
  175. def forw(x, W1, b1):
  176. dot1 = Dot(x, W1)
  177. z1d = dot1.f()
  178.  
  179. add1 = Add(z1d, b1)
  180. z1a = add1.f()
  181.  
  182. relu1 = Relu(z1a)
  183. y_ = relu1.f()
  184.  
  185. return y
  186.  
  187. for i in range(4):
  188. x = X[i, :].reshape(X.shape[1], 1)
  189. print("x: ", x.T, "y=", forw(x, W1, b1))
Add Comment
Please, Sign In to add comment