Advertisement
Guest User

test

a guest
Feb 24th, 2020
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. class stochastic_gradient_descent:
  2. def __init__ (self,
  3. initial_position,
  4. objective_function_handle,
  5. c = 0.25,
  6. beta = 0.0,
  7. sample_count_scale = 3,
  8. max_iter = 60,
  9. max_step_size = 0.25,
  10. stopping_slope = 0.001,
  11. gamma = 0.101,
  12. degrees_of_freedom = 2,
  13. verbose = True):
  14. self.x = initial_position
  15. self.x_old = initial_position
  16.  
  17. self.xs = initial_position.reshape((1,2))
  18. self.w = initial_position
  19. self.objective_function = objective_function_handle
  20.  
  21. self.beta = beta
  22. self.gamma = gamma
  23.  
  24. self.c = c
  25.  
  26. self.dofs = degrees_of_freedom
  27. self.max_iter = max_iter
  28. self.verbose = verbose
  29. self.diffs = 0
  30. self.f_evals = 0
  31. self.multiplier = sample_count_scale
  32. self.k = 0
  33. self.max_step_size = max_step_size
  34. self.stopping_slope = stopping_slope
  35. self.get_angle_scales()
  36.  
  37. def get_angle_scales(self):
  38. self.angle_scales = np.pi * np.ones(self.dofs-1)
  39. self.angle_scales[self.dofs-2] = 2.0 * np.pi
  40.  
  41. def sample_sphere(self):
  42. n = self.multiplier * self.dofs
  43. sample = np.ones((n,self.dofs))
  44. for indx in range(n):
  45. angles = np.random.random(self.dofs-1) * self.angle_scales
  46. for jndx in range(self.dofs-1):
  47. sample[indx,jndx] = sample[indx,jndx] * np.cos(angles[jndx])
  48. for kndx in range(jndx):
  49. sample[indx,jndx] = sample[indx,jndx] * np.sin(angles[kndx])
  50. for jndx in range(self.dofs-1):
  51. sample[indx,self.dofs-1] = sample[indx,self.dofs-1] * np.sin(angles[jndx])
  52. self.sphere_samples = sample
  53.  
  54. def evaluate_sphere_sample(self):
  55. n_samples = self.multiplier * self.dofs
  56. self.w_vals = np.zeros((n_samples, self.dofs))
  57. self.y_raw = np.zeros(n_samples)
  58. ycenters = np.zeros(n_samples+1)
  59. for indx in range(n_samples):
  60. self.w_vals[indx,:] = self.w + self.c_k * self.sphere_samples[indx]
  61. ycenters[indx] = self.objective_function(self.w)
  62. self.y_raw[indx] = self.objective_function(self.w_vals[indx,:])
  63. ycenters[n_samples] = self.objective_function(self.w)
  64. self.y = self.y_raw# - 0.5*(ycenters[0:n_samples] + ycenters[1:n_samples+1])
  65.  
  66. def compute_gradient(self):
  67. n_samples = self.multiplier * self.dofs
  68. self.sample_sphere()
  69. self.evaluate_sphere_sample()
  70. #d_vals = hooks_distance(self.w_vals, self.y)
  71. #mean_d = np.mean(d_vals)
  72. #std_d = np.std(d_vals)
  73. #indices = np.abs(d_vals - mean_d) < 2.5*std_d
  74. #indices = indices.reshape(np.max(indices.shape))
  75. A = np.ones((n_samples,self.dofs+1))
  76. A[:,0:self.dofs] = self.w_vals
  77. #self.gradient = np.linalg.lstsq(self.w_vals[indices,:],self.y[indices],rcond=-1)[0]
  78. #self.gradient =
  79. lstsq_res = np.linalg.lstsq(A,self.y,rcond=-1)[0]
  80. self.gradient = lstsq_res[0:self.dofs]
  81.  
  82. def next_step(self):
  83. self.x = self.beta*self.x_old + self.gradient
  84. if self.k < 1:
  85. self.a_k = 0.00005
  86. self.grad_test = np.array([np.linalg.norm(self.gradient)])
  87. else:
  88. self.a_k = np.linalg.norm(self.x - self.x_old)**2 / np.sum((self.x - self.x_old)*(self.gradient - self.gradient_old))
  89. self.grad_test = np.append(self.grad_test,np.linalg.norm(self.gradient)/self.k)
  90. self.gradient_old = self.gradient
  91. temp = - self.a_k * self.x
  92. tnorm = np.linalg.norm(temp)
  93. if tnorm > self.max_step_size:
  94. self.w = self.w + self.max_step_size * (temp/tnorm)
  95. else:
  96. self.w = self.w + temp
  97.  
  98. def optimize(self):
  99. converged = False
  100. while not converged:
  101. self.c_k = self.c / (((self.k) + 1)**self.gamma)
  102. self.compute_gradient()
  103. self.x_old = self.x
  104. self.next_step()
  105. self.xs = np.append(self.xs, self.w.reshape((1,2)), axis=0)
  106. self.k += 1
  107. converged = self.convergence_criteria()
  108.  
  109. def convergence_criteria(self):
  110. out = False
  111. if self.k > self.max_iter:
  112. out = True
  113. self.reason = "Max Iterations Reached"
  114. num_samples = np.max(np.shape(self.xs))
  115. all_x = self.xs[:,0].reshape((num_samples,))
  116. all_y = self.xs[:,1].reshape((num_samples,))
  117. self.diff_r = np.sqrt((self.xs[:,:]-self.xs[0,:])**2)
  118. self.diff_x = all_x[:]-all_x[0]
  119. self.diff_y = all_y[:]-all_y[0]
  120. self.diff_dx = all_x[1:] - all_x[0:-1]
  121. self.diff_dy = all_y[1:] - all_y[0:-1]
  122. self.diff_dr = np.sqrt((self.diff_dx**2 + self.diff_dy**2))
  123. """
  124. out = False
  125. if self.k > 16:
  126. y_vals = all_y[-15:]
  127. x_vals = all_x[-15:]
  128. r_vals = np.sqrt(x_vals**2 + y_vals**2)
  129. horiz = np.ones((15,2))
  130. horiz[:,0] = np.linspace(0,1,15)
  131. xlstsq = np.linalg.lstsq(horiz,x_vals,rcond=-1)
  132. ylstsq = np.linalg.lstsq(horiz,y_vals,rcond=-1)
  133. rlstsq = np.linalg.lstsq(horiz,r_vals,rcond=-1)
  134. x_slope = xlstsq[0][0]
  135. y_slope = ylstsq[0][0]
  136. outflagxy = (x_slope < self.stopping_slope) and (y_slope < self.stopping_slope)
  137. if outflagxy:
  138. out = True
  139. self.reason = 'Regression'
  140. """
  141. return out
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement