使用 TensorFlow 的线性回归教程 [示例]

什么是线性回归?

线性回归是一种统计方法,用于模拟两个变量之间的关系。这种建模是在一个标量响应和一个或多个解释变量之间进行的。与一个解释变量的关系称为简单线性回归,而具有一个以上解释变量的关系称为多元线性回归。

TensorFlow 提供了工具来完全控制计算。这是通过低级 API 完成的。在此基础上,TensorFlow 配备了各种 API 来执行许多机器学习算法。这是高级 API。TensorFlow 将它们称为估计器

  • 低级 API:从头开始构建模型架构和优化。对于初学者来说很复杂
  • 高级 API:定义算法。它对用户更友好。TensorFlow 提供了一个名为估计器的工具箱来构建、训练、评估和进行预测。

在本教程中,您将仅使用估计器。计算速度更快,并且更易于实现。教程的第一部分解释了如何使用梯度下降优化器在 TensorFlow 中训练线性回归。在第二部分中,您将使用波士顿数据集通过 TensorFlow 估计器预测房屋价格。

下载波士顿数据集

如何训练线性回归模型

在我们开始训练模型之前,让我们先看看什么是线性回归。

想象一下您有两个变量,x 和 y,您的任务是在知道 x 的值的情况下预测 y 的值。如果您绘制数据,您会看到自变量 x 和因变量 y 之间存在正相关关系。

Train a Linear Regression Model

您可能会注意到,如果 x=1,y 大约等于 6;如果 x=2,y 大约等于 8.5。

这不是一种非常准确的方法,并且容易出错,尤其是在拥有数十万个数据点的数据集上。

线性回归通过一个方程进行评估。变量 y 由一个或多个协变量解释。在您的示例中,只有一个因变量。如果要写出此方程,它将是

Train a Linear Regression Model

其中

  • Linear Regression with TensorFlow是偏差。即,如果 x=0,y=训练线性回归模型
  • Train a Linear Regression Model是与 x 相关的权重
  • Train a Linear Regression Model是残差或模型的误差。它包括模型无法从数据中学到的内容

想象一下您拟合了模型,并找到了以下解

  • Train a Linear Regression Model = 3.8
  • Train a Linear Regression Model = 2.78

您可以将这些数字代入方程,得到

y= 3.8 + 2.78x

现在您有了一种更好的方法来查找 y 的值。也就是说,您可以将 x 替换为任何您想要预测 y 的值。在下图所示,我们将 x 替换为数据集中所有值,并绘制结果。

Train a Linear Regression Model

红线代表拟合值,即每个 x 值的 y 值。您无需查看 x 的值即可预测 y,对于每个 x 都有一个属于红线的值。您也可以预测大于 2 的 x 值!

如果您想将线性回归扩展到更多的协变量,您可以通过向模型添加更多变量来实现。传统分析与线性回归的区别在于,线性回归关注 y 如何对每个自变量 x 做出反应。

让我们看一个例子。想象一下您想预测一家冰淇淋店的销售额。数据集包含各种信息,例如天气(例如下雨、晴天、多云)、客户信息(例如薪水、性别、婚姻状况)。

传统分析将尝试通过计算每个变量的平均值来预测销售额,并尝试估计不同场景下的销售额。这将导致预测不佳,并将分析限制在选定的场景。

如果您使用线性回归,您可以写出这个方程

Train a Linear Regression Model

算法将找到权重的最佳解决方案;这意味着它将尝试最小化成本(拟合线与数据点之间的差异)。

算法如何工作

Working of Algorithm

算法将为每个TensorFlow 线性回归选择一个随机数算法工作原理并替换 x 的值以获得 y 的预测值。如果数据集有 100 个观测值,算法将计算 100 个预测值。

我们可以计算误差,表示为算法工作原理模型的误差,即预测值与真实值之间的差异。正误差表示模型低估了 y 的预测值,负误差表示模型高估了 y 的预测值。

Working of Algorithm

您的目标是最小化误差的平方。算法计算平均误差平方。此步骤称为误差最小化。对于线性回归,它是均方误差,也称为 MSE。数学上,它是

Working of Algorithm

Where

  • Working of Algorithm是权重,所以算法工作原理表示预测值
  • y 是真实值
  • m 是观测值的数量

请注意,算法工作原理表示它使用矩阵的转置。 算法工作原理是均值的数学表示。

目标是找到最佳算法工作原理来最小化 MSE

如果平均误差很大,则表示模型性能不佳,权重选择不当。要校正权重,您需要使用优化器。传统的优化器称为梯度下降

梯度下降取导数并增加或减少权重。如果导数为正,则权重减小。如果导数为负,则权重增加。模型将更新权重并重新计算误差。此过程重复进行,直到误差不再改变。每个过程称为一个迭代。此外,梯度乘以学习率。它表示学习的速度。

如果学习率太小,算法将需要很长时间才能收敛(即需要大量迭代)。如果学习率太高,算法可能永远无法收敛。

Working of Algorithm

从上图可以看出,模型重复该过程约 20 次,然后找到权重的稳定值,从而达到最低误差。

请注意,误差不等于零,但稳定在 5 左右。这意味着模型会产生典型的 5 误差。如果您想减小误差,您需要向模型添加更多信息,例如更多变量或使用不同的估计器。

您还记得第一个方程

Working of Algorithm

最终权重是 3.8 和 2.78。下面的视频向您展示了梯度下降如何优化损失函数以找到这些权重

如何使用 TensorFlow 训练线性回归

现在您对幕后发生了什么有了更好的了解,您可以使用 TensorFlow 提供的估计器 API 来训练您的第一个 TensorFlow 线性回归。

您将使用波士顿数据集,其中包含以下变量

crim 每个城镇的人均犯罪率
zn 面积超过 25,000 平方英尺的住宅用地比例。
indus 每个城镇非零售商业地产的比例。
nox 硝酸氧化物浓度
rm 每户平均房间数
age 1940 年前建造的自住单位比例
dis 到波士顿五个就业中心的加权距离
tax 每万美元的全部房产税率
ptratio 每个城镇的师生比例
medv 自住房屋的中位数价值(以千美元为单位)

您将创建三个不同的数据集

数据集 目标 形状
训练 训练模型并获得权重 400, 10
评估 评估模型在未见过的数据上的性能 100, 10
预测 使用模型预测新数据上的房价 6, 10

目标是利用数据集的特征来预测房屋的价值。

在本教程的第二部分中,您将学习如何使用 TensorFlow 通过三种不同的方式导入数据

  • 使用 Pandas
  • 使用Numpy
  • 仅 TF

请注意,所有选项结果相同。

您将学习如何使用高级 API 来构建、训练和评估 TensorFlow 线性回归模型。如果您使用的是低级 API,您将不得不手动定义

  • 损失函数
  • 优化器:梯度下降
  • 矩阵乘法
  • 图和张量

这对于初学者来说很繁琐且更复杂。

Pandas

您需要导入必要的库来训练模型。

import pandas as pd
from sklearn import datasets
import tensorflow as tf
import itertools

第 1 步)使用 Pandas 导入数据。

您定义列名并将其存储在 COLUMNS 中。您可以使用 pd.read_csv() 导入数据。

COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",
           "dis", "tax", "ptratio", "medv"]

training_set = pd.read_csv(“E:/boston_train.csv”, skipinitialspace=True,skiprows=1, names=COLUMNS)

test_set = pd.read_csv(“E:/boston_test.csv”, skipinitialspace=True,skiprows=1, names=COLUMNS)

prediction_set = pd.read_csv(“E:/boston_predict.csv”, skipinitialspace=True,skiprows=1, names=COLUMNS)

您可以打印数据的形状。

print(training_set.shape, test_set.shape, prediction_set.shape)

输出

(400, 10) (100, 10) (6, 10)

请注意,标签,即您的 y,已包含在数据集中。所以您需要定义另外两个列表。一个只包含特征,一个只包含标签的名称。这两个列表将告诉您的估计器数据中的特征是什么,以及标签的列名是什么

它是使用以下代码完成的。

FEATURES = ["crim", "zn", "indus", "nox", "rm",				
                 "age", "dis", "tax", "ptratio"]
LABEL = "medv"

第 2 步)转换数据

您需要将数字变量转换为正确的格式。TensorFlow 提供了一种转换连续变量的方法:tf.feature_column.numeric_column()。

在之前的步骤中,您定义了一个您想包含在模型中的特征列表。现在您可以使用此列表将它们转换为数字数据。如果您想在模型中排除特征,请在构造 feature_cols 之前随意删除一个或多个变量 FEATURES 列表

请注意,您将使用 Python 列表推导式和 FEATURES 列表来创建一个名为 feature_cols 的新列表。它有助于您避免九次编写 tf.feature_column.numeric_column()。列表推导式是一种更快、更简洁的新列表创建方法

feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]

第 3 步)定义估计器

在此步骤中,您需要定义估计器。TensorFlow 目前提供了 6 个预构建的估计器,包括 3 个用于分类任务和 3 个用于 TensorFlow 回归任务

  • 回归器
    • DNNRegressor
    • LinearRegressor
    • DNNLineaCombinedRegressor
  • 分类器
    • DNNClassifier
    • LinearClassifier
    • DNNLineaCombinedClassifier

在本教程中,您将使用 Linear Regressor。要访问此功能,您需要使用 tf.estimator。

该函数需要两个参数

  • feature_columns:包含要包含在模型中的变量
  • model_dir:存储图、保存模型参数等的路径

TensorFlow 将在您的工作目录中自动创建一个名为 train 的文件。您需要使用此路径来访问 Tensorboard,如下面的 TensorFlow 回归示例所示。

estimator = tf.estimator.LinearRegressor(    
        feature_columns=feature_cols,   
        model_dir="train")

输出

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a215dc550>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

TensorFlow 的棘手之处在于为模型提供数据的方式。TensorFlow 设计用于并行计算和非常大的数据集。由于机器资源的限制,不可能一次将所有数据输入模型。为此,您需要每次输入一批数据。请注意,我们讨论的是拥有数百万甚至更多记录的巨大数据集。如果您不添加批处理,您最终会遇到内存错误。

例如,如果您的数据包含 100 个观测值,并且您定义了一个批次大小为 10,则表示模型在每次迭代中会看到 10 个观测值(10*10)。

当模型看到所有数据后,它完成一个epoch。Epoch 定义了您希望模型查看数据的次数。最好将此步骤设置为 none,让模型执行指定次数的迭代。

第二个要添加的信息是您是否想在每次迭代前对数据进行洗牌。在训练过程中,洗牌数据很重要,这样模型就不会学习数据集的特定模式。如果模型学习了数据底层模式的细节,它将在泛化预测未见过的数据时遇到困难。这称为过拟合。模型在训练数据上表现良好,但无法正确预测未见过的数据。

TensorFlow 使这两个步骤变得容易。当数据进入管道时,它会知道需要多少观测值(批次)以及是否需要洗牌数据。

要指示 TensorFlow 如何为模型提供数据,您可以使用 pandas_input_fn。此对象需要 5 个参数

  • x:特征数据
  • y:标签数据
  • batch_size:批次大小。默认为 128
  • num_epoch:Epoch 数量,默认为 1
  • shuffle:是否洗牌数据。默认为 None

您需要多次向模型提供数据,因此您需要定义一个函数来重复此过程。所有这些函数 get_input_fn。

def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):    
         return tf.estimator.inputs.pandas_input_fn(       
         x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),       
         y = pd.Series(data_set[LABEL].values),       
         batch_size=n_batch,          
         num_epochs=num_epochs,       
         shuffle=shuffle)

评估模型性能的常用方法是

  • 训练模型
  • 在不同的数据集上评估模型
  • 进行预测

TensorFlow 估计器提供了三个不同的函数来轻松完成这三个步骤。

第 4 步):训练模型

您可以使用估计器的 train 来评估模型。train 估计器需要一个 input_fn 和一个迭代次数。您可以使用上面创建的函数为模型提供数据。然后,您指示模型迭代 1000 次。请注意,您没有指定 epoch 的数量,而是让模型迭代 1000 次。如果您将 epoch 设置为 1,那么模型将迭代 4 次:训练集有 400 条记录,批次大小为 128

  1. 128 行
  2. 128 行
  3. 128 行
  4. 16 行

因此,最好将 epoch 设置为 none 并定义迭代次数,如下面的 TensorFlow 分类示例所示。

estimator.train(input_fn=get_input_fn(training_set,                                       
                                           num_epochs=None,                                      
                                           n_batch = 128,                                      
                                           shuffle=False),                                      
                                           steps=1000)

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 238.616
INFO:tensorflow:loss = 13909.657, step = 101 (0.420 sec)
INFO:tensorflow:global_step/sec: 314.293
INFO:tensorflow:loss = 12881.449, step = 201 (0.320 sec)
INFO:tensorflow:global_step/sec: 303.863
INFO:tensorflow:loss = 12391.541, step = 301 (0.327 sec)
INFO:tensorflow:global_step/sec: 308.782
INFO:tensorflow:loss = 12050.5625, step = 401 (0.326 sec)
INFO:tensorflow:global_step/sec: 244.969
INFO:tensorflow:loss = 11766.134, step = 501 (0.407 sec)
INFO:tensorflow:global_step/sec: 155.966
INFO:tensorflow:loss = 11509.922, step = 601 (0.641 sec)
INFO:tensorflow:global_step/sec: 263.256
INFO:tensorflow:loss = 11272.889, step = 701 (0.379 sec)
INFO:tensorflow:global_step/sec: 254.112
INFO:tensorflow:loss = 11051.9795, step = 801 (0.396 sec)
INFO:tensorflow:global_step/sec: 292.405
INFO:tensorflow:loss = 10845.855, step = 901 (0.341 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.9873.

您可以使用以下命令检查 Tensorboard

activate hello-tf
# For MacOS
tensorboard --logdir=./train
# For Windows
tensorboard --logdir=train

第 5 步)评估您的模型

您可以使用以下代码评估模型在测试集上的拟合度

ev = estimator.evaluate(    
          input_fn=get_input_fn(test_set,                          
          num_epochs=1,                          
          n_batch = 128,                          
          shuffle=False))

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-01:43:13
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-01:43:13
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896

您可以使用以下代码打印损失

loss_score = ev["loss"]
print("Loss: {0:f}".format(loss_score))

输出

Loss: 3215.895996

模型损失为 3215。您可以查看摘要统计信息以了解误差的大小。

training_set['medv'].describe()

输出

count    400.000000
mean      22.625500
std        9.572593
min        5.000000
25%       16.600000
50%       21.400000
75%       25.025000
max       50.000000
Name: medv, dtype: float64

从上面的摘要统计中,您知道房屋的平均价格是 22 千美元,最低价格是 9 千美元,最高价格是 50 千美元。该模型产生的典型误差为 3k 美元。

第 6 步)进行预测

最后,您可以使用 TensorFlow 的 predict 估计器来估计 6 栋波士顿房屋的价值。

y = estimator.predict(    
         input_fn=get_input_fn(prediction_set,                          
         num_epochs=1,                          
         n_batch = 128,                          
         shuffle=False))

要打印的估计值,您可以使用此代码

predictions = list(p["predictions"] for p in itertools.islice(y, 6))print("Predictions: {}".format(str(predictions)))

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.96125], dtype=float32), array([27.270979], dtype=float32), array([29.299236], dtype=float32), array([16.436684], dtype=float32), array([21.460876], dtype=float32)]

模型预测了以下值

房屋 预测
1 32.29
2 18.96
3 27.27
4 29.29
5 16.43
7 21.46

请注意,我们不知道真实值。在深度学习教程中,您将尝试击败线性模型

Numpy 解决方案

本节介绍如何使用 numpy 估计器来馈送数据来训练模型。方法相同,只是您将使用 numpy_input_fn 估计器。

training_set_n = pd.read_csv(“E:/boston_train.csv”).values

test_set_n = pd.read_csv(“E:/boston_test.csv”).values

prediction_set_n = pd.read_csv(“E:/boston_predict.csv”).values

第 1 步)导入数据

首先,您需要区分特征变量和标签。您需要对训练数据和评估数据执行此操作。定义一个函数来分割数据会更快。

def prepare_data(df):     
        X_train = df[:, :-3]    
        y_train = df[:,-3]    
        return X_train, y_train

您可以使用该函数从训练/评估数据集中分割标签和特征

X_train, y_train = prepare_data(training_set_n)
X_test, y_test = prepare_data(test_set_n)

您需要排除预测数据集的最后一列,因为它只包含 NaN

x_predict = prediction_set_n[:, :-2]

确认数组的形状。请注意,标签不应具有维度,它意味着(400,)。

print(X_train.shape, y_train.shape, x_predict.shape)

输出

(400, 9) (400,) (6, 9)

您可以按以下方式构建特征列

feature_columns = [      tf.feature_column.numeric_column('x', shape=X_train.shape[1:])]

估计器定义如前所述,您指示特征列和存储图的位置。

estimator = tf.estimator.LinearRegressor(    
         feature_columns=feature_columns,    
         model_dir="train1")

输出

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a218d8f28>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

您可以使用 numpy 估计器将数据馈送到模型,然后训练模型。请注意,我们之前定义了 input_fn 函数以方便阅读。

# Train the estimatortrain_input = tf.estimator.inputs.numpy_input_fn(   
           x={"x": X_train},    
           y=y_train,    
           batch_size=128,    
           shuffle=False,    
           num_epochs=None)
           estimator.train(input_fn = train_input,steps=5000)

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train1/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 490.057
INFO:tensorflow:loss = 13909.656, step = 101 (0.206 sec)
INFO:tensorflow:global_step/sec: 788.986
INFO:tensorflow:loss = 12881.45, step = 201 (0.126 sec)
INFO:tensorflow:global_step/sec: 736.339
INFO:tensorflow:loss = 12391.541, step = 301 (0.136 sec)
INFO:tensorflow:global_step/sec: 383.305
INFO:tensorflow:loss = 12050.561, step = 401 (0.260 sec)
INFO:tensorflow:global_step/sec: 859.832
INFO:tensorflow:loss = 11766.133, step = 501 (0.117 sec)
INFO:tensorflow:global_step/sec: 804.394
INFO:tensorflow:loss = 11509.918, step = 601 (0.125 sec)
INFO:tensorflow:global_step/sec: 753.059
INFO:tensorflow:loss = 11272.891, step = 701 (0.134 sec)
INFO:tensorflow:global_step/sec: 402.165
INFO:tensorflow:loss = 11051.979, step = 801 (0.248 sec)
INFO:tensorflow:global_step/sec: 344.022
INFO:tensorflow:loss = 10845.854, step = 901 (0.288 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train1/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.985.
Out[23]:
<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1b6ea860>

您使用不同的估计器重复相同的步骤来评估您的模型

eval_input = tf.estimator.inputs.numpy_input_fn(    
       x={"x": X_test},    
       y=y_test, 
       shuffle=False,    
       batch_size=128,    
       num_epochs=1)
   estimator.evaluate(eval_input,steps=None)

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-01:44:00
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-01:44:00
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.158947, global_step = 1000, loss = 3215.8945
Out[24]:
{'average_loss': 32.158947, 'global_step': 1000, 'loss': 3215.8945}

最后,您可以计算预测。它应该与 Pandas 相似。

test_input = tf.estimator.inputs.numpy_input_fn(    
        x={"x": x_predict},    
        batch_size=128,    
        num_epochs=1,   
        shuffle=False)
        y = estimator.predict(test_input) 			
predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Predictions: [array([32.297546], dtype=float32), array([18.961248], dtype=float32), array([27.270979], dtype=float32), array([29.299242], dtype=float32), array([16.43668], dtype=float32), array([21.460878], dtype=float32)]

Tensorflow 解决方案

最后一节是关于 TensorFlow 解决方案的。此方法比其他方法稍微复杂一些。

请注意,如果您使用Jupyter notebook,您需要重启并清理内核才能运行此会话。

TensorFlow 构建了一个强大的工具来将数据传入管道。在本节中,您将自行构建 input_fn 函数。

第 1 步)定义数据的路径和格式

首先,您声明两个变量,其中包含 csv 文件的路径。请注意,您有两个文件,一个用于训练集,一个用于测试集。

import tensorflow as tf
df_train = "E:/boston_train.csv"
df_eval = "E:/boston_test.csv"

然后,您需要定义要从 csv 文件使用的列。我们将使用所有列。之后,您需要声明它是哪种类型的变量。

浮点变量定义为 [0.]

COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",				
                "dis", "tax", "ptratio", "medv"]RECORDS_ALL = [[0.0], [0.0], [0.0], [0.0],[0.0],[0.0],[0.0],[0.0],[0.0],[0.0]]

第 2 步)定义 input_fn 函数

该函数可以分为三个部分

  1. 导入数据
  2. 创建迭代器
  3. 消耗数据

以下是定义函数的整体代码。代码将在之后进行解释

def input_fn(data_file, batch_size, num_epoch = None):				
       # Step 1				
          def parse_csv(value):        
          columns = tf.decode_csv(value, record_defaults= RECORDS_ALL)        
          features = dict(zip(COLUMNS, columns))				
          #labels = features.pop('median_house_value')        
          labels =  features.pop('medv')        
          return features, labels							
          
          # Extract lines from input files using the 
          Dataset API.    dataset = (tf.data.TextLineDataset(data_file) # Read text file       
          .skip(1) # Skip header row       
          .map(parse_csv))			   
          
          dataset = dataset.repeat(num_epoch)    
          dataset = dataset.batch(batch_size) 				
          # Step 3    
          iterator = dataset.make_one_shot_iterator()    
          features, labels = iterator.get_next()    
          return features, labels

**导入数据**

对于 csv 文件,dataset 方法一次读取一行。要构建数据集,您需要使用 TextLineDataset 对象。您的数据集有标题,所以您需要使用 skip(1) 来跳过第一行。此时,您只读取数据并排除管道中的标题。为了馈送模型,您需要将特征与标签分开。用于对数据应用任何转换的方法是 map。

此方法调用您将创建的函数来指示如何转换数据。简而言之,您需要将数据传入 TextLineDataset 对象,排除标题,并应用由函数指示的转换。代码解释

  • tf.data.TextLineDataset(data_file):此行读取 csv 文件
  • .skip(1) :跳过标题
  • .map(parse_csv)):将记录解析为张量您需要定义一个函数来指示 map 对象。您可以将此函数调用为 parse_csv。

此函数使用 tf.decode_csv 方法解析 csv 文件,并声明特征和标签。特征可以声明为字典或元组。您使用字典方法,因为它更方便。代码解释

  • tf.decode_csv(value, record_defaults= RECORDS_ALL):decode_csv 方法使用 TextLineDataset 的输出来读取 csv 文件。record_defaults 指示 TensorFlow 关于列类型。
  • dict(zip(_CSV_COLUMNS, columns)):使用在此数据处理期间提取的所有列填充字典
  • features.pop(‘median_house_value’): 从特征变量中排除目标变量并创建标签变量

Dataset 需要更多元素来迭代地馈送 Tensors。事实上,您需要添加 repeat 方法以允许数据集无限期地继续馈送模型。如果您不添加该方法,模型将只迭代一次然后抛出错误,因为没有更多数据馈送到管道中。

之后,您可以通过 batch 方法控制批次大小。这意味着您告诉数据集每次迭代您想在管道中传递多少数据。如果您设置了较大的批次大小,模型将会变慢。

第 3 步)创建迭代器

现在您已准备好进行第二步:创建一个迭代器来返回数据集中的元素。

创建操作员的最简单方法是使用 make_one_shot_iterator 方法。

之后,您可以从迭代器创建特征和标签。

第 4 步)消耗数据

您可以在会话中调用该函数来消耗数据。您可以尝试将批次大小设置为 1。

请注意,它将特征以字典形式打印,并将标签以数组形式打印。

它将显示 csv 文件的第一行。您可以尝试多次运行此代码并使用不同的批次大小。

next_batch = input_fn(df_train, batch_size = 1, num_epoch = None)
with tf.Session() as sess:    
     first_batch  = sess.run(next_batch)    
     print(first_batch)

输出

({'crim': array([2.3004], dtype=float32), 'zn': array([0.], dtype=float32), 'indus': array([19.58], dtype=float32), 'nox': array([0.605], dtype=float32), 'rm': array([6.319], dtype=float32), 'age': array([96.1], dtype=float32), 'dis': array([2.1], dtype=float32), 'tax': array([403.], dtype=float32), 'ptratio': array([14.7], dtype=float32)}, array([23.8], dtype=float32))

第 4 步)定义特征列

您需要按如下方式定义数字列

X1= tf.feature_column.numeric_column('crim')
X2= tf.feature_column.numeric_column('zn')
X3= tf.feature_column.numeric_column('indus')
X4= tf.feature_column.numeric_column('nox')
X5= tf.feature_column.numeric_column('rm')
X6= tf.feature_column.numeric_column('age')
X7= tf.feature_column.numeric_column('dis')
X8= tf.feature_column.numeric_column('tax')
X9= tf.feature_column.numeric_column('ptratio')

请注意,您需要将所有变量组合到一个存储桶中

base_columns = [X1, X2, X3,X4, X5, X6,X7, X8, X9]

第 5 步)构建模型

您可以使用 estimator LinearRegressor 来训练模型。

model = tf.estimator.LinearRegressor(feature_columns=base_columns, model_dir='train3')

输出

INFO:tensorflow:Using default config. INFO:tensorflow:Using config: {'_model_dir': 'train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1820a010f0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

您需要使用 lambda 函数来允许在 input_fn 函数中编写参数。如果您不使用 lambda 函数,您将无法训练模型。

# Train the estimatormodel.train(steps =1000,    
          input_fn= lambda : input_fn(df_train,batch_size=128, num_epoch = None))

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train3/model.ckpt.
INFO:tensorflow:loss = 83729.64, step = 1
INFO:tensorflow:global_step/sec: 72.5646
INFO:tensorflow:loss = 13909.657, step = 101 (1.380 sec)
INFO:tensorflow:global_step/sec: 101.355
INFO:tensorflow:loss = 12881.449, step = 201 (0.986 sec)
INFO:tensorflow:global_step/sec: 109.293
INFO:tensorflow:loss = 12391.541, step = 301 (0.915 sec)
INFO:tensorflow:global_step/sec: 102.235
INFO:tensorflow:loss = 12050.5625, step = 401 (0.978 sec)
INFO:tensorflow:global_step/sec: 104.656
INFO:tensorflow:loss = 11766.134, step = 501 (0.956 sec)
INFO:tensorflow:global_step/sec: 106.697
INFO:tensorflow:loss = 11509.922, step = 601 (0.938 sec)
INFO:tensorflow:global_step/sec: 118.454
INFO:tensorflow:loss = 11272.889, step = 701 (0.844 sec)
INFO:tensorflow:global_step/sec: 114.947
INFO:tensorflow:loss = 11051.9795, step = 801 (0.870 sec)
INFO:tensorflow:global_step/sec: 111.484
INFO:tensorflow:loss = 10845.855, step = 901 (0.897 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train3/model.ckpt.
INFO:tensorflow:Loss for final step: 5925.9873.
Out[8]:
<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x18225eb8d0>

您可以使用以下代码评估模型在测试集上的拟合度

results = model.evaluate(steps =None,input_fn=lambda: input_fn(df_eval, batch_size =128, num_epoch = 1))
for key in results:   
print("   {}, was: {}".format(key, results[key]))

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-13-02:06:02
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-13-02:06:02
INFO:tensorflow:Saving dict for global step 1000: average_loss = 32.15896, global_step = 1000, loss = 3215.896
   average_loss, was: 32.158958435058594
   loss, was: 3215.89599609375
   global_step, was: 1000

最后一步是根据值预测值,即特征的矩阵。您可以编写一个包含您想要预测的值的字典。您的模型有 9 个特征,所以您需要为每个特征提供一个值。模型将为每个特征提供一个预测。

在下面的代码中,您编写了 df_predict csv 文件中包含的每个特征的值。

您需要编写一个新的 input_fn 函数,因为数据集中没有标签。您可以使用 Dataset 的 from_tensor API。

prediction_input = {				
          'crim': [0.03359,5.09017,0.12650,0.05515,8.15174,0.24522],				
          'zn': [75.0,0.0,25.0,33.0,0.0,0.0],				
          'indus': [2.95,18.10,5.13,2.18,18.10,9.90],				
          'nox': [0.428,0.713,0.453,0.472,0.700,0.544],				
          'rm': [7.024,6.297,6.762,7.236,5.390,5.782],				
          'age': [15.8,91.8,43.4,41.1,98.9,71.7],				
          'dis': [5.4011,2.3682,7.9809,4.0220,1.7281,4.0317],				
          'tax': [252,666,284,222,666,304],				
          'ptratio': [18.3,20.2,19.7,18.4,20.2,18.4]
     }
     def test_input_fn():    
     dataset = tf.data.Dataset.from_tensors(prediction_input)    
     return dataset
     
     # Predict all our prediction_inputpred_results = model.predict(input_fn=test_input_fn)

最后,您将打印预测结果。

for pred in enumerate(pred_results):    
print(pred)

输出

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
(0, {'predictions': array([32.297546], dtype=float32)})
(1, {'predictions': array([18.96125], dtype=float32)})
(2, {'predictions': array([27.270979], dtype=float32)})
(3, {'predictions': array([29.299236], dtype=float32)})
(4, {'predictions': array([16.436684], dtype=float32)})
(5, {'predictions': array([21.460876], dtype=float32)})

INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train3/model.ckpt-5000 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. (0, {'predictions': array([35.60663], dtype=float32)}) (1, {'predictions': array([22.298521], dtype=float32)}) (2, {'predictions': array([25.74533], dtype=float32)}) (3, {'predictions': array([35.126694], dtype=float32)}) (4, {'predictions': array([17.94416], dtype=float32)}) (5, {'predictions': array([22.606628], dtype=float32)})

摘要

要训练模型,您需要

  • 定义特征:自变量:X
  • 定义标签:因变量:y
  • 构建训练/测试集
  • 定义初始权重
  • 定义损失函数:MSE
  • 优化模型:梯度下降
  • 定义
    • 学习率
    • Epoch 数量
    • 批次大小

在本教程中,您学习了如何为线性回归 TensorFlow 估计器使用高级 API。您需要定义

  1. 特征列。如果是连续的:tf.feature_column.numeric_column()。您可以使用 Python 列表推导式填充列表
  2. 估计器:tf.estimator.LinearRegressor(feature_columns, model_dir)
  3. 用于导入数据、批次大小和 epoch 的函数:input_fn()

之后,您就可以使用 train()、evaluate() 和 predict() 来训练、评估和预测了。