我的问题是否适用凸优化?如何用CVXPy正确表达广播逻辑?
好问题!让我一步步帮你解答:
1. 这个问题是否可以用凸优化求解?
当然可以!你的两个目标函数都是凸函数:
cp.sum(cp.abs(x + y + data))是L1损失的求和,属于凸函数cp.sum_squares(x + y + data)是L2损失的求和,同样是凸函数
而变量x和y都是无约束的连续变量,整个优化问题的可行域是全空间(凸集),完全满足凸优化的核心条件——凸目标函数 + 凸可行域,所以肯定可以用凸优化方法求解。
2. 如何用CVXPy正确表达该问题?
CVXPy确实不像NumPy那样支持自动广播操作,我们需要手动把x和y扩展成相同的(m,n)维度再进行运算,这里有两种简单且常用的实现方式:
方法一:利用矩阵乘法实现广播
通过全1矩阵和变量的矩阵乘法,我们可以轻松完成维度扩展:
- 对
x(形状(m,1)),乘以(1,n)的全1矩阵,得到(m,n)的矩阵(相当于把x的每一列重复n次) - 对
y(形状(1,n)),用(m,1)的全1矩阵乘以它,得到(m,n)的矩阵(相当于把y的每一行重复m次)
修改后的完整代码如下:
import cvxpy as cp import numpy as np # 问题数据 m = 3 n = 4 np.random.seed(1) data = np.random.randn(m, n) # 构建问题 x = cp.Variable((m, 1)) y = cp.Variable((1, n)) # 手动实现广播:将x和y扩展为(m,n)维度 x_broadcast = x @ np.ones((1, n)) y_broadcast = np.ones((m, 1)) @ y # 定义目标函数(二选一即可) objective = cp.Minimize(cp.sum(cp.abs(x_broadcast + y_broadcast + data))) # objective = cp.Minimize(cp.sum_squares(x_broadcast + y_broadcast + data)) prob = cp.Problem(objective) result = prob.solve() print("x的值:") print(x.value) print("\ny的值:") print(y.value)
方法二:使用CVXPy的cp.repeat函数
CVXPy内置了cp.repeat函数,可以直接对变量进行维度重复:
cp.repeat(x, n, axis=1):沿着列方向重复n次,把(m,1)的x扩展为(m,n)cp.repeat(y, m, axis=0):沿着行方向重复m次,把(1,n)的y扩展为(m,n)
只需要替换方法一中的广播代码即可,示例片段:
x_broadcast = cp.repeat(x, n, axis=1) y_broadcast = cp.repeat(y, m, axis=0)
为什么原代码会报错?
CVXPy对变量运算的维度匹配要求非常严格,不会像NumPy那样自动推断并完成广播。当你直接相加(3,1)的x和(1,4)的y时,CVXPy找不到合法的维度匹配逻辑,因此抛出了维度不兼容的错误。手动扩展维度后,两个变量都变成(3,4),就能正常进行加法运算了。
内容的提问来源于stack exchange,提问作者Just van Rossum
相关产品推荐
相关产品推荐

