精通 TensorFlow 1.x:1~5(1)https://developer.aliyun.com/article/1426814
下一章讨论的 Keras 库提供了将 Keras 模型转换为 Estimators 的便捷函数:keras.estimator.model_to_estimator()
。
笔记本ch-02_TF_High_Level_Libraries
中提供了 MNIST 分类示例的完整代码。 TFEstimator MNIST 示例的输出如下:
INFO:tensorflow:Using default config. WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmprvcqgu07 INFO:tensorflow:Using config: {'_save_checkpoints_steps': None, '_task_type': 'worker', '_save_checkpoints_secs': 600, '_service': None, '_task_id': 0, '_master': '', '_session_config': None, '_num_worker_replicas': 1, '_keep_checkpoint_max': 5, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7ff9d15f5fd0>, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_is_chief': True, '_save_summary_steps': 100, '_model_dir': '/tmp/tmprvcqgu07', '_num_ps_replicas': 0, '_tf_random_seed': None} INFO:tensorflow:Create CheckpointSaverHook. INFO:tensorflow:Saving checkpoints for 1 into /tmp/tmprvcqgu07/model.ckpt. INFO:tensorflow:loss = 2.4365, step = 1 INFO:tensorflow:global_step/sec: 597.996 INFO:tensorflow:loss = 1.47152, step = 101 (0.168 sec) INFO:tensorflow:global_step/sec: 553.29 INFO:tensorflow:loss = 0.728581, step = 201 (0.182 sec) INFO:tensorflow:global_step/sec: 519.498 INFO:tensorflow:loss = 0.89795, step = 301 (0.193 sec) INFO:tensorflow:global_step/sec: 503.414 INFO:tensorflow:loss = 0.743328, step = 401 (0.202 sec) INFO:tensorflow:global_step/sec: 539.251 INFO:tensorflow:loss = 0.413222, step = 501 (0.181 sec) INFO:tensorflow:global_step/sec: 572.327 INFO:tensorflow:loss = 0.416304, step = 601 (0.174 sec) INFO:tensorflow:global_step/sec: 543.99 INFO:tensorflow:loss = 0.459793, step = 701 (0.184 sec) INFO:tensorflow:global_step/sec: 687.748 INFO:tensorflow:loss = 0.501756, step = 801 (0.146 sec) INFO:tensorflow:global_step/sec: 654.217 INFO:tensorflow:loss = 0.666772, step = 901 (0.153 sec) INFO:tensorflow:Saving checkpoints for 1000 into /tmp/tmprvcqgu07/model.ckpt. INFO:tensorflow:Loss for final step: 0.426257. INFO:tensorflow:Starting evaluation at 2017-12-15-02:27:45 INFO:tensorflow:Restoring parameters from /tmp/tmprvcqgu07/model.ckpt-1000 INFO:tensorflow:Finished evaluation at 2017-12-15-02:27:45 INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8856, global_step = 1000, loss = 0.40996 {'accuracy': 0.88559997, 'global_step': 1000, 'loss': 0.40995964}
您将在第 5 章中看到如何使用核心 TensorFlow 创建此类模型。
TFSlim
TFSlim 是一个基于 TensorFlow 核心构建的轻量级库,用于定义和训练模型。 TFSlim 可与其他 TensorFlow 低级和高级库(如 TFLearn)结合使用。 TFSlim 是包装中 TensorFlow 安装的一部分:tf.contrib.slim
。运行以下命令以检查 TFSlim 安装是否正常工作:
python3 -c 'import tensorflow.contrib.slim as slim; eval = slim.evaluation.evaluate_once'
TFSlim 提供了几个模块,可以独立挑选和应用,并与其他 TensorFlow 包混合使用。例如,在撰写本书时,TFSlim 有以下主要模块:
TFSlim 模块 | 模块说明 |
arg_scope |
提供将元素应用于作用域下定义的所有图节点的机制。 |
layer |
提供几种不同的层,如fully_connected ,conv2d 等等。 |
loss |
提供用于训练优化器的损失函数 |
learn |
提供训练模型的函数 |
evaluate |
提供评估函数 |
metics |
提供用于评估模型的度量函数 |
regularizers |
提供用于创建正则化方法的函数 |
variable |
提供变量创建的函数 |
net |
提供各种预制和预训练模型,如 VGG16,InceptionV3,ResNet |
TFSlim 的简单工作流程如下:
- 使用 Slim 层创建模型。
- 提供层的输入以实例化模型。
- 使用对率和标签来定义损失。
- 使用便利函数
get_total_loss()
获得全部损失。 - 创建一个优化器。
- 使用便利函数
slim.learning.create_train_op()
,total_loss
和optimizer
创建训练函数。 - 使用上一步中定义的便捷函数
slim.learning.train()
和训练函数运行训练。
笔记本ch-02_TF_High_Level_Libraries
中提供了 MNIST 分类示例的完整代码。 TFSlim MNIST 示例的输出如下:
INFO:tensorflow:Starting Session. INFO:tensorflow:Saving checkpoint to path ./slim_logs/model.ckpt INFO:tensorflow:global_step/sec: 0 INFO:tensorflow:Starting Queues. INFO:tensorflow:global step 100: loss = 2.2669 (0.010 sec/step) INFO:tensorflow:global step 200: loss = 2.2025 (0.010 sec/step) INFO:tensorflow:global step 300: loss = 2.1257 (0.010 sec/step) INFO:tensorflow:global step 400: loss = 2.0419 (0.009 sec/step) INFO:tensorflow:global step 500: loss = 1.9532 (0.009 sec/step) INFO:tensorflow:global step 600: loss = 1.8733 (0.010 sec/step) INFO:tensorflow:global step 700: loss = 1.8002 (0.010 sec/step) INFO:tensorflow:global step 800: loss = 1.7273 (0.010 sec/step) INFO:tensorflow:global step 900: loss = 1.6688 (0.010 sec/step) INFO:tensorflow:global step 1000: loss = 1.6132 (0.010 sec/step) INFO:tensorflow:Stopping Training. INFO:tensorflow:Finished training! Saving model to disk. final loss=1.6131552457809448
从输出中可以看出,便捷函数slim.learning.train()
将训练输出保存在指定日志目录中的检查点文件中。如果重新开始训练,它将首先检查检查点是否存在,并且默认情况下将从检查点恢复训练。
在撰写本文时,TFSlim 的文档页面在此链接中被发现为空。 但是,可以在此链接的源代码中找到一些文档。
我们将使用 TFSlim 来学习如何在后面的章节中使用预训练的模型,如 VGG16 和 InceptionV3。
TFLearn
TFLearn 是 Python 中的模块化库,它构建在核心 TensorFlow 之上。
TFLearn 与 TensorFlow Learn 包不同,后者也称为 TFLearn(TF 和 Learn 之间有一个空格)。TFLearn 可从此链接获得,源代码可在 GitHub 上的此链接获得。
可以使用以下命令在 Python 3 中安装 TFLearn:
pip3 install tflearn
要在其他环境或源中安装 TFLearn,请参阅此链接。
TFLearn 中的简单工作流程如下:
- 首先创建一个输入层。
- 传递输入对象以创建更多层。
- 添加输出层。
- 使用估计器层(例如
regression
)创建网络。 - 从上一步中创建的网络创建模型。
- 使用
model.fit()
方法训练模型。 - 使用训练的模型进行预测或评估。
创建 TFLearn 层
让我们学习如何在 TFLearn 中创建神经网络模型的层:
- 首先创建一个输入层:
input_layer = tflearn.input_data(shape=[None,num_inputs]
- 传递输入对象以创建更多层:
layer1 = tflearn.fully_connected(input_layer,10, activation='relu') layer2 = tflearn.fully_connected(layer1,10, activation='relu')
- 添加输出层:
output = tflearn.fully_connected(layer2,n_classes, activation='softmax')
- 从估计器层创建最终网络,例如
regression
:
net = tflearn.regression(output, optimizer='adam', metric=tflearn.metrics.Accuracy(), loss='categorical_crossentropy' )
TFLearn 为以下子部分中描述的层提供了几个类。
TFLearn 核心层
TFLearn 在tflearn.layers.core
模块中提供以下层:
层类 | 描述 |
input_data |
该层用于指定神经网络的输入层。 |
fully_connected |
该层用于指定一个层,其中所有神经元都连接到前一层中的所有神经元。 |
dropout |
该层用于指定丢弃正则化。输入元素由1/keep_prob 缩放,同时保持预期的总和不变。 |
custom_layer |
此层用于指定要应用于输入的自定义函数。此类包装我们的自定义函数并将该函数显示为层。 |
reshape |
此层将输入重新整形为指定形状的输出。 |
flatten |
该层将输入张量转换为 2D 张量。 |
activation |
该层将指定的激活函数应用于输入张量。 |
single_unit |
该层将线性函数应用于输入。 |
highway |
该层实现了完全连接的公路函数。 |
one_hot_encoding |
此层将数字标签转换为二元向量单热编码表示。 |
time_distributed |
该层将指定的函数应用于输入张量的每个时间步长。 |
multi_target_data |
此层创建并连接多个占位符,特别是在层使用来自多个源的目标时使用。 |
TFLearn 卷积层
TFLearn 在tflearn.layers.conv
模块中提供以下层:
层类 | 描述 |
conv_1d |
该层将 1D 卷积应用于输入数据 |
conv_2d |
该层将 2D 卷积应用于输入数据 |
conv_3d |
该层将 3D 卷积应用于输入数据 |
conv_2d_transpose |
该层将conv2_d 的转置应用于输入数据 |
conv_3d_transpose |
该层将conv3_d 的转置应用于输入数据 |
atrous_conv_2d |
该层计算二维动态卷积 |
grouped_conv_2d |
该层计算深度 2D 卷积 |
max_pool_1d |
该层计算 1D 最大池化 |
max_pool_2d |
该层计算 2D 最大池化 |
avg_pool_1d |
该层计算 1D 平均池化 |
avg_pool_2d |
该层计算 2D 平均池化 |
upsample_2d |
该层应用行和列 2D 重复操作 |
upscore_layer |
该层实现了这个页面中规定的最高分。 |
global_max_pool |
该层实现全局最大池化操作 |
global_avg_pool |
该层实现全局平均池化操作 |
residual_block |
该层实现残差块以创建深度残差网络 |
residual_bottleneck |
该层实现深度残差网络的残差瓶颈块 |
resnext_block |
该层实现 ResNext 块 |
TFLearn 循环层
TFLearn 在tflearn.layers.recurrent
模块中提供以下层:
层类 | 描述 |
simple_rnn |
该层实现了简单的循环神经网络模型 |
bidirectional_rnn |
该层实现双向 RNN 模型 |
lstm |
该层实现了 LSTM 模型 |
gru |
该层实现 GRU 模型 |
TFLearn 正则化层
TFLearn 在tflearn.layers.normalization
模块中提供以下层:
层类 | 描述 |
batch_normalization |
该层正则化每个批次的先前层激活的输出 |
local_response_normalization |
该层实现 LR 正则化 |
l2_normalization |
该层将 L2 归一化应用于输入张量 |
TFLearn 嵌入层
TFLearn 在tflearn.layers.embedding_ops
模块中只提供一层:
层类 | 描述 |
embedding |
该层实现整数 ID 或浮点序列的嵌入函数 |
TFLearn 合并层
TFLearn 在tflearn.layers.merge_ops
模块中提供以下层:
层类 | 描述 |
merge_outputs |
该层将张量列表合并为单个张量,通常用于合并相同形状的输出张量 |
merge |
该层将张量列表合并为单个张量;您可以指定需要进行合并的轴 |
TFLearn 估计层
TFLearn 在tflearn.layers.estimator
模块中只提供一层:
层类 | 描述 |
regression |
该层实现线性或逻辑回归 |
在创建回归层时,您可以指定优化器以及损失和度量函数。
TFLearn 在tflearn.optimizers
模块中提供以下优化器函数作为类:
SGD
RMSprop
Adam
Momentum
AdaGrad
Ftrl
AdaDelta
ProximalAdaGrad
Nesterov
您可以通过扩展tflearn.optimizers.Optimizer
基类来创建自定义优化器。
TFLearn 在tflearn.metrics
模块中提供以下度量函数作为类或操作:
Accuracy
或accuracy_op
Top_k
或top_k_op
R2
或r2_op
WeightedR2
或weighted_r2_op
binary_accuracy_op
您可以通过扩展tflearn.metrics.Metric
基类来创建自定义指标。
TFLearn 在tflearn.objectives
模块中提供以下损失函数,称为目标:
softymax_categorical_crossentropy
categorical_crossentropy
binary_crossentropy
weighted_crossentropy
mean_square
hinge_loss
roc_auc_score
weak_cross_entropy_2d
在指定输入,隐藏和输出层时,您可以指定要应用于输出的激活函数。 TFLearn 在tflearn.activations
模块中提供以下激活函数:
linear
tanh
sigmoid
softmax
softplus
softsign
relu
relu6
leaky_relu
prelu
elu
crelu
selu
创建 TFLearn 模型
从上一步创建的网络创建模型(创建 TFLearn 层部分的步骤 4):
model = tflearn.DNN(net)
TFLearn 模型的类型
TFLearn 提供两种不同的模型:
DNN
(深度神经网络)模型:此类允许您从通过层创建的网络创建多层感知机SequenceGenerator
模型:该类允许您创建可以生成序列的深度神经网络
训练 TFLearn 模型
创建后,使用model.fit()
方法训练模型:
model.fit(X_train, Y_train, n_epoch=n_epochs, batch_size=batch_size, show_metric=True, run_id='dense_model')
使用 TFLearn 模型
使用训练的模型预测或评估:
score = model.evaluate(X_test, Y_test) print('Test accuracy:', score[0])
笔记本ch-02_TF_High_Level_Libraries
中提供了 TFLearn MNIST 分类示例的完整代码。 TFLearn MNIST 示例的输出如下:
Training Step: 5499 | total loss: 0.42119 | time: 1.817s | Adam | epoch: 010 | loss: 0.42119 - acc: 0.8860 -- iter: 54900/55000 Training Step: 5500 | total loss: 0.40881 | time: 1.820s | Adam | epoch: 010 | loss: 0.40881 - acc: 0.8854 -- iter: 55000/55000 -- Test accuracy: 0.9029
PrettyTensor
PrettyTensor 在 TensorFlow 上提供了一个薄包装器。 PrettyTensor 提供的对象支持可链接的语法来定义神经网络。例如,可以通过链接层来创建模型,如以下代码所示:
model = (X. flatten(). fully_connected(10). softmax_classifier(n_classes, labels=Y))
可以使用以下命令在 Python 3 中安装 PrettyTensor:
pip3 install prettytensor
PrettyTensor 以名为apply()
的方法提供了一个非常轻量级和可扩展的接口。可以使用.apply(function, arguments)
方法将任何附加函数链接到 PrettyTensor 对象。 PrettyTensor 将调用function
并提供当前张量作为function
的第一个参数。
用户创建的函数可以使用@prettytensor.register
装饰器来装饰。详细信息在这里。
在 PrettyTensor 中定义和训练模型的工作流程如下:
- 获取数据。
- 定义超参数和参数。
- 定义输入和输出。
- 定义模型。
- 定义评估器,优化器和训练器函数。
- 创建运行器对象。
- 在 TensorFlow 会话中,使用
runner.train_model()
方法训练模型。 - 在同一会话中,使用
runner.evaluate_model()
方法评估模型。
笔记本ch-02_TF_High_Level_Libraries
中提供了 PrettyTensor MNIST 分类示例的完整代码。 PrettyTensor MNIST 示例的输出如下:
[1] [2.5561881] [600] [0.3553167] Accuracy after 1 epochs 0.8799999952316284 [601] [0.47775066] [1200] [0.34739292] Accuracy after 2 epochs 0.8999999761581421 [1201] [0.19110668] [1800] [0.17418651] Accuracy after 3 epochs 0.8999999761581421 [1801] [0.27229539] [2400] [0.34908807] Accuracy after 4 epochs 0.8700000047683716 [2401] [0.40000191] [3000] [0.30816519] Accuracy after 5 epochs 0.8999999761581421 [3001] [0.29905257] [3600] [0.41590339] Accuracy after 6 epochs 0.8899999856948853 [3601] [0.32594997] [4200] [0.36930788] Accuracy after 7 epochs 0.8899999856948853 [4201] [0.26780865] [4800] [0.2911002] Accuracy after 8 epochs 0.8899999856948853 [4801] [0.36304188] [5400] [0.39880857] Accuracy after 9 epochs 0.8999999761581421 [5401] [0.1339224] [6000] [0.14993289] Accuracy after 10 epochs 0.8899999856948853
Sonnet
Sonnet 是一个用 Python 编写的面向对象的库。它是由 DeepMind 在 2017 年发布的。Sonnet 打算从对象中清晰地分离构建计算图的以下两个方面:
- 称为模块的对象的配置
- 对象与计算图的连接
可以使用以下命令在 Python3 中安装 Sonnet:
pip3 install dm-sonnet
模块被定义为抽象类sonnet.AbstractModule
的子类。在编写本书时,Sonnet 中提供了以下模块:
基本模块 | AddBias ,BatchApply ,BatchFlatten ,BatchReshape ,FlattenTrailingDimensions ,Linear ,MergeDims ,SelectInput ,SliceByDim ,TileByDim 和TrainableVariable |
循环模块 | DeepRNN ,ModelRNN ,VanillaRNN ,BatchNormLSTM ,GRU 和LSTM |
Recurrent + ConvNet 模块 | Conv1DLSTM 和Conv2DLSTM |
ConvNet 模块 | Conv1D ,Conv2D ,Conv3D ,Conv1DTranspose ,Conv2DTranspose ,Conv3DTranspose ,DepthWiseConv2D ,InPlaneConv2D 和SeparableConv2D |
ResidualNets | Residual ,ResidualCore 和SkipConnectionCore |
其他 | BatchNorm ,LayerNorm ,clip_gradient 和scale_gradient |
我们可以通过创建sonnet.AbstractModule
的子类来定义我们自己的新模块。从函数创建模块的另一种非推荐方法是通过传递要包装为模块的函数来创建sonnet.Module
类的对象。
在 Sonnet 库中构建模型的工作流程如下:
- 为从
sonnet.AbstractModule
继承的数据集和网络架构创建类。在我们的示例中,我们创建了一个 MNIST 类和一个 MLP 类。 - 定义参数和超参数。
- 从上一步中定义的数据集类定义测试和训练数据集。
- 使用定义的网络类定义模型。例如,在我们的案例中,
model = MLP([20, n_classes])
创建了一个 MLP 网络,其中包含两层 20 和每个神经元n_classes
的数量。 - 使用模型为训练和测试集定义
y_hat
占位符。 - 定义训练和测试集的损失占位符。
- 使用训练损失占位符定义优化器。
- 在 TensorFlow 会话中执行所需数量的周期的损失函数以优化参数。
笔记本电脑ch-02_TF_High_Level_Libraries
中提供了 Sonnet MNIST 分类示例的完整代码。 每个类中的__init__
方法初始化类和相关的超类。_build
方法在调用类时创建并返回数据集或模型对象。 Sonnet MNIST 示例的输出如下:
Epoch : 0 Training Loss : 236.79913330078125 Epoch : 1 Training Loss : 227.3693084716797 Epoch : 2 Training Loss : 221.96337890625 Epoch : 3 Training Loss : 220.99142456054688 Epoch : 4 Training Loss : 215.5921173095703 Epoch : 5 Training Loss : 213.88958740234375 Epoch : 6 Training Loss : 203.7091064453125 Epoch : 7 Training Loss : 204.57427978515625 Epoch : 8 Training Loss : 196.17218017578125 Epoch : 9 Training Loss : 192.3954315185547 Test loss : 192.8847198486328
由于神经网络中计算的随机性,您的输出可能会有所不同。这包括我们对 Sonnet 模块的概述。
总结
在本章中,我们浏览了一些构建在 TensorFlow 之上的高级库。我们了解了 TFEstimator,TFSlim,TFLearn,PrettyTensor 和 Sonnet。我们为所有五个实现了 MNIST 分类示例。如果您无法理解模型的细节,请不要担心,因为为 MNIST 示例构建的模型将在以下章节中再次介绍。
我们总结了下表中提供的库和框架,如下表所示:
高级库 | 文档链接 | 源代码链接 | PIP3 安装包 |
TFEstimator | https://www.tensorflow.org/get_started/estimator | https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python/estimator | TensorFlow 预置 |
TFSlim | https://github.com/tensorflow/tensorflow/tree/r1.4/tensorflow/contrib/slim | https://github.com/tensorflow/tensorflow/tree/r1.4/tensorflow/contrib/slim/python/slim | TensorFlow 预置 |
TFLearn | http://tflearn.org/ | https://github.com/tflearn/tflearn | tflearn |
PrettyTensor | https://github.com/google/prettytensor/tree/master/docs | https://github.com/google/prettytensor | prettytensor |
Sonnet | https://deepmind.github.io/sonnet/ | https://github.com/deepmind/sonnet | dm-sonnet |
在下一章中,我们将了解 Keras,这是用于创建和训练 TensorFlow 模型的最流行的高级库。
三、Keras 101
Keras 是一个高级库,允许使用 TensorFlow 作为后端深度学习库。 TensorFlow 团队将 TrasorFlow Core 中的 Keras 作为模块tf.keras
。除了 TensorFlow 之外,Keras 在撰写本书时还支持 Theano 和 CNTK。
以下 Keras 的指导原则使其在深度学习社区中非常受欢迎:
- 极简主义提供一致且简单的 API
- 模块化允许将各种元素表示为可插拔模块
- 将新模块添加为类和函数的可扩展性
- 用于代码和模型配置的 Python 原生
- 开箱即用的通用网络架构,支持 CNN,RNN 或两者的组合
在本书的其余部分中,我们将学习如何使用低级 TensorFlow API 和高级 Keras API 构建不同类型的深度学习和机器学习模型。
我们将在本章中介绍以下主题:
- 安装 Keras
- 在 Keras 中创建模型的工作流程
- 使用顺序和函数式 API 创建 Keras 模型
- Keras 层
- 使用顺序和函数式 API 创建和添加层
- 编译 Keras 模型
- 训练 Keras 模型
- 使用 Keras 模型进行预测
- Keras 的附加模块
- MNIST 数据集的 Keras 序列模型示例
安装 Keras
使用以下命令可以在 Python 3 中安装 Keras:
pip3 install keras
Keras 中的神经网络模型
Keras 中的神经网络模型将定义为层图。 Keras 中的模型可以使用顺序或函数式 API 创建。函数式和顺序 API 都可用于构建任何类型的模型。函数式 API 可以更轻松地构建具有多个输入,多个输出和共享层的复杂模型。
因此,根据经验,我们已经看到工程师将顺序 API 用于从简单层构建的简单模型,以及用于涉及分支和共享层的复杂模型的函数式 API。我们还观察到,使用函数式 API 构建简单模型可以更轻松地将模型扩展为具有分支和共享的复杂模型。因此,对于我们的工作,我们总是使用函数式 API。
在 Keras 中创建模型的工作流程
Keras 的简单工作流程如下:
- 创建模型
- 创建层并将其添加到模型中
- 编译模型
- 训练模型
- 使用该模型进行预测或评估
我们来看看每个步骤。
您可以使用代码包中包含的 Jupyter 笔记本ch-03_Keras_101
来遵循本章中的代码示例。 尝试修改笔记本中的代码以探索各种选项。
创建 Keras 模型
可以使用顺序 API 或函数式 API 创建 Keras 模型。以下两小节给出了以两种方式创建模型的示例 。
用于创建 Keras 模型的顺序 API
在顺序 API 中,使用以下代码创建空模型:
model = Sequential()
您现在可以将层添加到此模型中,我们将在下一节中看到。
或者,您也可以将所有层作为列表传递给构造器。例如,我们通过使用以下代码将它们传递给构造器来添加四个层:
model = Sequential([ Dense(10, input_shape=(256,)), Activation('tanh'), Dense(10), Activation('softmax') ])
用于创建 Keras 模型的函数式 API
在函数式 API 中,模型创建为Model
类的一个实例,它接受输入和输出参数。输入和输出参数分别代表一个或多个输入和输出张量。
例如,使用以下代码从函数式 API 实例化模型:
model = Model(inputs=tensor1, outputs=tensor2)
在上面的代码中,tensor1
和tensor2
是张量或对象,可以像张量一样对待,例如,Keras layer
对象。
如果有多个输入和输出张量,则可以将它们作为列表传递,如以下示例所示:
model = Model(inputs=[i1,i2,i3], outputs=[o1,o2,o3])
Keras 层
Keras 为网络架构的简单构建提供了几个内置层类。以下部分概述和描述了 Keras2 在撰写本书时提供的各种类型的层。
Keras 核心层
Keras 核心层实现基本操作,几乎用于各种网络架构。下表给出了 Keras2 提供的层的摘要和说明:
层名称 | 描述 |
Dense |
这是一个简单的完全连接的神经网络层。该层生成以下函数的输出:激活(输入 x 权重 + 偏差) ,其中激活是指传递给层的激活函数,默认为None 。 |
Activation |
该层将指定的激活函数应用于输出。该层生成以下函数的输出:激活(输入) ,其中激活是指传递给该层的激活函数。以下激活函数可用于实例化层:softmax ,elu ,selu ,softplus ,softsign ,relu ,tanh ,sigmoid ,hard_sigmoid 和linear |
Dropout |
该层以指定的丢弃率将丢弃正则化应用于输入。 |
Flatten |
该层使输入变平,即对于三维输入,它变平并产生一维输出。 |
Reshape |
此层将输入转换为指定的形状。 |
Permute |
此层按照指定的模式重新排序输入尺寸。 |
RepeatVector |
该层以给定次数重复输入。因此,如果输入是 2D 张量的形状(#samples, #feature) 并且该层被赋予n 次重复,那么输出将是 3D 张量的形状(#samples, n, #feature) 。 |
Lambda |
该层将提供的函数包装为层。因此,输入通过提供的自定义函数传递以产生输出。该层为 Keras 用户提供了最终的可扩展性,可以将自己的自定义函数添加为层。 |
ActivityRegularization |
该层将 L1 或 L2 或两种正则化的组合应用于其输入。该层应用于激活层的输出或具有激活函数的层的输出。 |
Masking |
此层在输入张量中屏蔽或跳过这些时间步长,其中输入张量中的所有值都等于作为层参数提供的屏蔽值。 |
Keras 卷积层
这些层为卷积神经网络实现了不同类型的卷积,采样和裁剪操作:
层名称 | 描述 |
Conv1D |
该层将单个空间或时间维度上的卷积应用于输入。 |
Conv2D |
该层将二维卷积应用于输入。 |
SeparableConv2D |
该层在每个输入通道上应用深度方式空间卷积,然后是逐点卷积,将所得到的输出通道混合在一起。 |
Conv2DTranspose |
该层将卷积的形状恢复为产生这些卷积的输入的形状。 |
Conv3D |
该层将三维卷积应用于输入。 |
Cropping1D |
该层沿时间维度裁剪输入数据。 |
Cropping2D |
此层沿空间维度裁剪输入数据,例如图像的宽度和高度。 |
Cropping3D |
该层沿着时空裁剪输入数据,即所有三维。 |
UpSampling1D |
该层按时间轴指定的时间重复输入数据。 |
UpSampling2D |
此层沿两个维度按指定时间重复输入数据的行和列维度。 |
UpSampling3D |
该层按三个维度的指定时间重复输入数据的三个维度。 |
ZeroPadding1D |
该层将零添加到时间维度的开头和结尾。 |
ZeroPadding2D |
此层将行和列的零添加到 2D 张量的顶部,底部,左侧或右侧。 |
ZeroPadding3D |
该层将零添加到 3D 张量的三个维度。 |
Keras 池化层
这些层为卷积神经网络实现不同的池化操作:
层名称 | 描述 |
MaxPooling1D |
该层实现一维输入数据的最大池化操作。 |
MaxPooling2D |
该层实现二维输入数据的最大池化操作。 |
MaxPooling3D |
该层实现三维输入数据的最大池化操作。 |
AveragePooling1D |
该层实现一维输入数据的平均池化操作。 |
AveragePooling2D |
该层实现二维输入数据的平均池化操作。 |
AveragePooling3D |
该层实现三维输入数据的平均吃阿虎操作。 |
GlobalMaxPooling1D |
该层实现一维输入数据的全局最大池化操作。 |
GlobalAveragePooling1D |
该层实现一维输入数据的全局平均池化操作。 |
GlobalMaxPooling2D |
该层实现二维输入数据的全局最大池化操作。 |
GlobalAveragePooling2D |
该层实现二维输入数据的全局平均池化操作。 |
Keras 本地连接层
这些层在卷积神经网络中很有用:
层名称 | 描述 |
LocallyConnected1D |
该层通过在输入的每个不同补丁上应用不同的滤波器组,将单个空间或时间维度上的卷积应用于输入,从而不共享权重。 |
LocallyConnected2D |
该层通过在输入的每个不同补丁上应用不同的滤波器组,将两个维上的卷积应用于输入,从而不共享权重。 |
Keras 循环层
这些层实现循环神经网络的不同变体:
层名称 | 描述 |
SimpleRNN |
该层实现了完全连接的循环神经网络。 |
GRU |
该层实现了门控循环单元网络。 |
LSTM |
该层实现了长期短期记忆网络。 |
Keras 嵌入层
目前,只有一个嵌入层选项可用:
层名称 | 描述 |
Embedding |
该层采用由下标组成的 2D 张量,形状为(batch_size, sequence_length) ,并产生由形状(batch_size, sequence_length, output_dim) 的密集向量组成的张量。 |
Keras 合并层
这些层合并两个或多个输入张量,并通过应用每个层表示的特定操作产生单个输出张量:
层名称 | 描述 |
Add |
该层计算输入张量的逐元素加法。 |
Multiply |
该层计算输入张量的逐元素乘法 |
Average |
该层计算输入张量的逐元素平均值。 |
Maximum |
该层计算输入张量的逐元素最大值。 |
Concatenate |
此层沿指定轴连接输入张量。 |
Dot |
该层计算两个输入张量中样本之间的点积。 |
add ,multiply ,average ,maximum ,concatenate 和dot |
这些函数表示此表中描述的各个合并层的函数接口。 |
Keras 高级激活层
这些层实现了高级激活函数,这些函数无法作为简单的底层后端函数实现。它们的操作类似于我们在核心层部分中介绍的Activation()
层:
层名称 | 描述 |
LeakyReLU |
该层计算ReLU 激活函数的泄漏版本。 |
PReLU |
该层计算参数化ReLU 激活函数。 |
ELU |
该层计算指数线性单元激活函数。 |
ThresholdedReLU |
该层计算阈值版本的ReLU 激活函数。 |
Keras 正则化层
目前,只有一个标准化层可用:
层名称 | 描述 |
BatchNormalization |
该层标准化前一层的每个批量的输出,使得该层的输出近似为具有接近零的平均值和接近 1 的标准偏差。 |
Keras 噪音层
这些层可以添加到模型中,以防止过拟合添加噪音;它们也被称为正则化层。这些层的操作方式与核心层部分中的Dropout()
和ActivityRegularizer()
层相同。
层名称 | 描述 |
GaussianNoise |
该层将附加的零中心高斯噪声应用于输入。 |
GaussianDropout |
该层将乘法的单中心高斯噪声应用于输入。 |
AlphaDropout |
该层丢弃一定百分比的输入,使得丢弃后输出的均值和方差与输入的均值和方差紧密匹配。 |
将层添加到 Keras 模型
上一节中提到的所有层都需要添加到我们之前创建的模型中。在以下部分中,我们将介绍如何使用函数式 API 和顺序 API 添加层。
用于向 Keras 模型添加层的顺序 API
在顺序 API 中,可以通过实例化前面部分中给出的某个层类型的对象来创建层。然后使用model.add()
函数将创建的层添加到模型中。作为示例,我们将创建一个模型,然后为其添加两个层:
model = Sequential() model.add(Dense(10, input_shape=(256,)) model.add(Activation('tanh')) model.add(Dense(10)) model.add(Activation('softmax'))
用于向 Keras 模型添加层的函数式 API
在函数式 API 中,首先以函数方式创建层,然后在创建模型时,输入和输出层作为张量参数提供,如我们在上一节。
这是一个例子:
- 首先,创建输入层:
input = Input(shape=(64,))
- 接下来,以函数方式从输入层创建密集层:
hidden = Dense(10)(inputs)
- 以同样的方式,以函数方式创建更多隐藏层,构建在前面的层之上:
hidden = Activation('tanh')(hidden) hidden = Dense(10)(hidden) output = Activation('tanh')(hidden)
- 最后,使用输入和输出层实例化模型对象:
model = Model(inputs=input, outputs=output)
有关创建顺序和函数式 Keras 模型的更深入细节,您可以阅读由 Antonio Gulli 和 Sujit Pal,Packt Publishing,2017 年出版的题为 Deep Learning with Keras 的书。
编译 Keras 模型
前面部分中构建的模型需要使用model.compile()
方法进行编译,然后才能用于训练和预测。compile()
方法的完整签名如下:
compile(self, optimizer, loss, metrics=None, sample_weight_mode=None)
compile
方法有三个参数:
optimizer
:您可以指定自己的函数或 Keras 提供的函数之一。此函数用于更新优化迭代中的参数。 Keras 提供以下内置优化器函数:
SGD
RMSprop
Adagrad
Adadelta
Adam
Adamax
Nadam
loss
:您可以指定自己的损失函数或使用提供的损失函数之一。优化器函数优化参数,以便最小化此损失函数的输出。 Keras 提供以下损失函数:
mean_squared_error
mean_absolute_error
mean_absolute_pecentage_error
mean_squared_logarithmic_error
squared_hinge
hinge
categorical_hinge
sparse_categorical_crossentropy
binary_crossentropy
poisson
cosine proximity
binary_accuracy
categorical_accuracy
sparse_categorical_accuracy
top_k_categorical_accuracy
sparse_top_k_categorical_accuracy
metrics
:第三个参数是训练模型时需要收集的指标列表。如果启用了详细输出,则会为每次迭代打印度量标准。指标就像损失函数;一些由 Keras 提供,能够编写您自己的度量函数。所有损失函数也可用作度量函数。
训练 Keras 模型
训练 Keras 模型就像调用model.fit()
方法一样简单。该方法的完整签名如下:
fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
我们不会详细介绍这种方法的参数; 您可以在 Keras 网站上阅读详细信息。
对于我们之前创建的示例模型,使用以下代码训练模型:
model.fit(x_data, y_labels)
使用 Keras 模型进行预测
经过训练的模型可用于使用model.predict()
方法来预测值,或用model.evaluate()
方法评估模型。
这两种方法的签名如下:
predict(self, x, batch_size=32, verbose=0)
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
Keras 的附加模块
Keras 提供了几个补充基本工作流程的附加模块(附加函数在本章开头描述)。部分模块如下:
preprocessing
模块提供了几种预处理序列,图像和文本数据的函数。datasets
模块提供了多种函数,可以快速访问几个流行的数据集,如 CIFAR10 图像,CIFAR100 图像,IMDB 电影评论,路透社新闻专线主题,MNIST 手写数字和波士顿房价。initializers
模块提供了几种设置层初始随机权重参数的函数,如Zeros
,Ones
,Constant
,RandomNormal
,RandomUniform
,TruncatedNormal
,VarianceScaling
,Orthogonal
,Identity
,lecun_normal
,lecun_uniform
,glorot_normal
,glorot_uniform
,he_normal
和he_uniform
。models
模块提供了几种恢复模型架构和权重的函数,如model_from_json
,model_from_yaml
,和load_model
。可以使用model.to_yaml()
和model.to_json()
方法保存模型架构。通过调用model.save()
方法可以保存模型权重。权重保存在 HDF5 文件中。applications
模块提供了几种预先构建和预训练的模型,例如 Xception,VGG16,VGG19,ResNet50,InceptionV3,InceptionResNetV2 和 MobileNet。我们将学习如何使用预建模型来预测我们的数据集。我们还将学习,如何使用来自略有不同的域的数据集,再训练applications
模块中的预训练模型。
这就结束了我们对 Keras 的简要介绍,这是 TensorFlow 的高级框架。我们将在本书中提供使用 Keras 构建模型的示例。
用于 MNIST 数据集的 Keras 序列模型示例
以下是构建简单多层感知机(在第 5 章中详细介绍)的一个小例子,用于对 MNIST 集中的手写数字进行分类:
import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import SGD from keras import utils import numpy as np # define some hyper parameters batch_size = 100 n_inputs = 784 n_classes = 10 n_epochs = 10 # get the data (x_train, y_train), (x_test, y_test) = mnist.load_data() # reshape the two dimensional 28 x 28 pixels # sized images into a single vector of 784 pixels x_train = x_train.reshape(60000, n_inputs) x_test = x_test.reshape(10000, n_inputs) # convert the input values to float32 x_train = x_train.astype(np.float32) x_test = x_test.astype(np.float32) # normalize the values of image vectors to fit under 1 x_train /= 255 x_test /= 255 # convert output data into one hot encoded format y_train = utils.to_categorical(y_train, n_classes) y_test = utils.to_categorical(y_test, n_classes) # build a sequential model model = Sequential() # the first layer has to specify the dimensions of the input vector model.add(Dense(units=128, activation='sigmoid', input_shape=(n_inputs,))) # add dropout layer for preventing overfitting model.add(Dropout(0.1)) model.add(Dense(units=128, activation='sigmoid')) model.add(Dropout(0.1)) # output layer can only have the neurons equal to the number of outputs model.add(Dense(units=n_classes, activation='softmax')) # print the summary of our model model.summary() # compile the model model.compile(loss='categorical_crossentropy', optimizer=SGD(), metrics=['accuracy']) # train the model model.fit(x_train, y_train, batch_size=batch_size, epochs=n_epochs) # evaluate the model and print the accuracy score scores = model.evaluate(x_test, y_test) print('\n loss:', scores[0]) print('\n accuracy:', scores[1])
我们从描述和训练 Keras 模型得到以下输出:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_7 (Dense) (None, 128) 100480 _________________________________________________________________ dropout_5 (Dropout) (None, 128) 0 _________________________________________________________________ dense_8 (Dense) (None, 128) 16512 _________________________________________________________________ dropout_6 (Dropout) (None, 128) 0 _________________________________________________________________ dense_9 (Dense) (None, 10) 1290 ================================================================= Total params: 118,282 Trainable params: 118,282 Non-trainable params: 0 _________________________________________________________________ Epoch 1/10 60000/60000 [========================] - 3s - loss: 2.3018 - acc: 0.1312 Epoch 2/10 60000/60000 [========================] - 2s - loss: 2.2395 - acc: 0.1920 Epoch 3/10 60000/60000 [========================] - 2s - loss: 2.1539 - acc: 0.2843 Epoch 4/10 60000/60000 [========================] - 2s - loss: 2.0214 - acc: 0.3856 Epoch 5/10 60000/60000 [========================] - 3s - loss: 1.8269 - acc: 0.4739 Epoch 6/10 60000/60000 [========================] - 2s - loss: 1.5973 - acc: 0.5426 Epoch 7/10 60000/60000 [========================] - 2s - loss: 1.3846 - acc: 0.6028 Epoch 8/10 60000/60000 [========================] - 3s - loss: 1.2133 - acc: 0.6502 Epoch 9/10 60000/60000 [========================] - 3s - loss: 1.0821 - acc: 0.6842 Epoch 10/10 60000/60000 [========================] - 3s - loss: 0.9799 - acc: 0.7157 loss: 0.859834249687 accuracy: 0.788
您可以看到,在 Keras 中构建和训练模型是多么容易。
您可以从他们记录完备的网站获取有关 Keras 的更多信息。
总结
在本章中,我们了解了 Keras。 Keras 是 TensorFlow 最受欢迎的高级库。我个人更喜欢将 Keras 用于我为商业制作和学术研究开发的所有模型。我们学习了使用函数式和顺序 API 在 Keras 中创建和训练模型所遵循的工作流程。我们了解了各种 Keras 层以及如何将层添加到顺序和函数式模型中。我们还学习了如何编译,训练和评估 Keras 模型。我们还看到了 Keras 提供的一些附加模块。
在本书的其余章节中,我们将介绍核心 TensorFlow 和 Keras 中的大多数示例。 在下一章中,我们将学习如何使用 TensorFlow 构建传统的机器学习模型进行分类和回归。
四、TensorFlow 中的经典机器学习
机器学习是计算机科学领域,涉及算法的研究,开发和应用,以使计算机器从数据中学习。计算机学习的模型用于进行预测和预测。机器学习研究人员和工程师通过构建模型然后使用这些模型进行预测来实现这一目标。现在众所周知,机器学习已成功地应用于各种领域,如自然语言理解,视频处理,图像识别,语音和视觉。
我们来谈谈模型。所有机器学习问题都以一种或另一种形式抽象为以下等式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wyTw8KUu-1681566326305)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/3d553b03-80b7-4120-9df0-a607ad64af36.png)]
这里,y
是输出或目标,x
是输入或特征。如果x
是一组特征,我们也将其称为特征向量,并用X
表示。当我们说模型时,我们的意思是找到将特征映射到目标的函数f
。因此,一旦我们找到f
,我们就可以使用x
的新值来预测y
的值。
机器学习的核心是找到可用于从x
的值预测y
的函数f
。正如您可能从高中数学周期回忆的那样,该线的等式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a6E2bnuo-1681566326306)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/ba408e0e-2d86-4499-bc6d-a8fbeaf344d7.png)]
我们可以重写前面的简单等式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQ2bS5Xm-1681566326306)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/fc46f48c-ee0d-43bd-b8bf-998f54b785c6.png)]
这里,W
称为权重,b
称为偏差。不要担心现在的权重和偏置,我们稍后会介绍它们。现在,您可以将W
视为等效于m
和b
等效于c
。因此,现在机器学习问题可以说是从X
的当前值找到W
和b
的问题,这样该方程可用于预测y
的值。
回归分析或回归建模是指用于估计变量之间关系的方法和技术。输入到回归模型的变量称为独立变量或预测变量或特征,而回归模型的输出变量称为因变量或目标。回归模型定义如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W5h3zBa3-1681566326306)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/5fc17d1b-7188-4209-bce2-77f97aa72877.png)]
其中Y
是目标变量,X
是特征向量,β
是参数向量
通常,我们使用一种非常简单的回归形式,称为简单线性回归来估计参数 β。
在机器学习问题中,我们必须从给定数据中学习模型参数β0
和β1
,以便我们有一个估计模型,从X
的未来值预测Y
的值。我们对偏置使用β1
,对权重项使用β0
,分别用w
和b
代表它们。
因此模型如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qsQe0BCO-1681566326306)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/ff368a23-744e-4bc3-9c9a-82686936c8a1.png)]
分类是机器学习中的经典问题之一。正在考虑的数据可以属于一个或其他类别,例如,如果提供的图像是数据,则它们可以是猫或狗的图片。因此,在这种情况下,类别是猫和狗。分类是指识别或识别所考虑的数据或对象的标签或类别。分类属于监督机器学习的范畴。在分类问题中,提供具有特征或输入及其相应输出或标签的训练数据集。使用该训练数据集,训练模型;换句话说,计算模型的参数。然后将训练的模型用于新数据以找到其正确的标签。
分类问题可以有两种类型:两类或多类。两类意味着数据被分类为两个不同且不连续的标签,例如,患者患有癌症或患者没有癌症,图像是猫或狗。多类意味着数据将被分类到多个类别中,例如,电子邮件分类问题会将电子邮件分成社交媒体电子邮件,与工作相关的电子邮件,个人电子邮件,与家人相关的电子邮件,垃圾邮件,购物优惠电子邮件等等。 。另一个例子是数字图片的例子;每张图片可以标记在 0 到 9 之间,具体取决于图片所代表的数字。在本章中,我们将看到两种分类的示例。
在本章中,我们将进一步扩展以下主题:
- 回归
- 简单的线性回归
- 多元回归
- 正则化回归
- LASSO 正则化
- 岭正则化
- ElasticNet 正则化
- 分类
- 使用逻辑回归的分类
- 二分类
- 多类分类
简单的线性回归
您可能使用过其他机器学习库;现在让我们练习使用 TensorFlow 学习简单的线性回归模型。在继续讨论特定于域的示例之前,我们将首先使用生成的数据集解释这些概念。
我们将使用生成的数据集,以便来自所有不同域的读者可以学习而不会被示例的特定域的细节所淹没。
您可以按照 Jupyter 笔记本中的代码ch-04a_Regression
。
数据准备
要生成数据集,我们使用sklearn
库的datasets
模块中的make_regression
函数:
from sklearn import datasets as skds X, y = skds.make_regression(n_samples=200, n_features=1, n_informative=1, n_targets=1, noise = 20.0)
这将生成一个回归数据集,其中包含一个特征的 200 个样本值和每个特征的一个目标,并添加了一些噪声。因为我们只生成一个目标,所以该函数使用一维 NumPy 数组生成y
;因此,我们重塑y
有两个维度:
if (y.ndim == 1): y = y.reshape(len(y),1)
我们使用以下代码绘制生成的数据集以查看数据:
import matplotlib.pyplot as plt plt.figure(figsize=(14,8)) plt.plot(X,y,'b.') plt.title('Original Dataset') plt.show()
我们得到以下绘图。由于生成的数据是随机的,您可能会得到不同的绘图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vcgMegEv-1681566326307)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/9dd24ca6-c0a6-427a-bc83-e12c3480d5fa.png)]
现在让我们将数据分为训练集和测试集:
X_train, X_test, y_train, y_test = skms.train_test_split(X, y, test_size=.4, random_state=123)
构建一个简单的回归模型
要在 TensorFlow 中构建和训练回归模型,通常采取以下步骤:
- 定义输入,参数和其他变量。
- 定义模型。
- 定义损失函数。
- 定义优化器函数。
- 训练模型进行多次迭代,称为周期。
定义输入,参数和其他变量
在我们使用 TensorFlow 构建和训练回归模型之前,让我们定义一些重要的变量和操作。我们从X_train
和y_train
中找出输出和输入变量的数量,然后使用这些数字来定义x
(x_tensor
),y
(y_tensor
),权重(w
)和偏置(b
):
num_outputs = y_train.shape[1] num_inputs = X_train.shape[1] x_tensor = tf.placeholder(dtype=tf.float32, shape=[None, num_inputs], name="x") y_tensor = tf.placeholder(dtype=tf.float32, shape=[None, num_outputs], name="y") w = tf.Variable(tf.zeros([num_inputs,num_outputs]), dtype=tf.float32, name="w") b = tf.Variable(tf.zeros([num_outputs]), dtype=tf.float32, name="b")
x_tensor
被定义为具有可变行和num_inputs
列的形状,并且在我们的示例中列数仅为 1y_tensor
定义为具有可变行和num_outputs
列的形状,列数在我们的示例中只有一个w
被定义为维度num_inputs
xnum_outputs
的变量,在我们的例子中是1 x 1
b
被定义为维度num_outputs
的变量,在我们的例子中是一个
定义模型
接下来,我们将模型定义为x_tensor × w + b
:
model = tf.matmul(x_tensor, w) + b
定义损失函数
接下来,我们使用均方误差(MSE)定义损失函数。 MSE 定义如下:
有关 MSE 的更多详细信息,请访问此链接
y
的实际值和估计值的差异称为残差。损失函数计算残差平方的平均值。我们通过以下方式在 TensorFlow 中定义它:
loss = tf.reduce_mean(tf.square(model - y_tensor))
model - y_tensor
计算残差tf.square(model - y_tensor)
计算每个残差的平方tf.reduce_mean( ... )
最终计算在前一步骤中计算的平方均值
我们还定义均方误差(MSE)和 R 平方(RS)函数来评估训练模型。我们使用单独的mse
函数,因为在接下来的章节中,损失函数将改变但mse
函数将保持不变。
# mse and R2 functions mse = tf.reduce_mean(tf.square(model - y_tensor)) y_mean = tf.reduce_mean(y_tensor) total_error = tf.reduce_sum(tf.square(y_tensor - y_mean)) unexplained_error = tf.reduce_sum(tf.square(y_tensor - model)) rs = 1 - tf.div(unexplained_error, total_error)
定义优化器函数
接下来,我们实例化学习率为 0.001 的theGradientDescentOptimizer
函数并将其设置为最小化损失函数:
learning_rate = 0.001 optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
有关梯度下降的更多详细信息,请访问此链接:
https://en.wikipedia.org/wiki/Gradient_descent
TensorFlow 提供了许多其他优化器函数,如 Adadelta,Adagrad 和 Adam。我们将在以下章节中介绍其中一些内容。
训练模型
现在我们已经定义了模型,损失函数和优化函数,训练模型来学习参数w
和b
。要训练模型,请定义以下全局变量:
num_epochs
:运行训练的迭代次数。每次迭代,模型都会学习更好的参数,我们将在后面的图中看到。w_hat
和b_hat
:收集估计的w
和b
参数。loss_epochs
,mse_epochs
,rs_epochs
:收集训练数据集中的总误差值,以及每次迭代中测试数据集上模型的 mse 和 R 平方值。mse_score
和rs_score
:收集最终训练模型的 mse 和 R 平方值。
num_epochs = 1500 w_hat = 0 b_hat = 0 loss_epochs = np.empty(shape=[num_epochs],dtype=float) mse_epochs = np.empty(shape=[num_epochs],dtype=float) rs_epochs = np.empty(shape=[num_epochs],dtype=float) mse_score = 0 rs_score = 0
初始化会话和全局变量后,运行num_epoch
次的训练循环:
with tf.Session() as tfs: tf.global_variables_initializer().run() for epoch in range(num_epochs):
在循环的每次迭代中,在训练数据上运行优化器:
tfs.run(optimizer, feed_dict={x_tensor: X_train, y_tensor: y_train})
使用学习的w
和b
值,计算误差并将其保存在loss_val
中以便稍后绘制:
loss_val = tfs.run(loss,feed_dict={x_tensor: X_train, y_tensor: y_train}) loss_epochs[epoch] = loss_val
计算测试数据预测值的均方误差和 R 平方值:
mse_score = tfs.run(mse,feed_dict={x_tensor: X_test, y_tensor: y_test}) mse_epochs[epoch] = mse_score rs_score = tfs.run(rs,feed_dict={x_tensor: X_test, y_tensor: y_test}) rs_epochs[epoch] = rs_score
最后,一旦完成循环,保存w
和b
的值以便稍后绘制它们:
w_hat,b_hat = tfs.run([w,b]) w_hat = w_hat.reshape(1)
让我们在 2,000 次迭代后打印模型和测试数据的最终均方误差:
print('model : Y = {0:.8f} X + {1:.8f}'.format(w_hat[0],b_hat[0])) print('For test data : MSE = {0:.8f}, R2 = {1:.8f} '.format( mse_score,rs_score))
This gives us the following output:
model : Y = 20.37448120 X + -2.75295663 For test data : MSE = 297.57995605, R2 = 0.66098368
因此,我们训练的模型不是一个非常好的模型,但我们将在后面的章节中看到如何使用神经网络来改进它。
本章的目标是介绍如何使用 TensorFlow 构建和训练回归模型,而无需使用神经网络。
让我们绘制估计模型和原始数据:
plt.figure(figsize=(14,8)) plt.title('Original Data and Trained Model') x_plot = [np.min(X)-1,np.max(X)+1] y_plot = w_hat*x_plot+b_hat plt.axis([x_plot[0],x_plot[1],y_plot[0],y_plot[1]]) plt.plot(X,y,'b.',label='Original Data') plt.plot(x_plot,y_plot,'r-',label='Trained Model') plt.legend() plt.show()
精通 TensorFlow 1.x:1~5(3)https://developer.aliyun.com/article/1426816