優化算法經常要用到導數、梯度、Hesse矩陣等,因此編寫了一個類用於實現這些功能
建立一個Function類,構造函數的參數是一個函數
其中part的功能是求偏導,var_index表示是第幾個變量,val表示這些變量的值
diff的功能是方便一元函數求導
私有函數__diff_是為了hesse編寫,傳入要求導的變量,返回一個求導后的Function類
hesse函數利用__diff_函數計算Hesse矩陣,返回一個matrix
為方便梯度進行線性代數運算,在定義grad函數時,返回值轉化成了numpy.array類型
1 from numpy import * 2 3 4 class Function: 5 def __init__(self, _f): 6 self.fun = _f 7 8 def value(self, val): 9 return self.fun(val) 10 11 def part(self, var_index, val): 12 a = self.fun(val) 13 b = a + 1 14 i = 0 15 e = 2 ** 10 - 1 16 e1 = 2 ** 10 17 while 10 ** (-6) < e < e1 or i > -6: 18 e1 = e 19 a = b 20 val_ = list(val) 21 val_[var_index] += 10 ** i 22 m = self.fun(val_) 23 n = self.fun(val) 24 b = (m - n) / 10 ** i 25 i -= 2 26 e = abs(b - a) 27 return a 28 29 def part_2(self, x_index, y_index, val): 30 return self.__diff_(x_index).__diff_(y_index).value(val) 31 32 def diff(self, val): 33 a = self.fun(val) 34 b = a + 1 35 i = 0 36 e = 2 ** 10 - 1 37 e1 = 2 ** 10 38 while 10 ** (-6) < e < e1 or i > -6: 39 e1 = e 40 a = b 41 val_ = val + 10 ** i 42 m = self.fun(val_) 43 n = self.fun(val) 44 b = (m - n) / 10 ** i 45 i -= 2 46 e = abs(b - a) 47 return a 48 49 def grad(self, val): 50 g = array(val).astype('float') 51 for i in range(0, g.size): 52 g[i] = self.part(i, val) 53 return array(g) 54 55 def __diff_(self, index): 56 def diff_f(vals): 57 vals_ = list(vals) 58 vals_[index] = vals_[index] + 10 ** (-6) 59 m = self.fun(vals_) 60 n = self.fun(vals) 61 return (m - n) / 10 ** (-6) 62 return Function(diff_f) 63 64 def hesse(self, val): 65 v = mat(val) 66 G = mat(dot(v.T, v)).astype('float') 67 for i in range(0, v.size): 68 for j in range(0, v.size): 69 p = self.part_2(i, j, val) 70 G[i, j] = p 71 return G 72 73 def norm(self, val): 74 s = 0 75 for x in self.grad(val): 76 s += x ** 2 77 return sqrt(s)