基于tensorflow自动求导实现的二元梯度下降法

之前用tensorflow的张量完成了二元随机梯度下降法,但是tensorflow可以自动求导,这样的话就不用进行复杂的矩阵变换以求得损失函数的导数,可以直接用tensorflow获取导数(GradientTape()方法),同样这里也有一些坑 

首先,还是导入模块

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from mpl_toolkits.mplot3d import Axes3D

然后导入数据,并转换为可处理的形式

x0 = tf.ones([13], dtype=tf.float32)
area = tf.Variable([125, 145, 361, 123, 451, 233, 451, 123,
                   411, 236, 452, 123, 411], dtype=tf.float32)
room = tf.Variable([1, 1, 3, 1, 4, 2, 4, 1, 4, 2, 4, 1, 4], dtype=tf.float32)
price = tf.Variable([124, 125, 355, 143, 481, 243, 461, 143,
                    451, 237, 472, 153, 441], dtype=tf.float32)

x1 = tf.reshape((area-tf.reduce_min(area)) /
                (tf.reduce_max(area)-tf.reduce_min(area)), [13])
x2 = tf.reshape((room-tf.reduce_min(room)) /
                (tf.reduce_max(room)-tf.reduce_min(room)), [13])

X = tf.stack((x0, x1, x2), axis=1)  # 堆叠

Y = tf.reshape(price, [13, 1])
g1 = tf.random.Generator.from_seed(211)  # 随机数种子
W = g1.normal([3, 1])
W = tf.Variable(W)                  # 转换为图变量

基本的数据导入以及矩阵变换,因为之后要计算损失函数因此还需要对矩阵形状进行修改。值得注意的是由于损失函数loss=tf.reduce_sum(tf.square(Y-tf.matmul(X,W))),在函数之中需要追踪的是W的变化梯度,因此需要将W变换为Variable类型的变量进行运算.

完成数据导入之后就设置超参数以及进行运算

learn_rate=0.001         #学习率
iters=10000              #迭代次数
display=1000             #展示间隔
mse=[]
for i in range(iters+1):
    with tf.GradientTape() as tape:
        loss=tf.reduce_sum(tf.square(Y-tf.matmul(X,W)))        #损失函数
    dw=tape.gradient(loss,W)
    W=tf.Variable(W-learn_rate*dw)                             #转换为图变量
    pred=tf.matmul(X,W)
    LOSS=tf.reduce_mean(tf.square(Y-pred))/2
    mse.append(LOSS)
    if i%display==0:
        print("i:%d LOSS:%f"%(i,LOSS))                         #输出损失

值得注意的是通过tape.gradient获得的导数dw的变量类型并不是Variable,因此需要在运算后转换为Variable变量,否则在第二次迭代的时候tape.gradient会无法获取变量,导致dw变成None,进而无法继续运行。最后就这样获得了一个迭代结果

 最后是画图表现结果不过要加一句

price=np.array(price)

转换为numpy数组,否则二维图会报错。

然后画图——

plt.rcParams['font.sans-serif']=['SimHei']
plt.figure(figsize=(12,4))

plt.subplot(1,2,1)
plt.plot(mse)
plt.xlabel("Iter",fontsize=14)
plt.ylabel("Loss",fontsize=14)

plt.subplot(1,2,2)
pred=tf.reshape(pred,-1)


plt.plot(price,color='red',label="销售记录")
plt.plot(pred,color='blue',label="预测房价")

plt.xlabel("Sample",fontsize=14)
plt.ylabel("Price",fontsize=14)

plt.legend()
plt.show

 然后是三维网格图——(代码我就直接复制上我一篇文章的代码了,关于这段代码,上一篇文章上有详解)

fig=plt.figure() 

ax3d=Axes3D(fig,auto_add_to_figure=False)
fig.add_axes(ax3d)
ax3d.scatter(area,room,price,color="blue",marker="*")
A, R = np.meshgrid(x1, x2)
AREA,ROOM=np.meshgrid(area, room)
P=W[0,0]+W[1,0]*A+W[2,0]*R
ax3d.plot_wireframe(AREA,ROOM,P,linewidth=0.5)  # 设置颜色映射
# 设置标题
plt.title("3D图")
ax3d.set_xlabel("areas",color="r",fontsize=14)
ax3d.set_ylabel("rooms",color="r",fontsize=14)
ax3d.set_zlabel("prices",color="r",fontsize=14)
ax3d.set_yticks([1,2,3])


plt.show

 至此终于完成了利用tensorflow自动求导的梯度下降算法以及可视化展示,下面贴一个完整代码。

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from mpl_toolkits.mplot3d import Axes3D

x0 = tf.ones([13], dtype=tf.float32)
area = tf.Variable([125, 145, 361, 123, 451, 233, 451, 123,
                   411, 236, 452, 123, 411], dtype=tf.float32)
room = tf.Variable([1, 1, 3, 1, 4, 2, 4, 1, 4, 2, 4, 1, 4], dtype=tf.float32)
price = tf.Variable([124, 125, 355, 143, 481, 243, 461, 143,
                    451, 237, 472, 153, 441], dtype=tf.float32)

x1 = tf.reshape((area-tf.reduce_min(area)) /
                (tf.reduce_max(area)-tf.reduce_min(area)), [13])
x2 = tf.reshape((room-tf.reduce_min(room)) /
                (tf.reduce_max(room)-tf.reduce_min(room)), [13])

X = tf.stack((x0, x1, x2), axis=1)  # 堆叠
X = tf.Variable(X)

Y = tf.reshape(price, [13, 1])
g1 = tf.random.Generator.from_seed(211)  # 随机数种子
W = g1.normal([3, 1])
W = tf.Variable(W)

learn_rate=0.001
iters=10000
display=1000
mse=[]
for i in range(iters+1):
    with tf.GradientTape() as tape:
        loss=tf.reduce_sum(tf.square(Y-tf.matmul(X,W)))
    dw=tape.gradient(loss,W)
    W=tf.Variable(W-learn_rate*dw)
    pred=tf.matmul(X,W)
    LOSS=tf.reduce_mean(tf.square(Y-pred))/2
    mse.append(LOSS)
    if i%display==0:
        print("i:%d LOSS:%f"%(i,LOSS))
price=np.array(price)

plt.rcParams['font.sans-serif']=['SimHei']
plt.figure(figsize=(12,4))

plt.subplot(1,2,1)
plt.plot(mse)
plt.xlabel("Iter",fontsize=14)
plt.ylabel("Loss",fontsize=14)

plt.subplot(1,2,2)
pred=tf.reshape(pred,-1)


plt.plot(price,color='red',label="销售记录")
plt.plot(pred,color='blue',label="预测房价")

plt.xlabel("Sample",fontsize=14)
plt.ylabel("Price",fontsize=14)

plt.legend()
plt.show

fig=plt.figure() 

ax3d=Axes3D(fig,auto_add_to_figure=False)
fig.add_axes(ax3d)
ax3d.scatter(area,room,price,color="blue",marker="*")
A, R = np.meshgrid(x1, x2)
AREA,ROOM=np.meshgrid(area, room)
P=W[0,0]+W[1,0]*A+W[2,0]*R
ax3d.plot_wireframe(AREA,ROOM,P,linewidth=0.5)  # 设置颜色映射
# 设置标题
plt.title("3D图")
ax3d.set_xlabel("areas",color="r",fontsize=14)
ax3d.set_ylabel("rooms",color="r",fontsize=14)
ax3d.set_zlabel("prices",color="r",fontsize=14)
ax3d.set_yticks([1,2,3])

plt.show

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB的二元函数梯度下降法的编程可以按照以下步骤进行: 1. 首先,定义要优化的二元函数。例如,假设我们要优化的函数是f(x, y) = x^2 + y^2。 2. 然后,计算函数f(x, y)关于x和y的偏导数。在这个例子中,f对x的偏导数为2x,f对y的偏导数为2y。 3. 初始化变量x和y的初始值,以及学习率alpha和迭代次数iterations。 4. 在每次迭代中,根据当前的x和y值计算函数f的梯度。然后更新变量x和y的值,通过减去学习率乘以梯度。即更新公式为 x = x - alpha * df/dx y = y - alpha * df/dy 5. 重复步骤4,直到达到指定的迭代次数iterations。 6. 最后,输出最终的优化结果。 下面是一个MATLAB代码的示例: ```matlab % 定义优化的二元函数 f = @(x, y) x^2 + y^2; % 计算函数f关于x和y的偏导数 df_dx = @(x, y) 2 * x; df_dy = @(x, y) 2 * y; % 初始化变量 x = 0; % 初始x值 y = 0; % 初始y值 alpha = 0.1; % 学习率 iterations = 100; % 迭代次数 % 进行梯度下降优化 for i = 1:iterations % 计算梯度 gradient_x = df_dx(x, y); gradient_y = df_dy(x, y); % 更新变量 x = x - alpha * gradient_x; y = y - alpha * gradient_y; end % 输出最终结果 x_final = x; y_final = y; fprintf('Optimized solution: x = %.4f, y = %.4f\n', x_final, y_final); ``` 这样,就可以通过梯度下降法二元函数进行优化。请注意,这只是一个示例代码,实际使用时需要根据具体的二元函数和参数进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值