Tensorflow,线性模型,梯度下降

TF基本

import tensorflow as tf

Tensorflow对于机器学习模型的实现分为两个阶段:
1. 构建阶段:搭建计算模型
2. 计算阶段:运行计算

举个简单示例,我们要计算一个函数 f = x 2 y + y + 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搭建线性模型对加州房价数据进行处理。

扫描二维码关注公众号,回复: 1926207 查看本文章

前置模块与设置

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为样本数

计算模型搭建

正规方程

利用正规方程 W = ( X T X ) 1 X T Y 优化线性模型。

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梯度下降是一样的,因为没有改变计算过程,只是将数据分批多次输入。

学习曲线如下图所示:

猜你喜欢

转载自blog.csdn.net/qq_31823267/article/details/79408904