zoukankan      html  css  js  c++  java
  • 人工智能实战2019

    项目 内容
    课程 人工智能实战2019
    作业要求 第3次作业
    课程目标 学习人工智能基础知识
    本次作业对我的帮助 学习随机梯度下降的三种方法,理解损失函数图像的内涵
    理论课程 梯度下降的三种形式

    使用Mini-Batch方式进行梯度下降

    要求

    • 采用随机选取数据的方式
    • batch size 分别选择5、10、15进行运行

    代码实现

    import numpy as np
    import matplotlib.pyplot as plt
    from pathlib import Path
    
    x_data_name = "TemperatureControlXData.dat"
    y_data_name = "TemperatureControlYData.dat"
    
    
    def ReadData():
        Xfile = Path(x_data_name)
        Yfile = Path(y_data_name)
        if Xfile.exists() & Yfile.exists():
            X = np.load(Xfile)
            Y = np.load(Yfile)
            return X.reshape(1,-1),Y.reshape(1,-1)
        else:
            return None,None
    
    def shuffle_batch(X, Y, batch_size):    
        rnd_idx = np.random.permutation(len(X))
        n_batches = len(X)
        for batch_idx in np.array_split(rnd_idx, n_batches):
            X_batch, Y_batch = X[batch_idx], Y[batch_idx]
            yield X_batch, Y_batch
    
    def ForwardCalculationBatch(W,B,batch_x):
        Z = np.dot(W, batch_x) + B
        return Z
    
    def BackPropagationBatch(batch_x, batch_y, batch_z):
        m = batch_x.shape[1]
        dZ = batch_z - batch_y
        dB = dZ.sum(axis=1, keepdims=True)/m
        dW = np.dot(dZ, batch_x.T)/m
        return dW, dB
    
    def UpdateWeights(w, b, dW, dB, eta):
        w = w - eta*dW
        b = b - eta*dB
        return w,b
    
    def InitialWeights(num_input, num_output, flag):
        if flag == 0:
            # zero,全零初始化
            W = np.zeros((num_output, num_input))
        elif flag == 1:
            # normalize,高斯分布初始化
            W = np.random.normal(size=(num_output, num_input))
        elif flag == 2:
            # xavier,均匀分布初始化
            W=np.random.uniform(
                -np.sqrt(6/(num_input+num_output)),
                np.sqrt(6/(num_input+num_output)),
                size=(num_output,num_input))
    
        B = np.zeros((num_output, 1))
        return W,B
    
    def CheckLoss(W, B, X, Y):
        m = X.shape[1]
        Z = np.dot(W, X) + B
        LOSS = (Z - Y)**2
        loss = LOSS.sum()/m/2
        return loss
    
    
    if __name__ == '__main__':
        
        eta = 0.1
        size = {5,15,20}
        max_epoch = 50
    
        X, Y = ReadData()
       
        num_example = X.shape[1]
        num_feature = X.shape[0]
    
        for batch_size in size:
            W, B = InitialWeights(1,1,2)
            loss = []
            for epoch in range(max_epoch):
                for batch_x,batch_y in shuffle_batch(X,Y,batch_size):
                    batch_z = ForwardCalculationBatch(W, B, batch_x)
                    dW, dB = BackPropagationBatch(batch_x, batch_y, batch_z)
                    W, B = UpdateWeights(W, B, dW, dB, eta)
         
                temp = CheckLoss(W,B,X,Y)
                loss.append(temp)
            plt.plot(loss)
            plt.legend(['batch_size : 5','batch_size : 10','batch_size : 15'],loc ='upper right')  
        plt.show()
    
    

    运行结果

    • 学习率eta = 0.01
      At2Dkd.png
    • 学习率eta = 0.1
      At2sfI.png
    • 学习率eta = 0.2
      At26pt.png
    • 学习率eta = 0.5
      At2c1P.png

    总结

    • 随着学习率eta的增大,会在极值点附近产生跳跃,曲线波动增大
    • batch size的的改变,会改变学习速度;batch size过大或过小都不利于提高学习速度
    • Mini-Batch综合了全批量梯度下降BGD和随机梯度下降SGD的优点,在更新速度与更新次数中取一个平衡。相较于BGD,提高了每次的学习速度,不必担心内存瓶颈;相较于SGD,降低了收敛波动性,使更新更加稳定。

    梯度下降算法的问题与挑战

    • 很难选择一个合理的学习速率
    • 学习速率调整都需要事先进行固定设置,无法自适应每次学习的数据集特点(比如对于很少出现的特征,应用较大的学习速率)
    • 对于非凸目标函数,容易陷入局部最优(虽然使用SGD,会增大得到全局最优的可能性)

    关于损失函数的2D示意图的思考题

    1. 为什么是椭圆而不是圆?

    由题设知:

    [J(w, b)=frac{1}{2 m} sum_{i}^{m}left(a_{i}-y_{i} ight)^{2}=frac{1}{2 m} sum_{i}^{m}left(omega x+b-y_{i} ight)^{2} ]

    令J=z,整理损失函数表达式可得:

    [left(sum_{i}^{m} x_{i}^{2} ight) w^{2}+m b^{2}+left(2 sum_{i}^{m} x_{i} ight) w b-left(2 sum_{i}^{m} x_{i} y_{i} ight) w-left(2 sum_{i}^{m} y_{i} ight) b+left(sum_{i}^{m} y_{i}^{2} ight)=2 m z ]

    椭圆抛物面的标准方程可推知,变换后的损失函数表达式为椭圆抛物面的一般方程。故投影到2维平面是一般椭圆。

    2. 如何把这个图变成一个圆?

    只需使变换后的损失函数表达式与回转抛物面的一般方程一致即可。
    交叉项前的系数为0,二次项前的系数相等:

    [left(2 sum_{i}^{m} x_{i} ight)=0 quad left(sum_{i}^{m} x_{i}^{2} ight)=m ]

    代码实现

        x = x - x.mean(axis=0)  #使交叉项前的系数为0
        x = x*np.sqrt(len(x)/np.sum(np.square(x)))    #使二次方前的系数相等
    

    运行结果(主程序引用自:Microsoft/ai-edu

    AYxZwj.png

    3. 为什么中心是个椭圆区域而不是一个点?

    • 从数学角度分析,利用偏导数的知识可以求出唯一最优解,故椭圆抛物面中心是一个点。
    • 我们绘制的图像其实是由很多离散的点组成,并非连续曲面。由于我们使用的梯度下降算法属于数值解法,会无限逼近数学解析最优解,而满足给定误差限的点有无穷多个,故中心形成区域。
  • 相关阅读:
    寄存器总结
    汇编知识积累
    windbg 配置符号路径
    UNICODE环境下读写txt文件操作
    vs2010 安装项目完成桌面快捷方式无法定位程序文件夹 解决方法
    spring源码解析之属性编辑器propertyEditor
    springboot国际化与@valid国际化支持
    No identifier specified for entity
    springboot 项目中css js 等静态资源无法访问的问题
    Git教程
  • 原文地址:https://www.cnblogs.com/wangshihong/p/10586308.html
Copyright © 2011-2022 走看看