TensorFlow 线性回归教程 [示例]
什么是线性回归?
线性回归 是统计学中一种用于对两个变量之间的关系进行建模的方法。这种建模是在标量响应和一个或多个解释变量之间进行的。与一个解释变量的关系称为简单线性回归,而对于多个解释变量,则称为多元线性回归。
TensorFlow 提供了完全控制计算的工具。这是通过低级 API 实现的。除此之外,TensorFlow 还配备了大量 API 来执行许多 机器学习 算法。这是高级 API。TensorFlow 称之为估算器
- 低级 API:从头开始构建架构、优化模型。对于初学者来说,这很复杂
- 高级API:定义算法。这很容易。TensorFlow 提供了一个名为的工具箱 估计 构建、训练、评估和做出预测。
在本教程中,您将使用 仅限估算器。计算速度更快,更容易实现。本教程的第一部分讲解了如何使用梯度下降优化器在 TensorFlow 中训练线性回归。在第二部分中,您将使用波士顿数据集通过 TensorFlow 估算器预测房价。
如何训练线性回归模型
在我们开始训练模型之前,让我们先看看什么是线性回归。
假设你有两个变量,x 和 y,你的任务是预测已知值的值。如果你绘制数据,你会看到独立变量 x 和因变量 y 之间存在正相关关系。
您可能会发现,如果 x=1,y 将大致等于 6,而如果 x=2,y 将在 8.5 左右。
这不是一个非常准确的方法,而且容易出错,尤其是对于包含数十万个点的数据集。
线性回归用方程来评估。变量 y 由一个或多个协变量解释。在您的示例中,只有一个因变量。如果您必须写出此方程,则它将是:
附:
是偏差。即如果 x=0,y=
是与 x 相关的权重
是模型的残差或误差。它包括模型无法从数据中学习到的内容
假设你拟合了模型,并找到了以下解决方案:
= 3.8
= 2.78
您可以将这些数字代入等式中,结果变为:
y= 3.8 + 2.78x
现在,您有了更好的方法来查找 y 的值。也就是说,您可以将 x 替换为您想要预测 y 的任何值。在下图中,我们用数据集中的所有值替换方程中的 x 并绘制结果。
红线表示拟合值,即每个 x 值的 y 值。您无需查看 x 值即可预测 y,每个 x 都有属于红线的值。您还可以预测高于 2 的 x 值!
如果要将线性回归扩展到更多协变量,可以通过向模型添加更多变量来实现。传统分析与线性回归之间的区别在于,线性回归研究 y 对每个变量 x 独立做出的反应。
让我们看一个例子。假设你想预测一家冰淇淋店的销售额。数据集包含不同的信息,例如天气(即下雨、晴天、多云)、客户信息(即工资、性别、婚姻状况)。
传统分析会尝试通过计算每个变量的平均值来预测销售额,并尝试估算不同情景下的销售额。这会导致预测不准确,并将分析限制在所选情景中。
如果使用线性回归,则可以写出以下方程:
该算法将找到权重的最佳解决方案;这意味着它将尝试最小化成本(拟合线和数据点之间的差异)。
该算法是如何工作的
算法将为每个 和
并替换 x 的值以获取 y 的预测值。如果数据集有 100 个观测值,则算法会计算 100 个预测值。
我们可以计算误差,记为 模型的误差,即预测值与真实值之间的差异。正误差表示模型低估了 y 的预测,负误差表示模型高估了 y 的预测。
您的目标是最小化误差的平方。该算法计算平方误差的平均值。此步骤称为最小化误差。对于线性回归, 均方误差,也称为 MSE。从数学上讲,它是:
地点:
那么权重
指预测值
- y 是实际值
- m 是观测值的数量
需要注意的是 意味着它使用矩阵的转置。
是平均值的数学符号。
目标是找到最好的 最小化 MSE
如果平均误差很大,则意味着模型表现不佳,权重选择不正确。要纠正权重,需要使用优化器。传统的优化器称为 梯度下降.
梯度下降采用导数来减少或增加权重。如果导数为正,则减少权重。如果导数为负,则增加权重。模型将更新权重并重新计算误差。重复此过程,直到误差不再变化。每个过程称为 迭代。另外,梯度还乘以一个学习率,表示学习的速度。
如果学习率太小,算法收敛需要很长时间(即需要大量迭代)。如果学习率太高,算法可能永远不会收敛。
从上图可以看出,模型重复了大约20次这个过程,才找到一个稳定的权重值,从而达到最低的误差。
需要注意的是,误差不等于零,而是稳定在 5 左右。这意味着,该模型的典型误差为 5。如果要减少错误,则需要向模型添加更多信息,例如更多变量或使用不同的估计量。
你还记得第一个等式
最终权重分别为 3.8 和 2.78。下面的视频向您展示了梯度下降如何优化损失函数来找到这些权重
如何使用 TensorFlow 训练线性回归
现在您对幕后发生的事情有了更好的了解,您可以使用 TensorFlow 提供的估算器 API 来训练您的第一个线性回归。
您将使用波士顿数据集,其中包括以下变量
犯罪 | 城镇人均犯罪率 |
---|---|
zn | 面积超过 25,000 平方英尺的住宅用地比例 |
梧桐 | 每个城镇非零售商业用地面积比例。 |
氮氧化物 | 一氧化氮浓度 |
rm | 每套住房的平均房间数 |
年龄 | 1940 年之前建造的自住房比例 |
DIS | 到波士顿五个就业中心的加权距离 |
税务 | 每 10,000 美元全值房产税率 |
比例 | 各城镇师生比例 |
医疗病毒 | 自住房屋的中位价值(千美元) |
您将创建三个不同的数据集:
数据集 | 目标 | 塑造 |
---|---|---|
培训 | 训练模型并获取权重 | 400,10 |
评价 | 评估模型在未知数据上的表现 | 100,10 |
预测 | 使用模型根据新数据预测房屋价值 | 6,10 |
目标是利用数据集的特征来预测房屋的价值。
在本教程的第二部分中,您将学习如何使用 TensorFlow 通过三种不同方式导入数据:
- 熊猫
- 通过 脾气暴躁的
- 仅限 TF
请注意,所有选项 提供相同的结果。
您将学习如何使用高级 API 来构建、训练和评估 TensorFlow 线性回归模型。如果您使用低级 API,则必须手动定义:
- 损失函数
- 优化:梯度下降
- 矩阵乘法
- 图和张量
对于初学者来说,这是比较繁琐和复杂的。
熊猫
您需要导入必要的库来训练模型。
import pandas as pd from sklearn import datasets import tensorflow as tf import itertools
步骤1) 使用导入数据 熊猫.
您定义列名并将其存储在 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 回归任务:
- 回归器
- DNN回归器
- 线性回归器
- DNNLinea组合回归器
- 分类
- DNN分类器
- 线性分类器
- DNNLinea组合分类器
在本教程中,您将使用线性回归器。要访问此功能,您需要使用 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 定义了你希望模型查看数据的次数。最好将此步骤设置为 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 来评估模型。训练估计器需要一个 input_fn 和一些步骤。您可以使用上面创建的函数来输入模型。然后,您指示模型迭代 1000 次。请注意,您没有指定 epoch 的数量,而是让模型迭代 1000 次。如果您将 epoch 的数量设置为 1,则模型将迭代 4 次:训练集中有 400 条记录,批处理大小为 128
- 128行
- 128行
- 128行
- 16行
因此,将 epoch 数设置为无并定义迭代次数更加容易,如下面的 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 美元。该模型的典型误差为 3 美元。
步骤6) 做出预测
最后,您可以使用估算器 TensorFlow 预测来估算 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”)。值
test_set_n = pd.read_csv(“E:/boston_test.csv”).值
prediction_set_n = pd.read_csv(“E:/boston_predict.csv”)。值
步骤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 estimapor 将数据输入模型,然后训练模型。请注意,我们之前定义了 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}
最后,你可以计算预测。它应该与熊猫类似。
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 笔记本,您需要重新启动并清理内核才能运行此会话。
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 函数
该功能可分为三部分:
- 导入数据
- 创建迭代器
- 使用数据
以下是定义该函数的总体代码。代码将在后面解释
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 文件,数据集方法一次读取一行。要构建数据集,您需要使用对象 TextLine数据集。您的数据集有一个标题,因此您需要使用 skip(1) 跳过第一行。此时,您只读取数据并在管道中排除标题。要为模型提供数据,您需要将特征与标签分开。对数据应用任何转换所使用的方法是 map。
此方法调用您将创建的函数来指示如何转换数据。简而言之,您需要在 TextLine数据集对象,排除标题并应用由函数指示的转换。代码解释
- tf.数据。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使用 TextLine用于读取 csv 文件的数据集。record_defaults 指示 TensorFlow 有关列的类型。
- dict(zip(_CSV_COLUMNS, columns)):用此数据处理过程中提取的所有列填充字典
- features.pop(‘median_house_value’):从特征变量中排除目标变量,并创建标签变量
数据集需要更多元素来迭代地向张量提供数据。实际上,您需要添加 repeat 方法,以允许数据集无限期地继续向模型提供数据。如果您不添加该方法,模型将只迭代一次,然后抛出错误,因为管道中没有更多数据提供。
之后,您可以使用批处理方法控制批处理大小。这意味着您告诉数据集每次迭代要在管道中传递多少数据。如果设置较大的批处理大小,模型就会变慢。
步骤 3)创建迭代器
现在您已准备好进行第二步:创建一个迭代器来返回数据集中的元素。
创建操作符的最简单方法是使用方法 make_one_shot_iterator。
之后,您可以从迭代器创建特征和标签。
步骤 4)使用数据
您可以检查 input_fn 函数发生了什么。您需要在会话中调用该函数来使用数据。您尝试将批处理大小设置为 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) 建立模型
您可以使用估计器 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 函数来允许在函数 inpu_fn 中写入参数。如果您不使用 拉姆达函数,则无法训练模型。
# 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 函数,因为数据集中没有标签。您可以使用数据集中的 API from_tensor。
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
- 优化模型:梯度下降
- 定义:
- 学习率
- 历元数
- 批量大小
在本教程中,您学习了如何使用线性回归 TensorFlow 估算器的高级 API。您需要定义:
- 特征列。如果是连续的:tf.feature_column.numeric_column()。你可以使用 python 列表推导填充列表
- 估计器:tf.estimator.LinearRegressor(feature_columns, model_dir)
- 导入数据、批次大小和时期的函数:input_fn()
之后,您就可以使用 train()、evaluate() 和 predict() 进行训练、评估和预测了。