基于tensorfolw与matplotlib实现的二元梯度下降法预测模型

最近嘛,在学tensorflow,就学到了梯度下降法,也用3D网格画图,途中遇到了不少问题,踩了一些坑,于是准备记录下来,其中有tensorflow的张量运算问题(和numpy的有些不太一样,就很头疼),张量矩阵变换问题(大概是学得马虎了,没弄好),运算溢出问题(归一化解决),然后3D绘图问题,总之都是一系列问题,最后跌跌撞撞终于全部解决了,话不多说,现在就开始。

首先,导入模块

import matplotlib.pyplot as plt
import numpy as np                         #tensor张量输出我懒了,直接用numpy
import tensorflow as tf
from mpl_toolkits.mplot3d import Axes3D    #画3D图必须的模块

 上面的模块没什么特别的,没有模块就pip下载吧,然后是导入参数

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

注意:三个张量的数据类型都要一样,都是tensor的float32(tf.float32),不然在后面的矩阵计算会报错。

num = len(area)
x0 = tf.ones([13], 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])  # 归一化
Y = tf.reshape(price, [13, 1])                                    
X = tf.stack((x0, x1, x2), axis=1)                                #堆叠
g1 = tf.random.Generator.from_seed(211)                           #随机数种子
W = g1.normal([3, 1])                                             #生成随机数

差不多就是数据处理,进行归一化,防止后面运算的时候溢出,堆叠矩阵,随机数种子。值得注意的是,tensorflow里面求平均值的方法是reduce_mean,求最大值的是reduce_max,最小值的是reduce_min,这是和numpy所不一样的,使用随机数种子的是random.Generator.from_seed,这也是和numpy所不一样的。

learn_rate = 0.001             # 学习率
iters = 10000                  # 运行次数
display_step = 1000            # 展示结果次数
mse = []
for i in range(0, iters+1):
    dL_dw = tf.matmul(tf.transpose(X), tf.matmul(X, W)-Y)  # 梯度下降法预测
    W = W-learn_rate*dL_dw

    pred = tf.matmul(X, W)
    Loss = tf.reduce_mean(tf.square(Y-pred))/2
    mse.append(Loss)

    if i % display_step == 0:
        print("i:%i,Loss:%f" % (i, mse[i]))

很正常的梯度下降法设置学习率,然后运算,不过要注意在运算的时候,矩阵的形状要注意,要不然运算时候会报错,W必须是[3,1]的张量,Y必须是[13,1]的张量,除此之外,张量的计算结果似乎比numpy的计算速度更慢,而且同样的设置,收敛速度也比numpy更慢,原因暂不清楚,至此已经实现了tensorflow的梯度下降法计算模型。但是很明显需要一个三维图以更好的表示模型运算的结果,于是就要用到matplotlib.pyplot了。

fig = plt.figure()
plt.rcParams['font.sans-serif'] = ['KaiTi']   #设置字体

ax3d = Axes3D(fig, auto_add_to_figure=False)  # 3D图
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("预测模型")
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

然后上面就是一些简单的设置,matplotlib.pyplot支持直接张量绘图,还是挺方便的,值得注意的有几点:

1.需要导入中文字体才能使用中文
2.散点图倒是直接用张量就行了,但是网格图就必须要先将张量升维,才能正常绘制(这里用的np.meshgrid
3.获得的模型是经过归一化处理的模型,也就是说正常预测需要使用归一化处理后的数据,而需要的3D图的,x,y则是原数据的,因此我对归一化的数据和原本的数据都进行了网格化,用归一化的数据获得预测值,用原本的数据和预测值画出了3D的网格图。预测模型结果就是这样。

 至此完成了tensorflow的张量梯度下降法预测。

下面贴一个完整的代码

area = tf.constant([125, 145, 361, 123, 451, 233, 451, 123, 411, 236, 452, 123, 411],
                   dtype=tf.float32)
room = tf.constant([1, 1, 3, 1, 4, 2, 4, 1, 4, 2, 4, 1, 4], dtype=tf.float32)
price = tf.constant([124, 125, 355, 143, 481, 243, 461, 143,
                    451, 237, 472, 153, 441], dtype=tf.float32)
num = len(area)
x0 = tf.ones([13], 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])
Y = tf.reshape(price, [13, 1])
X = tf.stack((x0, x1, x2), axis=1)
g1 = tf.random.Generator.from_seed(211)
W = g1.normal([3, 1])


learn_rate = 0.001
iters = 10000  # 运行次数
display_step = 1000
mse = []
for i in range(0, iters+1):
    dL_dw = tf.matmul(tf.transpose(X), tf.matmul(X, W)-Y)  # 梯度下降法预测
    W = W-learn_rate*dL_dw

    pred = tf.matmul(X, W)
    Loss = tf.reduce_mean(tf.square(Y-pred))/2
    mse.append(Loss)

    if i % display_step == 0:
        print("i:%i,Loss:%f" % (i, mse[i]))
fig = plt.figure()
plt.rcParams['font.sans-serif'] = ['KaiTi']
ax3d = Axes3D(fig, auto_add_to_figure=False)  # 3D画图
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("预测模型")
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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值