来喝无糖汽水

“择栖工作室招新”

题目

下列Python程序生成了三维空间中的一系列点,获得了坐标x、y、z,他们的分布可以使用一个平面去近似,本质上就是一个三维的线性回归问题:Z=aX+bY+c。其中a、b和c即为我们需要通过机器学习去获得的量。

要求使用梯度下降算法,使用任意方式去实现这一算法,完成对于我们所给出的data_creater_3d函数所生成的数据的拟合。

123

解法

题目的要求就是用一个三维平面去拟合一系列三维空间里的坐标点,总题思路就是,先随机生成一个平面,再利用最小二乘法,构造所有点与平面的差值,构造损失函数,再利用梯度下降调整参数,得到最优解。

(PS:博主的能力有限,代码可能存在不少待改进的地方,恳请各路大佬指正)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import numpy as np
import tensorflow as tf
#题目自带创建随机点的函数
def data_create_3d(w1, w2, b, amount, size, turb):
X = np.random.normal(size=(amount, 2), scale=size)
w = np.array((w1, w2))
delta = np.random.normal(size=amount, scale=size) * turb
y = np.dot(X, w) + b + delta
return X[:, 0], X[:, 1], y

print("目标值->","w1:", 2, "w2:", 3, "b:", 20)

#得到各点的值
x, y, z = data_create_3d(2, 3, 20, 1000, 10, 3)

#构造损失函数f
def loss(w1, w2, b):
f = 0
for i in range(0, 1000):
f += (w1*x[i]+w2*y[i]+b-z[i])**2
f / 1000

return f

if __name__ == "__main__":
#构造变量 原函数为y=w1x+w2z+b

w1=tf.Variable(1.0)
w2=tf.Variable(2.0)
b=tf.Variable(25.0)


cnt = 0#循环计数器
foot1 = 0.000001 #w1学习率
foot2 = 0.000001 #w2学习率
foot3 = 0.0001 #b学习率
yuzhi = 100 #迭代阈值



while True:
cnt += 1
with tf.GradientTape(persistent=True) as tape:
losss = loss(w1, w2, b)
#计算三个变量的偏导数↓
dw1 = tape.gradient(losss, w1)
dw2 = tape.gradient(losss, w2)
db = tape.gradient(losss, b)
#储存上次损失函数,用作下面作差使用
pre = loss(w1, w2, b)
#根据导数更新参量的值
w1.assign_sub(foot1*dw1)
w2.assign_sub(foot2*dw2)
b.assign_sub(foot3*db)
#作两次迭代函数的差
derta = abs(loss(w1, w2, b)-pre)
#每轮各数据打印
print("=========\n迭代次数:",cnt)
tf.print("loss:",loss(w1,w2,b))
a=tf.print("w1:"w1)
d=tf.print("w2:",w2)
c=tf.print("b:",b)
#结束条件
if derta < yuzhi:
print("迭代结束!")
break

运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
=========
迭代次数: 1
loss: 1041114.94
w1: 1.2122817
w2: 2.21572828
b: 23.7844467
=========
迭代次数: 2
loss: 979924.188
w1: 1.38431644
w2: 2.38638473
b: 22.8210564
=========
迭代次数: 3
loss: 940783.313
w1: 1.52372897
w2: 2.52139711
b: 22.0576153
=========
迭代次数: 4
loss: 915732
w1: 1.63670099
w2: 2.62821913
b: 21.4527035
=========

可以看到w1,w2,b的值正在向目标值收敛,说明这个模型比较成功。


本文由 rufus 创作,采用 知识共享署名 4.0 国际许可协议。

本站文章除注明转载/出处外,均为本站原创或翻译,转载请务必署名。