使用 numpy 实现线性回归
Implementing Linear Regression using numpy
我正在尝试学习线性方程 y = x1 + x2 + e,其中 e 是 0 到 0.5 之间的随机误差。
数据定义如下:
X1 = np.random.randint(1, 10000, 5000)
X2 = np.random.randint(1, 10000, 5000)
e = np.array([random.uniform(0, 0.5) for i in range(5000)])
y = X1 + X2 + e
当我实现一个简单的梯度下降来寻找参数时,损失和梯度都在爆炸。我哪里错了?梯度下降的代码:
w1, w2, b = 1, 1, 0
n = X1.shape[0]
alpha = 0.01
for i in range(5):
y_pred = w1 * X1 + w2 * X2 + b
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = (-1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = (-1/n) * np.sum((y - y_pred) * X2)
dL_db = (-1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
b = b - alpha * dL_db
print(L, w1, w2, b)
这个输出是:
0.042928723015982384 , 13.7023102434034 , 13.670617201430483 , 0.00254938447277222
9291487188.8259 , -7353857.489486973 , -7293941.123714662 , -1261.9252592161051
3.096713445664372e+21 , 4247172241132.3584 , 4209117175658.749 , 728518135.2857293
1.0320897597938595e+33 , -2.4520737800716524e+18 , -2.4298158059267333e+18 , -420579738783719.2
3.4398058610314825e+44 , 1.415615899689713e+24 , 1.402742160404974e+24 , 2.428043942370682e+20
好的,问题的表述有一些问题
- 缩放:梯度下降通常需要对变量进行很好的缩放,以确保可以正确设置 alpha。在大多数情况下,一切都是相对的,你总是可以将一个问题乘以一个固定的常数。然而,因为权重直接由 alpha 值操纵,所以很难达到非常高或非常低的权重值,我特此将您的机制缩小约 10000,并将随机误差减少到 scale
import numpy as np
import random
X1 = np.random.random(5000)
X2 = np.random.random(5000)
e = np.array([random.uniform(0, 0.0005) for i in range(5000)])
y = X1 + X2 + e
y_pred
对 b 的依赖性:B 的值 我不确定它应该做什么以及为什么要明确向 y_pred
引入错误。您的预测应该假设没有错误:D
如果 X 和 Y 缩放得很好,使用超参数尝试几次会产生一个好的值
for i in range(5):
y_pred = w1 * X1 + w2 * X2
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = -(1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = -(1/n) * np.sum((y - y_pred) * X2)
dL_db = -(1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
print(L, w1, w2)
您可以尝试使用这些值,但它们会收敛
w1, w2, b = 1.1, 0.9, 0.01
alpha = 1
0.0008532534726479387 1.0911950693892498 0.9082610891021278
0.0007137567968828647 1.0833134985852988 0.9159869797801239
0.0005971536415151483 1.0761750602775175 0.9231234590515701
0.0004996145120126794 1.0696746682185534 0.9296797694772246
0.0004180103133293466 1.0637407602096771 0.9356885401106588
您所缺少的只是数据规范化。对于基于梯度的学习算法,您必须确保数据已标准化,即它具有 mean=0
和 std=1
.
让我们通过一个恒定的错误来验证这一点(比如 e=33
)。
X1 = np.random.randint(1, 10000, 5000)
X2 = np.random.randint(1, 10000, 5000)
e = 33
# Normalize data
X1 = (X1 - np.mean(X1))/np.std(X1)
X2 = (X2 - np.mean(X2))/np.std(X2)
y = X1 + X2 + e
w1, w2, b = np.random.rand(), np.random.rand(), np.random.rand()
n = X1.shape[0]
alpha = 0.01
for i in range(1000):
y_pred = w1 * X1 + w2 * X2 + b
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = (-1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = (-1/n) * np.sum((y - y_pred) * X2)
dL_db = (-1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
b = b - alpha * dL_db
if (i)%100 == 0:
print(L)
print (w1, w2, b)
输出:
Loss: 517.7575710514508
Loss: 69.36601211594098
Loss: 9.29326322560041
Loss: 1.2450619081931993
Loss: 0.16680720657514425
Loss: 0.022348057963833764
Loss: 0.002994096883392299
Loss: 0.0004011372165515275
Loss: 5.374289796164062e-05
Loss: 7.2002934167549005e-06
0.9999609731610163 0.9999911458582055 32.99861157362915
如您所见,它确实收敛了。
除了必须规范化数据外,您的代码没有任何问题。
现在您可以补回错误并找到可能的最佳估计值。
我正在尝试学习线性方程 y = x1 + x2 + e,其中 e 是 0 到 0.5 之间的随机误差。 数据定义如下:
X1 = np.random.randint(1, 10000, 5000)
X2 = np.random.randint(1, 10000, 5000)
e = np.array([random.uniform(0, 0.5) for i in range(5000)])
y = X1 + X2 + e
当我实现一个简单的梯度下降来寻找参数时,损失和梯度都在爆炸。我哪里错了?梯度下降的代码:
w1, w2, b = 1, 1, 0
n = X1.shape[0]
alpha = 0.01
for i in range(5):
y_pred = w1 * X1 + w2 * X2 + b
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = (-1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = (-1/n) * np.sum((y - y_pred) * X2)
dL_db = (-1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
b = b - alpha * dL_db
print(L, w1, w2, b)
这个输出是:
0.042928723015982384 , 13.7023102434034 , 13.670617201430483 , 0.00254938447277222
9291487188.8259 , -7353857.489486973 , -7293941.123714662 , -1261.9252592161051
3.096713445664372e+21 , 4247172241132.3584 , 4209117175658.749 , 728518135.2857293
1.0320897597938595e+33 , -2.4520737800716524e+18 , -2.4298158059267333e+18 , -420579738783719.2
3.4398058610314825e+44 , 1.415615899689713e+24 , 1.402742160404974e+24 , 2.428043942370682e+20
好的,问题的表述有一些问题
- 缩放:梯度下降通常需要对变量进行很好的缩放,以确保可以正确设置 alpha。在大多数情况下,一切都是相对的,你总是可以将一个问题乘以一个固定的常数。然而,因为权重直接由 alpha 值操纵,所以很难达到非常高或非常低的权重值,我特此将您的机制缩小约 10000,并将随机误差减少到 scale
import numpy as np
import random
X1 = np.random.random(5000)
X2 = np.random.random(5000)
e = np.array([random.uniform(0, 0.0005) for i in range(5000)])
y = X1 + X2 + e
y_pred
对 b 的依赖性:B 的值 我不确定它应该做什么以及为什么要明确向y_pred
引入错误。您的预测应该假设没有错误:D如果 X 和 Y 缩放得很好,使用超参数尝试几次会产生一个好的值
for i in range(5):
y_pred = w1 * X1 + w2 * X2
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = -(1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = -(1/n) * np.sum((y - y_pred) * X2)
dL_db = -(1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
print(L, w1, w2)
您可以尝试使用这些值,但它们会收敛
w1, w2, b = 1.1, 0.9, 0.01
alpha = 1
0.0008532534726479387 1.0911950693892498 0.9082610891021278
0.0007137567968828647 1.0833134985852988 0.9159869797801239
0.0005971536415151483 1.0761750602775175 0.9231234590515701
0.0004996145120126794 1.0696746682185534 0.9296797694772246
0.0004180103133293466 1.0637407602096771 0.9356885401106588
您所缺少的只是数据规范化。对于基于梯度的学习算法,您必须确保数据已标准化,即它具有 mean=0
和 std=1
.
让我们通过一个恒定的错误来验证这一点(比如 e=33
)。
X1 = np.random.randint(1, 10000, 5000)
X2 = np.random.randint(1, 10000, 5000)
e = 33
# Normalize data
X1 = (X1 - np.mean(X1))/np.std(X1)
X2 = (X2 - np.mean(X2))/np.std(X2)
y = X1 + X2 + e
w1, w2, b = np.random.rand(), np.random.rand(), np.random.rand()
n = X1.shape[0]
alpha = 0.01
for i in range(1000):
y_pred = w1 * X1 + w2 * X2 + b
L = np.sum(np.square(y - y_pred))/(2 * n)
dL_dw1 = (-1/n) * np.sum((y - y_pred) * X1)
dL_dw2 = (-1/n) * np.sum((y - y_pred) * X2)
dL_db = (-1/n) * np.sum((y - y_pred))
w1 = w1 - alpha * dL_dw1
w2 = w2 - alpha * dL_dw2
b = b - alpha * dL_db
if (i)%100 == 0:
print(L)
print (w1, w2, b)
输出:
Loss: 517.7575710514508
Loss: 69.36601211594098
Loss: 9.29326322560041
Loss: 1.2450619081931993
Loss: 0.16680720657514425
Loss: 0.022348057963833764
Loss: 0.002994096883392299
Loss: 0.0004011372165515275
Loss: 5.374289796164062e-05
Loss: 7.2002934167549005e-06
0.9999609731610163 0.9999911458582055 32.99861157362915
如您所见,它确实收敛了。
除了必须规范化数据外,您的代码没有任何问题。
现在您可以补回错误并找到可能的最佳估计值。