题目

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

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

123

解法

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

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

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
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的值正在向目标值收敛,说明这个模型比较成功。