ML笔记——梯度下降

目录


数学表达

求解代价函数 J(θ0,θ1) J ( θ 0 , θ 1 ) 中的 θ0,θ1 θ 0 , θ 1 使得 J(θ0,θ1) J ( θ 0 , θ 1 ) 最小。

  1. θ0=0,θ1=0 θ 0 = 0 , θ 1 = 0
  2. 重复同时更新 θj:=θjαθjJ(θ0,θ1)(j=0,1) θ j := θ j − α ∂ ∂ θ j J ( θ 0 , θ 1 ) ( j = 0 , 1 ) ,直到 θj θ j 不再改变

其中的 θ0,θ1 θ 0 , θ 1 表示假设的线性函数中的两个参数, α α 表示学习速率

胡思乱想时刻


  • 计算机如何表示这个求偏导数的过程呢?

结合假设函数 hθ(x) h θ ( x ) 与代价函数 J(θ0,θ1) J ( θ 0 , θ 1 )
θ0=θ0αθ0J(θ0,θ1)=θ0αθ0(12mmi=1(hθ(xi)yi)2)=θ0αmmi=1((hθ(xi)yi)θ0hθ(xi))=θ0αmmi=1((hθ(xi)yi)θ0(θ0+θ1xi))=θ0αmmi=1(hθ(xi)yi) θ 0 = θ 0 − α ∂ ∂ θ 0 J ( θ 0 , θ 1 ) = θ 0 − α ∂ ∂ θ 0 ( 1 2 m ∑ i = 1 m ( h θ ( x i ) − y i ) 2 ) = θ 0 − α m ∑ i = 1 m ( ( h θ ( x i ) − y i ) ∂ ∂ θ 0 h θ ( x i ) ) = θ 0 − α m ∑ i = 1 m ( ( h θ ( x i ) − y i ) ∂ ∂ θ 0 ( θ 0 + θ 1 x i ) ) = θ 0 − α m ∑ i = 1 m ( h θ ( x i ) − y i )
同理得到 θ1 θ 1
θ1=θ1αmmi=1xi(hθ(xi)yi) θ 1 = θ 1 − α m ∑ i = 1 m x i ( h θ ( x i ) − y i )
推广开去:
θi=θiαmm1k=0xki(hθ(xk)yk) θ i = θ i − α m ∑ k = 0 m − 1 x i k ( h θ ( x k ) − y k ) (其中的 k k 表示第几组训练数据,与上面式子中的i等价,而此式子中的 i i 表示第几项)
hθ(x)=θ0x0+θ1x1+...+θnxn=j=0n1θjxj代入上式得
θi=θi(αmn1j=0m1k=0θjxkjxkiαmm1k=0ykxki) θ i = θ i − ( α m ∑ j = 0 n − 1 ∑ k = 0 m − 1 θ j x j k x i k − α m ∑ k = 0 m − 1 y k x i k )

//Batch Gradient Descent
const int N = 30, M = 100000;
typedef struct Data {
    double x[N + 1], y;
} TrainingData;

TrainingData TD[M];

void partial (double alpha, double *p, double *theta, int n, TrainingData *TD, int m) {
//此处偏导数的求解,依据上面最后一个式子
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j)
            for (int k = 0; k < m; ++k)
                p[i] += alpha * theta[j] * TD[k].x[j] * TD[k].x[i] / m;

        for (int k = 0; k < m; ++k)
            p[i] -= alpha * TD[k].y * TD[k].x[i] / m;
    }
}

void GDA(double *theta, int n, TrainingData *TD, int m) {
    double alpha = 1, p[n];
    //此处的alpha没有动态处理,p数组用于记录偏导数
    for (int i= 0; i < m; ++i) //初始化
        TD[i].x[0] = 1;

    for (int i = 0; i < n; ++i) //初始化
        p[i] = 0, theta[i] = 0;

    do {
        bool isLoop = false; //控制循环是否终止

        partial(alpha, p, theta, n, TD, m); //求偏导数

        for (int i = 0; i < n; ++i) {
            if (p[i] != 0) { //判断偏导数是否为零
                theta[i] -= p[i];
                isLoop = true;
            }
        }

    }while(isLoop);
}
  • 关于 θj=θjαθjJ(θ0,θ1) θ j = θ j − α ∂ ∂ θ j J ( θ 0 , θ 1 ) 是如何能够在 α α 取值合理的情况下,保证趋于最小值呢?

    导数能够表示一个函数的在该点处的切线斜率。
    当导数值越小时,切线斜率的绝对值也就越小。
    当导数值等于0时,切线斜率就为0,此时取得最优。
    同时还有考虑到,导数的正负表示在最优点的右侧和左侧(因为代价函数是只有最小值,不存在最大值)。
    那么导数的正负就可以,引导 θj θ j 的取值是增大还是减少,最终达到导数为零的情况。

  • 学习速率 α α 如何取值?

    如果 α α 取的值很大,那么可能无法收敛于最小值;如果 α α 取的很小,则将增大运算次数。
    由此得出, α α 的取值一定不是一个定值。
    再次考虑,导数与斜率的关系,当接近最优点时,斜率就会变小,此时学习速率就需要减少。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值