梯度寻优

作者: 水之心 | 来源:发表于2017-12-04 20:01 被阅读11次

    参考:梯度下降算法的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 n<N and e>E:  
            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 n<N and e>E:  
            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
    
    梯度寻优

    相关文章

      网友评论

        本文标题:梯度寻优

        本文链接:https://www.haomeiwen.com/subject/pjhfixtx.html