LinneKing 2023-10-28 19:41 采纳率: 0%
浏览 28
已结题

cvx和梯度下降求解逻辑回归问题时参数结果不一致,如何解决?

如题,我在用CVX和GD两种方法来求解一个逻辑回归问题,问题如下
在常规逻辑回归的基础上添加了L2正则项来约束w,b

img

我的代码如下

import numpy as np
import cvxpy as cp
N = 50
mi = 5
# 数据点一共N * mi个,用的是集中训练
C = 1
alpha = 0.001
eps = 1e-8
def logistic_loss(w, b, x, y):
    z = np.dot(x, w) + b
    return np.log(1 + np.exp(-y * z))

def gradient_logistic_loss(w, b, x, y):
    z = np.dot(x, w) + b
    common_term = -y / (1 + np.exp(y * z))
    grad_w = common_term * x
    grad_b = common_term
    return grad_w, grad_b

def optimal_solution_overall_GD(pc, labels):
    d = pc[0][0].shape[0]
    w_opt = np.zeros(d)
    b_opt = 0
    g_w = np.zeros(d)
    g_b = 0
    iteration = 0
    while True:
        sum_w = np.zeros(d)
        sum_b = 0
        iteration += 1
        for i in range(N):
            for j in range(mi):
                grad_w, grad_b = gradient_logistic_loss(w_opt, b_opt, pc[i][j], labels[i][j])
                sum_w += grad_w#累加梯度
                sum_b += grad_b
        g_w = sum_w / (N * mi) + C * w_opt
        g_b = sum_b / (N * mi) + C * b_opt
        w_opt -= alpha * g_w
        b_opt -= alpha * g_b
        if(iteration % 2000 == 0):
            print("iteration_GD", format(iteration))
            print("g_w", format(g_w))
            print("g_b", format(g_b))
            print(w_opt)
            print(b_opt)

        if np.all(np.abs(g_w) < eps) and np.all(np.abs(g_b) < eps):
            break
    return w_opt, b_opt

def logistic_loss_cvx(w, b, x, y):
    z = x @ w + b
    return cp.logistic(-y * z)
def optimal_solution_cvx(pc, labels, C):
    d = pc[0][0].shape[0]
    w = cp.Variable(d)
    b = cp.Variable()
    total_loss = 0
    for i in range(N):
        for j in range(mi):
            total_loss += logistic_loss_cvx(w, b, pc[i][j], labels[i][j])
    # 添加L2正则项
    total_loss += C/2 * (cp.norm(w, 2) + cp.norm(b, 2))
    # 定义优化问题
    problem = cp.Problem(cp.Minimize(total_loss))
    # 求解优化问题
    problem.solve()
    return w.value, b.value

def loss_caculate(w, b, pc, labels):
    loss = 0
    for i in range(N):
        for j in range(mi):
            loss += np.log(1 + np.exp(-labels[i][j] * (np.dot(w, pc[i][j]) + b)))
    loss = loss + C/2 * (np.linalg.norm(w, 2) + b**2)
    return loss
def main():
    # 数据集pc和标签labels都是随机的
    pc = np.random.rand(N, mi, 2)*100
    labels = np.random.choice([1, -1], size=(N, mi))
    w_GD, b_GD = optimal_solution_overall_GD(pc, labels)
    w_cvx, b_cvx = optimal_solution_cvx(pc, labels, C)
    loss1 = loss_caculate(w_GD, b_GD, pc, labels)
    loss2 = loss_caculate(w_cvx, b_cvx, pc, labels)
    print("w_GD", w_GD)
    print("w_cvx", w_cvx)
    print("b_GD", b_GD)
    print("b_cvx", b_cvx)
    print("loss1", loss1)
    print("loss2", loss2)
if __name__ == "__main__":
    main()

部分的输出如下:(因为数据随机,所以结果不固定)|

w_GD [ 0.00223391 -0.00296834]
w_cvx [ 0.00309932 -0.00200936]
b_GD -0.005593343606514088
b_cvx -0.11333700307375219
loss1 172.80617003109705
loss2 172.7096589915864

可以看出wb的值,两种方法得出的结果并不同
目前不知道是哪一个方法出了问题
问题目标是让两个结果达成近似的一致

  • 写回答

18条回答 默认 最新

  • 社区专家-Monster-XH 2023-10-28 19:42
    关注
    获得2.10元问题酬金

    参考答案有吗?

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 11月5日
  • 创建了问题 10月28日

悬赏问题

  • ¥15 有偿求苍穹外卖环境配置
  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,