【发布时间】:2021-11-13 05:00:41
【问题描述】:
我正在尝试使用多项逻辑回归和梯度下降来训练多类分类器。具体来说,该模型将具有经过训练的权重矩阵 w,其形状为 (C, D),其中 C 是类数,D 是每个输入的特征数。此外,我们将有一个维度为 (C,) 的偏置向量 b。我们有一个 (N, D) 输入矩阵 X,其中 N 是训练输入的数量,以及一个形状为 (N,) 的向量 y,其中 y 中的每个条目是一个从 0 到 C - 1 的数字,表示哪个类输入属于。我写了以下代码:
for _ in range(max_iterations):
z = np.apply_along_axis(lambda v: v - max(v), 1, X @ w.T + b)
probs = np.exp(z)
denom = np.sum(probs, axis=1)
for i in range(C):
for j in range(N):
if i == y[j]:
w[i] -= (step_size / N) * ((probs[j][i] / denom[j]) - 1) * X[j]
b[i] -= (step_size / N) * ((probs[j][i] / denom[j]) - 1)
else:
w[i] -= (step_size / N) * (probs[j][i] / denom[j]) * X[j]
b[i] -= (step_size / N) * (probs[j][i] / denom[j])
这会产生我想要的正确权重和偏差,但显然它没有利用 numpy 的操作来加快速度。因此,我尝试使用以下代码加快其中一些速度:
for _ in range(max_iterations):
z = np.apply_along_axis(lambda v: v - max(v), 1, X @ w.T + b)
probs = np.exp(z)
denom = np.sum(probs, axis=1)
s = np.zeros((N, C))
for i in range(N):
s[i] = probs[i] / denom[i]
for i in range(N):
s[i][y[i]] += -1
for c in range(C):
grad_w = s.T[c] @ X
w[c] += (step_size / N) * grad_w
b[c] += (step_size / N) * sum(s.T[c])
我希望这会产生与上一部分相同的结果,同时速度更快......它设法更快,但结果不正确。
所以我有几个问题。首先,为什么我的第二段代码没有产生正确的结果,有什么办法可以解决它?其次,更重要的是,我将如何进一步优化它?这主要是为了让我学习如何利用numpy的向量化操作。
【问题讨论】:
-
不是说它处理更大的问题,而是
np.apply_along_axis不是一个速度工具。而且我怀疑它可以使用axis和keepdims参数(无迭代)替换为np.max。
标签: python-3.x performance numpy classification logistic-regression