朴素梯度下降

前言

对于求局部最优解的情况,可采用梯度下降逼近最小值。这也是机器学习最基本的东西。

一、服务中心的最佳位置

在这里插入图片描述

二、题解

梯度下降,讲究数据选择的随机性/批量度,学习率,衰减率,误差精度。

// 小批量梯度下降。
func getMinDistSum(positions [][]int) float64 {
    n := len(positions)
    // 设置批量数
    batchSize = n
    // 初始化起点值
    var x,y float64
    for _,p := range positions {
        x += float64(p[0])
        y += float64(p[1])
    }
    x /= float64(n)
    y /= float64(n)
    // 开始小批量下降
    for {
        xPre,yPre := x,y
        shuffle(positions)// 每轮都洗一次数据
        for i := 0;i < n;i += batchSize {
            j := min(n,i + batchSize)
            // 批误差求和
            var dx,dy float64
            for k := i;k < j;k++ {
                curX,curY := float64(positions[k][0]),float64(positions[k][1])
                // 注意分母为0,+eps
                dx += (x - curX) / (math.Sqrt((x - curX) * (x - curX) + (y - curY) * (y - curY)) + eps)
                dy += (y - curY) / (math.Sqrt((x - curX) * (x - curX) + (y - curY) * (y - curY)) + eps)
            }
            // 更新x,y
            x -= alpha * dx
            y -= alpha * dy
            
            // 每批次,学习率衰减。
            alpha *= (1.0 - decay)
        }
        // 如果更新前后差值在误差内,就不用迭代了。
        gap := math.Sqrt((x - xPre) * (x - xPre) + (y - yPre) * (y - yPre))
        if eps > gap {
            break
        }
    }
    return getDistance(positions,x,y)
}
// 保住批量数据取数据。
func shuffle(positions [][]int) {
    n := len(positions)

    for i := 0;i < n;i++ {
        x,y := positions[i][0],positions[i][1]
        idx := rand.Intn(n)
        positions[i][0],positions[i][1] = positions[idx][0],positions[idx][1]
        positions[idx][0],positions[idx][1] = x,y
    }
}
// 设置学习率/最小误差/防止来回波动的衰减值
var (
    alpha float64 = 1
    eps float64 = 1e-7
    decay float64 = 1e-3
    batchSize int
)
// 得到服务中心到所有点的距离
func getDistance(positions [][]int,x,y float64) float64 {
    var rs float64
    for _,p := range positions {
        i,j := float64(p[0]),float64(p[1])
        rs += math.Sqrt((i - x) * (i - x) + (j - y) * (j - y))
    }
    return rs
}
// 取最小值
func min(x,y int) int {
    if x < y {
        return x
    }
    return y
}

总结

1)朴素梯度下降,抓住几个参数就OK了,学习率,衰减值,误差精度,批量大小,再注意数据的随机选择即可。

参考文献

[1] LeetCode 服务中心的最佳位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值