TF基本
import tensorflow as tf
Tensorflow对于机器学习模型的实现分为两个阶段:
1. 构建阶段:搭建计算模型
2. 计算阶段:运行计算
举个简单示例,我们要计算一个函数 ,首先需要将这个计算模型搭建起来。
Tensorflow本身提供了可视化的套件叫做Tensorboard,在模型搭建之前,我们先将Tensorboard设置好。
from datetime import datetime
now=datetime.utcnow().strftime("%Y%m%d%H%M%S")
root_logdir="tf_logs" #设置根目录为当前目录下的tf_logs文件夹
logdir="{}/run-{}/".format(root_logdir,now) #文件夹名加入时间戳
模型的搭建包括:
- 变量的设置与初始值设置
- 变量之间的运算关系
tf.reset_default_graph() #重置图
x=tf.Variable(1,name="x") #初始值为1,名为"x"的变量
y=tf.Variable(2,name="y") #初始值为2,名为"y"的变量
f=x*x*y+y+2 #变量间的运算关系
file_writer=tf.summary.FileWriter(logdir,tf.get_default_graph()) #将默认图写入文件
然后启动一个会话,在会话中进行计算:
with tf.Session() as sess:
x.initializer.run()
y.initializer.run()
result=f.eval()
file_writer.close() #关闭写入器
print(result)
输出6。
需要注意的是上述代码中,x,y均是作为tf变量存在,tf变量有如下特点:
- 需要设定初始值
- 在计算之前需要在会话中进行初始化
- 变量的生命周期开始于初始化,与会话一同结束
因为我们在上述代码中保存了图,所以可以在Tensorboard中观察。在控制台中键入tensorboard --logdir C:\Users\qq435\Desktop\tf_logs
启动Tensorboard服务,在浏览器中键入http://daya-workstation:6006/
进入Tensorboard的页面。
上述模型(方程式)的计算图如下图所示:
Tensorflow对于模型的实现既然分为构建阶段和计算阶段,那么理所当然地,构建阶段是不进行计算的,计算任务均在计算阶段进行。
线性模型
这节我们使用TF搭建线性模型对加州房价数据进行处理。
前置模块与设置
import tensorflow
import numpy as np
from datetime import datetime
root_logdir="tf_logs" #设置根目录为当前目录下的tf_logs文件夹
获取数据
from sklearn.datasets import fetch_california_housing
housing=fetch_california_housing() #每一个样本为行向量
m,n=housing.data.shape #m为样本数
计算模型搭建
正规方程
利用正规方程 优化线性模型。
housing_data_plus_bias=np.c_[np.ones((m,1)),housing.data] #在数据第一列前加上偏置项1
tf.reset_default_graph()
X=tf.constant(housing_data_plus_bias,dtype=tf.float32,name="X") #常量值不需要初始化
Y=tf.constant(housing.target.reshape(-1,1),dtype=tf.float32,name="Y")
XT=tf.transpose(X)
W=tf.matmul(tf.matmul(tf.matrix_inverse(tf.matmul(XT,X)),XT),Y) #正规方程
now=datetime.utcnow().strftime("%Y%m%d%H%M%S")
logdir="{}/run-{}/".format(root_logdir,now) #文件夹名加入时间戳
file_writer=tf.summary.FileWriter(logdir,tf.get_default_graph())
with tf.Session() as sess:
W_val=W.eval()
file_writer.close()
print(W_val)
以上代码所生成的计算图如下图所示:
梯度下降法
以MSE作为损失函数,使用梯度下降法来优化线性模型。
在使用梯度下降法时,预先对数据进行缩放处理能够加快收敛,使用sklearn中的预处理包来进行缩放。
from sklearn.preprocessing import StandardScaler
#数据缩放
scaler = StandardScaler()
scaled_housing_data = scaler.fit_transform(housing.data)
scaled_housing_data_plus_bias = np.c_[np.ones((m, 1)), scaled_housing_data]
在搭建模型之前,先介绍一种Tensorflow中的新类型:placeholder。placeholder在Tensorboard中表现为一个占位节点,其在计算阶段需要输入数据才能进行计算,否则报错。
使用tf搭建模型的惯用方法是将输入数据X与数据标签Y通过placeholder来实现,然后在计算阶段对X、Y输入相应的数据与标签即可。具体做法见代码。
在使用梯度下降法时,我们可以绘制出loss-epoch学习曲线,Tensorboard中提供了非常便捷的曲线可视化功能。下述两段代码都将MSE与epoch写入到了Tensorboard文件中以供可视化。
batch梯度下降
#构建计算图
tf.reset_default_graph()
n_epochs=1000
learning_rate=0.01
X=tf.placeholder(dtype=tf.float32,name="X")
Y=tf.placeholder(dtype=tf.float32,name="Y")
W=tf.Variable(tf.random_uniform([n+1,1],-1,1),name="W") #因为X第一列加了偏置项,所以W的形状对应的需要加1
Y_pre=tf.matmul(X,W,name="prediction")
#整合节点
with tf.name_scope("loss") as scope:
error=Y_pre-Y
mse=tf.reduce_mean(tf.square(error),name="mse")
optimizer=tf.train.GradientDescentOptimizer(learning_rate=learning_rate) #设置优化器
training_op=optimizer.minimize(mse) #优化目标
#tensorboard设置
mse_summary=tf.summary.scalar('MSE',mse)
now=datetime.utcnow().strftime("%Y%m%d%H%M%S")
logdir="{}/run-{}/".format(root_logdir,now) #文件夹名加入时间戳
file_writer=tf.summary.FileWriter(logdir,tf.get_default_graph())
with tf.Session() as sess:
W.initializer.run()
for epoch in range(n_epochs):
if epoch%10==0:
#计算过程需要对placeholder给数据
summary_str=mse_summary.eval(feed_dict={X:scaled_housing_data_plus_bias,Y:housing.target.reshape(-1,1)})
file_writer.add_summary(summary_str,epoch)
sess.run(training_op,feed_dict={X:scaled_housing_data_plus_bias,Y:housing.target.reshape(-1,1)}) #给数据
W_val=W.eval()
print(W_val)
file_writer.close()
计算图如下图所示:
学习曲线如图所示:
mini-batch梯度下降
#构建计算图
tf.reset_default_graph()
n_epochs=10
learning_rate=0.01
X=tf.placeholder(dtype=tf.float32,name="X")
Y=tf.placeholder(dtype=tf.float32,name="Y")
W=tf.Variable(tf.random_uniform([n+1,1],-1,1),name="W")
batch_size=100
n_batches=int(np.ceil(m/batch_size))
#随机取batch
def fetch_batch(epoch,batch_index,batch_size):
np.random.seed(epoch * n_batches + batch_index)
indices = np.random.randint(m, size=batch_size)
X_batch = scaled_housing_data_plus_bias[indices]
Y_batch = housing.target.reshape(-1, 1)[indices]
return X_batch,Y_batch
Y_pre=tf.matmul(X,W,name="prediction")
#整合节点
with tf.name_scope("loss") as scope:
error=Y_pre-Y
mse=tf.reduce_mean(tf.square(error),name="mse")
optimizer=tf.train.GradientDescentOptimizer(learning_rate=learning_rate) #设置优化器
training_op=optimizer.minimize(mse) #优化目标
#tensorboard设置
mse_summary=tf.summary.scalar('MSE',mse)
now=datetime.utcnow().strftime("%Y%m%d%H%M%S")
logdir="{}/run-{}/".format(root_logdir,now) #文件夹名加入时间戳
file_writer=tf.summary.FileWriter(logdir,tf.get_default_graph())
with tf.Session() as sess:
W.initializer.run()
for epoch in range(n_epochs):
for batch_index in range(n_batches):
X_batch,Y_batch=fetch_batch(epoch,batch_index,batch_size)
if batch_index%10==0:
summary_str=mse_summary.eval(feed_dict={X:X_batch,Y:Y_batch}) #给数据
file_writer.add_summary(summary_str,epoch*batch_size+batch_index)
sess.run(training_op,feed_dict={X:X_batch,Y:Y_batch}) #给数据
W_val=W.eval()
print(W_val)
file_writer.close()
mini-batch梯度下降的计算图与batch梯度下降是一样的,因为没有改变计算过程,只是将数据分批多次输入。
学习曲线如下图所示: