以下内容主要参考:
https://www.bilibili.com/video/av54557524/?p=32
import pandas as pd
import numpy as np
'''
##############################################################################################
######################## 分析数据 ########################
##############################################################################################
from mpl_toolkits import mplot3d
# import pandas as pd
import matplotlib.pyplot as plt
df1 = pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price'])
# 数据归一化
def normalize_feature(df):
return df.apply(lambda column: (column - column.mean()) / column.std())
df = normalize_feature(df1)
fig = plt.figure() # 先通过plt创建一张空的图片
ax = plt.axes(projection='3d') # 告诉plt我们将要创建一个3d对象
# 这一步会建立一个三维坐标系,但到目前为止这个图依旧是空的
ax.set_xlabel('square')
ax.set_ylabel('bedrooms')
ax.set_zlabel('price')
# scatter3D的前3个数据分别填充x,y,和z轴的数据
# 参数c是为了给不同的点赋予不同的颜色深度,这里颜色深度具体为多少,我们设置其根据price \
# 的大小来设定:price越大,颜色就越深
# cmap指定要用什么颜色去绘制散点
ax.scatter3D(df['square'], df['bedrooms'], df['price'], c=df['price'], cmap='Reds')
plt.show()
'''
##############################################################################################
######################## 处理数据 ########################
##############################################################################################
# 这一步的目的是为了得到能够输入到模型中的标准的数据格式
def normalize_feature(df):
return df.apply(lambda column: (column - column.mean()) / column.std())
df = normalize_feature(pd.read_csv('data1.csv', names=['square', 'bedrooms', 'price']))
# 创建一个n行1列全为1的数据框
# len(df)返回df的长度(在这里为行数)
# 这里是以字典的形式创建的,其中 ones 是对应的标题,value才是真正的值
ones = pd.DataFrame({'ones': np.ones(len(df))})
# 将全1数据合并到已有的数据框里
df = pd.concat([ones, df], axis=1) # 这里是根据列合并
# 如何根据axis判断是在哪一维合并:左手准则。大拇指指向自己,\
# axis = 0, 1, 2分别对应x轴,y轴和z轴
# 将DataFrame中的数据表示成矩阵的形式
X_data = np.array(df[df.columns[0:3]]) # 注意区间是左闭右开的
y_data = np.array(df[df.columns[-1]]).reshape(len(df), 1)
# print(X_data.shape, type(X_data))
# print(y_data.shape, type(y_data))
'''
输出:
(47, 3)
(47, 1)
'''
##############################################################################################
######################## 创建模型 ########################
##############################################################################################
import tensorflow as tf
alpha = 0.01 # 设置学习率
epoch = 500 # 设置总共要训练的轮数
#-------------- 创建一个线性回归模型 --------------#
# 首先定义模型中要用到的一些数据
X = tf.placeholder(tf.float32, X_data.shape) # 输入X,形状为[47, 3]
y = tf.placeholder(tf.float32, y_data.shape) # 输入Y,形状为[47, 1]
# 权重变量W,形状为[3, 1]
W = tf.get_variable('weights',(X_data.shape[1], 1), initializer=tf.constant_initializer())
# 假设模型的表达式为:h(x) = w0 * x0 + w1 * x1 + w2 * x2,其中x0恒为1,用来计算偏置项
# 将该表达式用矩阵乘法来表示
y_pred = tf.matmul(X, W) # 得到的y_pred的形状为[47, 1]
#------------- 接下来要考虑损失函数和梯度下降策略 -------------#
# 这里损失函数用L2损失:
# 注意tf.matmul(a, b, transpose_a=True)表示矩阵a的转置乘以矩阵b,在这里即为 [1, 47] x [47, 1]
# 因此最终loss_op得到的是一个数
loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)
# 这里采用随机梯度下降优化器,设置学习率为alpha
opt = tf.train.GradientDescentOptimizer(learning_rate=alpha)
# 定义每一步的训练目标:最小化loss函数
train_op = opt.minimize(loss_op)
##############################################################################################
######################## 训练 ########################
##############################################################################################
# 创建会话
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
# 开始训练模型
# 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
for e in range(1, epoch + 1):
sess.run(train_op, feed_dict={X: X_data, y: y_data})
if e % 10 == 0:
loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, w[1], w[2], w[0]))
输出结果为:
Epoch 10 Loss=0.4116 Model: y = 0.0791x1 + 0.03948x2 + 3.353e-10
Epoch 20 Loss=0.353 Model: y = 0.1489x1 + 0.07135x2 + -5.588e-11
Epoch 30 Loss=0.3087 Model: y = 0.2107x1 + 0.09676x2 + 3.912e-10
Epoch 40 Loss=0.2748 Model: y = 0.2655x1 + 0.1167x2 + -1.863e-11
Epoch 50 Loss=0.2489 Model: y = 0.3142x1 + 0.1321x2 + 1.77e-10
Epoch 60 Loss=0.2288 Model: y = 0.3576x1 + 0.1436x2 + -4.47e-10
Epoch 70 Loss=0.2131 Model: y = 0.3965x1 + 0.1519x2 + -8.103e-10
Epoch 80 Loss=0.2007 Model: y = 0.4313x1 + 0.1574x2 + -6.985e-10
Epoch 90 Loss=0.1908 Model: y = 0.4626x1 + 0.1607x2 + -4.936e-10
Epoch 100 Loss=0.1828 Model: y = 0.4909x1 + 0.1621x2 + -6.147e-10
Epoch 110 Loss=0.1763 Model: y = 0.5165x1 + 0.162x2 + -7.87e-10
Epoch 120 Loss=0.1709 Model: y = 0.5397x1 + 0.1606x2 + -5.821e-10
Epoch 130 Loss=0.1664 Model: y = 0.5609x1 + 0.1581x2 + -9.08e-10
Epoch 140 Loss=0.1625 Model: y = 0.5802x1 + 0.1549x2 + -9.965e-10
Epoch 150 Loss=0.1592 Model: y = 0.5979x1 + 0.1509x2 + -9.756e-10
Epoch 160 Loss=0.1564 Model: y = 0.6142x1 + 0.1465x2 + -4.144e-10
Epoch 170 Loss=0.1539 Model: y = 0.6292x1 + 0.1416x2 + -1.001e-10
Epoch 180 Loss=0.1518 Model: y = 0.643x1 + 0.1364x2 + -3.236e-10
Epoch 190 Loss=0.1498 Model: y = 0.6559x1 + 0.131x2 + -6.286e-11
Epoch 200 Loss=0.1481 Model: y = 0.6678x1 + 0.1255x2 + 2.119e-10
Epoch 210 Loss=0.1466 Model: y = 0.6789x1 + 0.1199x2 + -1.956e-10
Epoch 220 Loss=0.1452 Model: y = 0.6892x1 + 0.1142x2 + -1.758e-10
Epoch 230 Loss=0.1439 Model: y = 0.6989x1 + 0.1085x2 + -4.307e-11
Epoch 240 Loss=0.1428 Model: y = 0.708x1 + 0.1029x2 + 3.376e-10
Epoch 250 Loss=0.1418 Model: y = 0.7165x1 + 0.09736x2 + 2.841e-10
Epoch 260 Loss=0.1408 Model: y = 0.7245x1 + 0.09189x2 + 3.295e-10
Epoch 270 Loss=0.14 Model: y = 0.732x1 + 0.08653x2 + -8.033e-11
Epoch 280 Loss=0.1392 Model: y = 0.7391x1 + 0.08128x2 + 1.141e-10
Epoch 290 Loss=0.1385 Model: y = 0.7458x1 + 0.07616x2 + 1.321e-10
Epoch 300 Loss=0.1378 Model: y = 0.7522x1 + 0.07118x2 + 5.087e-10
Epoch 310 Loss=0.1372 Model: y = 0.7582x1 + 0.06634x2 + 7.398e-10
Epoch 320 Loss=0.1367 Model: y = 0.7639x1 + 0.06165x2 + 6.845e-10
Epoch 330 Loss=0.1362 Model: y = 0.7693x1 + 0.0571x2 + 8.423e-10
Epoch 340 Loss=0.1357 Model: y = 0.7744x1 + 0.0527x2 + 9.252e-10
Epoch 350 Loss=0.1353 Model: y = 0.7793x1 + 0.04845x2 + 1.104e-09
Epoch 360 Loss=0.1349 Model: y = 0.784x1 + 0.04435x2 + 1.145e-09
Epoch 370 Loss=0.1346 Model: y = 0.7884x1 + 0.0404x2 + 1.631e-09
Epoch 380 Loss=0.1343 Model: y = 0.7926x1 + 0.03658x2 + 1.446e-09
Epoch 390 Loss=0.134 Model: y = 0.7966x1 + 0.03291x2 + 1.429e-09
Epoch 400 Loss=0.1337 Model: y = 0.8004x1 + 0.02938x2 + 1.694e-09
Epoch 410 Loss=0.1334 Model: y = 0.8041x1 + 0.02598x2 + 1.697e-09
Epoch 420 Loss=0.1332 Model: y = 0.8076x1 + 0.02271x2 + 2.125e-09
Epoch 430 Loss=0.133 Model: y = 0.8109x1 + 0.01957x2 + 2.292e-09
Epoch 440 Loss=0.1328 Model: y = 0.8141x1 + 0.01655x2 + 2.913e-09
Epoch 450 Loss=0.1326 Model: y = 0.8171x1 + 0.01366x2 + 3.412e-09
Epoch 460 Loss=0.1325 Model: y = 0.82x1 + 0.01087x2 + 3.749e-09
Epoch 470 Loss=0.1323 Model: y = 0.8228x1 + 0.008204x2 + 3.499e-09
Epoch 480 Loss=0.1322 Model: y = 0.8254x1 + 0.005641x2 + 3.663e-09
Epoch 490 Loss=0.1321 Model: y = 0.828x1 + 0.003183x2 + 4.2e-09
Epoch 500 Loss=0.132 Model: y = 0.8304x1 + 0.0008239x2 + 4.138e-09
TensorBoard可视化数据流图:
首先创建数据流图需要的events文件:
# 在Session会话中写入如下代码:(第9行)
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
#----------------------- 用Tensorboard进行可视化 ------------------------#
# 首先要创建FileWriter实例,将其放置在当前目录下
# summaty接收两个参数:保存目录及要保存的是哪个会话
writer = tf.summary.FileWriter("./summary/linear-regression-1/", sess.graph)
# 开始训练模型
# 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
for e in range(1, epoch + 1):
sess.run(train_op, feed_dict={X: X_data, y: y_data})
if e % 10 == 0:
loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, w[1], w[2], w[0]))
# 记得最后要关闭writer
# 这样程序执行完之后就会生成一个events文件,供TensorBoard使用
writer.close()
为数据流图加上名字作用域:
##############################################################################################
######################## 创建模型 ########################
##############################################################################################
import tensorflow as tf
alpha = 0.01 # 设置学习率
epoch = 500 # 设置总共要训练的轮数
#-------------- 创建一个线性回归模型 --------------#
# 首先定义模型中要用到的一些数据
with tf.name_scope('input'):
X = tf.placeholder(tf.float32, X_data.shape, name='X') # 输入X,形状为[47, 3]
y = tf.placeholder(tf.float32, y_data.shape, name='y') # 输入Y,形状为[47, 1]
with tf.name_scope('hypothesis'):
# 权重变量W,形状为[3, 1]
W = tf.get_variable('weights',(X_data.shape[1], 1), initializer=tf.constant_initializer())
# 假设模型的表达式为:h(x) = w0 * x0 + w1 * x1 + w2 * x2,其中x0恒为1,用来计算偏置项
# 将该表达式用矩阵乘法来表示
y_pred = tf.matmul(X, W, name='y_pred') # 得到的y_pred的形状为[47, 1]
#------------- 接下来要考虑损失函数和梯度下降策略 -------------#
# 这里损失函数用L2损失:
# 注意tf.matmul(a, b, transpose_a=True)表示矩阵a的转置乘以矩阵b,在这里即为 [1, 47] x [47, 1]
# 因此最终loss_op得到的是一个数
with tf.name_scope('loss'):
loss_op = 1 / (2 * len(X_data)) * tf.matmul((y_pred - y), (y_pred - y), transpose_a=True)
with tf.name_scope('train'):
# 这里采用随机梯度下降优化器,设置学习率为alpha
opt = tf.train.GradientDescentOptimizer(learning_rate=alpha)
# 定义每一步的训练目标:最小化loss函数
train_op = opt.minimize(loss_op)
这样创建出来的数据流图就会显示我们定义的节点的名称,使数据流图更具有可读性。
在当前目录生成events文件之后:
-
如果是在Windows环境下,直接在vscode的控制台输入以下命令:
tensorboard --logdir ./ --host localhost
其中
--logdir
指定用当前目录,--host
指定用localhost
。之后会生成一个链接,按
Ctrl + 鼠标左键
即可打开该链接,然后便可以看到生成的数据流图。
使用Matplotlib可视化损失函数
with tf.Session() as sess:
# 初始化全局变量
sess.run(tf.global_variables_initializer())
#----------------------- 用Tensorboard进行可视化 ------------------------#
# 首先要创建FileWriter实例,将其放置在当前目录下
# summaty接收两个参数:保存目录及要保存的是哪个会话
writer = tf.summary.FileWriter("./summary/linear-regression-1/", sess.graph)
# 记录损失值,以方便可视化损失函数
loss_data = []
# 开始训练模型
# 这里因为数据集比较小(只有47个样本),所以每次都用全部的数据进行训练
for e in range(1, epoch + 1):
_, loss, w = sess.run([train_op, loss_op, W], feed_dict={X: X_data, y: y_data})
# 记录每一轮损失值变化情况
loss_data.append(float(loss))
if e % 10 == 0:
loss, w = sess.run([loss_op, W], feed_dict={X: X_data, y: y_data})
log_str = "Epoch %d \t Loss=%.4g \t Model: y = %.4gx1 + %.4gx2 + %.4g"
print(log_str % (e, loss, w[1], w[2], w[0]))
# 记得最后要关闭writer
# 这样程序执行完之后就会生成一个events文件,供TensorBoard使用
writer.close()
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(context='notebook', style='whitegrid', palette='dark')
ax = sns.lineplot(x='epoch', y='loss', data=pd.DataFrame({'loss': loss_data, 'epoch': np.arange(epoch)}))
ax.set_xlabel('epoch')
ax.set_ylabel('loss')
plt.show()
用这种方法有一个很大的缺点:首先需要把所有要可视化的量都记录下来,当要可视化的变量非常多时,这种方法会非常麻烦。
附:数据集的链接及提取码
链接:https://pan.baidu.com/s/11fHYCGZ30EVoCgINUxBL6g
提取码:ie95