梯度寻优

参考:梯度下降算法的Python实现

  1. 批量梯度下降:
for i in range(nb_epochs):
    params_grad = evaluate_gradient(loss_function, data, params)
    params = params - learning_rate * params_grad  

在上述代码中,nb_epochs为迭代次数;data是所有的数据;params_grad是每一个权系数的梯度方向,显然它是一个向量;learning_rate * params_grad 就是权系数要改变的量。

  1. 随机梯度下降:
for i in range(nb_epochs):
    np.random.shuffle(data)
    for example in data:
        params_grad = evaluate_gradient(loss_function, example, params)
        params = params - learning_rate * params_grad

参考上面的代码,data变成了example ,所以BGD变成了SGD。

  1. 小批量梯度下降:
for i in range(nb_epochs):
  np.random.shuffle(data)
  for batch in get_batches(data, batch_size=50):
    params_grad = evaluate_gradient(loss_function, batch, params)
    params = params - learning_rate * params_grad

这次变成了batch,所以就是Mini-batch gradient descent了

import tensorflow as tf
import numpy as np
x = (np.linspace(0, 10, 100))
y_ = x + np.random.normal(0, 1, 100)
x = tf.to_float(np.matrix(x).T)
y_ = tf.to_float(np.matrix(y_).T)

w = tf.Variable(0.000001 + tf.random_normal([1, 100]), name = 'w')
b = tf.Variable(tf.constant([0.000001], dtype= tf.float32), name= 'b')

y = tf.matmul(x, w) + b
loss = tf.reduce_mean(tf.square(y - y_))
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss) # vanilla策略(普通的梯度更新策略)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(20):
        sess.run(train_op)
        print(sess.run(loss))
64.7117
63.0106
61.3772
59.8085
58.3013
56.853
55.4606
54.1218
52.8338
51.5945
50.4017
49.253
48.1467
47.0807
46.0532
45.0625
44.1069
43.1848
42.2948
41.4355

自适应梯度更新策略

train_Ad = tf.train.AdagradOptimizer(0.7).minimize(loss) 

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(20):
        sess.run(train_Ad)
        print(sess.run(loss))
26.4333
14.6923
9.53683
6.81778
5.21666
4.19792
3.51116
3.0272
2.67413
2.40928
2.20603
2.04696
1.92032
1.81791
1.73391
1.66406
1.60525
1.55513
1.51194
1.47433

动量更新策略

train_mov = tf.train.MomentumOptimizer(0.01, 0.04).minimize(loss)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(20):
        sess.run(train_mov)
        print(sess.run(loss))
65.0046
63.2387
61.5431
59.9169
58.3569
56.8599
55.4229
54.043
52.7175
51.4437
50.2192
49.0416
47.9088
46.8186
45.7689
44.7581
43.7841
42.8453
41.9401
41.0669

求导示例

import tensorflow as tf

w1 = tf.Variable([[1,2]])
w2 = tf.Variable([[3,4]])

res = tf.matmul(w1, [[2],[1]])

grads = tf.gradients(res,[w1])

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    re = sess.run(grads)
    print(re)
[array([[2, 1]])]

改进的动量更新策略

(Nesterov Accelerated Gradient, NAG)
(这个算法编写的程序好像有点问题,暂时无法解决)

import numpy as np
import tensorflow as tf

def grads(x):
    '''求解损失函数loss的梯度'''
    return tf.gradients(loss, x)[0]

x = (np.linspace(0, 10, 100))
y_ = x + np.random.normal(0, 1, 100)
x = tf.to_float(np.matrix(x).T)
y_ = tf.to_float(np.matrix(y_).T)

w = tf.Variable(tf.random_normal([1, 100], seed = 1), name = 'w')
b = tf.Variable(tf.constant([0.000001], dtype= tf.float32), name= 'b')
y = tf.matmul(x, w) + b
loss = tf.reduce_mean(tf.square(y - y_))

def train_op_NAG(lr, mu):
    dw, db = tf.gradients(loss, [w, b])
    
    tf.assign(w, w - mu * dw)
    tf.assign(b, b - mu * db)
    
    v1 = mu * dw + lr * tf.gradients(loss, w)[0]
    v2 = mu * db + lr * tf.gradients(loss, b)[0]
    
    tf.assign(w, w - v1)
    tf.assign(b, b - v2)
    
    return w, b
lr = 0.5   # 学习率
mu = 0.1 # 动量系数

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(1000):
        sess.run(train_op_NAG(lr, mu))
        if i % 100 == 0:
            print(sess.run(loss))
86.0236
86.0236
86.0236
86.0236

共轭梯度

import sympy,numpy  
import math  
import matplotlib.pyplot as pl  
from mpl_toolkits.mplot3d import Axes3D as ax3  

#共轭梯度法FR、PRP两种格式  
def CG_FR(x0,N,E,f,f_d):  
    X=x0;Y=[];Y_d=[];  
    n = 1  
    ee = f_d(x0)  
    e=(ee[0]**2+ee[1]**2)**0.5  
    d=-f_d(x0)  
    Y.append(f(x0)[0,0]);Y_d.append(e)  
    a=sympy.Symbol('a',real=True)  
    print('第%2s次迭代:e=%f' % (n, e))  
    while nE:  
        n=n+1  
        g1=f_d(x0)  
        f1=f(x0+a*f_d(x0))  
        a0=sympy.solve(sympy.diff(f1[0,0],a,1))  
        x0=x0-d*a0  
        X=numpy.c_[X,x0];Y.append(f(x0)[0,0])  
        ee = f_d(x0)  
        e = math.pow(math.pow(ee[0,0],2)+math.pow(ee[1,0],2),0.5)  
        Y_d.append(e)  
        g2=f_d(x0)  
        beta=(numpy.dot(g2.T,g2))/numpy.dot(g1.T,g1)  
        d=-f_d(x0)+beta*d  
        print('第%2s次迭代:e=%f'%(n,e))  
    return X,Y,Y_d  
def CG_PRP(x0,N,E,f,f_d):  
    X=x0;Y=[];Y_d=[];  
    n = 1  
    ee = f_d(x0)  
    e=(ee[0]**2+ee[1]**2)**0.5  
    d=-f_d(x0)  
    Y.append(f(x0)[0,0]);Y_d.append(e)  
    a=sympy.Symbol('a',real=True)  
    print('第%2s次迭代:e=%f' % (n, e))  
    while nE:  
        n=n+1  
        g1=f_d(x0)  
        f1=f(x0+a*f_d(x0))  
        a0=sympy.solve(sympy.diff(f1[0,0],a,1))  
        x0=x0-d*a0  
        X=numpy.c_[X,x0];Y.append(f(x0)[0,0])  
        ee = f_d(x0)  
        e = math.pow(math.pow(ee[0,0],2)+math.pow(ee[1,0],2),0.5)  
        Y_d.append(e)  
        g2=f_d(x0)  
        beta=(numpy.dot(g2.T,g2-g1))/numpy.dot(g1.T,g1)  
        d=-f_d(x0)+beta*d  
        print('第%2s次迭代:e=%f'%(n,e))  
    return X,Y,Y_d  
if __name__=='__main__':  
    ''''' 
    G=numpy.array([[21.0,4.0],[4.0,15.0]]) 
    #G=numpy.array([[21.0,4.0],[4.0,1.0]]) 
    b=numpy.array([[2.0],[3.0]]) 
    c=10.0 
    x0=numpy.array([[-10.0],[100.0]]) 
    '''  
      
    m=4  
    T=6*numpy.eye(m)  
    T[0,1]=-1;T[m-1,m-2]=-1  
    for i in range(1,m-1):  
        T[i,i+1]=-1  
        T[i,i-1]=-1  
    W=numpy.zeros((m**2,m**2))  
    W[0:m,0:m]=T  
    W[m**2-m:m**2,m**2-m:m**2]=T  
    W[0:m,m:2*m]=-numpy.eye(m)  
    W[m**2-m:m**2,m**2-2*m:m**2-m]=-numpy.eye(m)  
    for i in range(1,m-1):  
        W[i*m:(i+1)*m,i*m:(i+1)*m]=T  
        W[i*m:(i+1)*m,i*m+m:(i+1)*m+m]=-numpy.eye(m)  
        W[i*m:(i+1)*m,i*m-m:(i+1)*m-m]=-numpy.eye(m)  
    mm=m**2  
    mmm=m**3  
    G=numpy.zeros((mmm,mmm))  
    G[0:mm,0:mm]=W;G[mmm-mm:mmm,mmm-mm:mmm]=W;  
    G[0:mm,mm:2*mm]=-numpy.eye(mm)  
    G[mmm-mm:mmm,mmm-2*mm:mmm-mm]=-numpy.eye(mm)  
    for i in range(1,m-1):  
        G[i*mm:(i+1)*mm,i*mm:(i+1)*mm]=W  
        G[i*mm:(i+1)*mm,i*mm-mm:(i+1)*mm-mm]=-numpy.eye(mm)  
        G[i*mm:(i+1)*mm,i*mm+mm:(i+1)*mm+mm]=-numpy.eye(mm)  
    x_goal=numpy.ones((mmm,1))  
    b=-numpy.dot(G,x_goal)  
    c=0  
    f = lambda x: 0.5 * (numpy.dot(numpy.dot(x.T, G), x)) + numpy.dot(b.T, x) + c  
    f_d = lambda x: numpy.dot(G, x) + b  
    x0=x_goal+numpy.random.rand(mmm,1)*100  
    N=100  
    E=10**(-6)  
    print('共轭梯度PR')  
    X1, Y1, Y_d1=CG_FR(x0,N,E,f,f_d)  
    print('共轭梯度PBR') 
    X2, Y2, Y_d2=CG_PRP(x0,N,E,f,f_d)  
    figure1=pl.figure('trend')  
    n1=len(Y1)  
    n2=len(Y2)  
    x1=numpy.arange(1,n1+1)  
    x2=numpy.arange(1,n2+1)  
         
    pl.semilogy(x1,Y1,'r*',markersize=10,label='CG-FR:'+str(n1))  
    pl.semilogy(x2,Y2,'b*',markersize=10,label='CG-PRP:'+str(n2))  
    pl.legend()  
    #图像显示了两种种不同的方法各自迭代的次数与最优值变化情况,共轭梯度方法是明显优于最速下降法的  
    pl.xlabel('n')  
    pl.ylabel('f(x)')  
    pl.show()  
共轭梯度PR
第 1次迭代:e=258.635139
第 2次迭代:e=139.441695
第 3次迭代:e=19.041089
第 4次迭代:e=41.066524
第 5次迭代:e=8.338590
第 6次迭代:e=6.293510
第 7次迭代:e=4.064956
第 8次迭代:e=2.434763
第 9次迭代:e=0.479482
第10次迭代:e=0.788652
第11次迭代:e=0.361512
第12次迭代:e=0.254609
第13次迭代:e=0.168094
第14次迭代:e=0.144135
第15次迭代:e=0.099708
第16次迭代:e=0.127521
第17次迭代:e=0.078925
第18次迭代:e=0.057012
第19次迭代:e=0.047691
第20次迭代:e=0.003498
第21次迭代:e=0.017225
第22次迭代:e=0.006909
第23次迭代:e=0.005744
第24次迭代:e=0.001183
第25次迭代:e=0.002864
第26次迭代:e=0.001860
第27次迭代:e=0.001019
第28次迭代:e=0.000437
第29次迭代:e=0.000495
第30次迭代:e=0.000158
第31次迭代:e=0.000136
第32次迭代:e=0.000064
第33次迭代:e=0.000062
第34次迭代:e=0.000029
第35次迭代:e=0.000012
第36次迭代:e=0.000012
第37次迭代:e=0.000009
第38次迭代:e=0.000004
第39次迭代:e=0.000002
第40次迭代:e=0.000001
第41次迭代:e=0.000000
共轭梯度PBR
第 1次迭代:e=258.635139
第 2次迭代:e=139.441695
第 3次迭代:e=19.041089
第 4次迭代:e=40.134162
第 5次迭代:e=10.908230
第 6次迭代:e=13.012950
第 7次迭代:e=6.363456
第 8次迭代:e=4.667071
第 9次迭代:e=0.832482
第10次迭代:e=0.639173
第11次迭代:e=1.350706
第12次迭代:e=1.153151
第13次迭代:e=0.576897
第14次迭代:e=0.718519
第15次迭代:e=0.372759
第16次迭代:e=0.220066
第17次迭代:e=0.031159
第18次迭代:e=0.007196
第19次迭代:e=0.056745
第20次迭代:e=0.045436
第21次迭代:e=0.011660
第22次迭代:e=0.006583
第23次迭代:e=0.016376
第24次迭代:e=0.007466
第25次迭代:e=0.001820
第26次迭代:e=0.001621
第27次迭代:e=0.001336
第28次迭代:e=0.001719
第29次迭代:e=0.000987
第30次迭代:e=0.000222
第31次迭代:e=0.000211
第32次迭代:e=0.000038
第33次迭代:e=0.000154
第34次迭代:e=0.000083
第35次迭代:e=0.000033
第36次迭代:e=0.000008
第37次迭代:e=0.000007
第38次迭代:e=0.000004
第39次迭代:e=0.000005
第40次迭代:e=0.000002
第41次迭代:e=0.000000
梯度寻优_第1张图片
图片发自App

你可能感兴趣的:(梯度寻优)