热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

opencv4.5.0c++人脸识别模型保存_TensorFlow2.0教程使用keras训练模型

TensorFlow2.0教程-使用keras训练模型最全Tensorflow2.0入门教程持续更新:Doit:最全Tensorflow2.0入门教程持
0742da9d799fcbc459b8232030619984.gif

TensorFlow2.0教程-使用keras训练模型

最全Tensorflow 2.0 入门教程持续更新:

Doit:最全Tensorflow 2.0 入门教程持续更新​zhuanlan.zhihu.com
14bab2963c4f45054a7f89f7cd218534.png

完整tensorflow2.0教程代码请看https://github.com/czy36mengfei/tensorflow2_tutorials_chinese (欢迎star)

本教程主要由tensorflow2.0官方教程的个人学习复现笔记整理而来,中文讲解,方便喜欢阅读中文教程的朋友,官方教程:https://www.tensorflow.org

1.一般的模型构造、训练、测试流程

# 模型构造
inputs = keras.Input(shape=(784,), name='mnist_input')
h1 = layers.Dense(64, activation='relu')(inputs)
h1 = layers.Dense(64, activation='relu')(h1)
outputs = layers.Dense(10, activation='softmax')(h1)
model = keras.Model(inputs, outputs)
# keras.utils.plot_model(model, 'net001.png', show_shapes=True)model.compile(optimizer=keras.optimizers.RMSprop(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[keras.metrics.SparseCategoricalAccuracy()])# 载入数据
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') /255
x_test = x_test.reshape(10000, 784).astype('float32') /255x_val = x_train[-10000:]
y_val = y_train[-10000:]x_train = x_train[:-10000]
y_train = y_train[:-10000]# 训练模型
history = model.fit(x_train, y_train, batch_size=64, epochs=3,validation_data=(x_val, y_val))
print('history:')
print(history.history)result = model.evaluate(x_test, y_test, batch_size=128)
print('evaluate:')
print(result)
pred = model.predict(x_test[:2])
print('predict:')
print(pred)

2.自定义损失和指标

自定义指标只需继承Metric类, 并重写一下函数

_init_(self),初始化。

update_state(self,y_true,y_pred,sample_weight = None),它使用目标y_true和模型预测y_pred来更新状态变量。

result(self),它使用状态变量来计算最终结果。

reset_states(self),重新初始化度量的状态。

# 这是一个简单的示例,显示如何实现CatgoricalTruePositives指标,该指标计算正确分类为属于给定类的样本数量class CatgoricalTruePostives(keras.metrics.Metric):def __init__(self, name='binary_true_postives', **kwargs):super(CatgoricalTruePostives, self).__init__(name=name, **kwargs)self.true_postives = self.add_weight(name='tp', initializer='zeros')def update_state(self, y_true, y_pred, sample_weight=None):y_pred = tf.argmax(y_pred)y_true = tf.equal(tf.cast(y_pred, tf.int32), tf.cast(y_true, tf.int32))y_true = tf.cast(y_true, tf.float32)if sample_weight is not None:sample_weight = tf.cast(sample_weight, tf.float32)y_true = tf.multiply(sample_weight, y_true)return self.true_postives.assign_add(tf.reduce_sum(y_true))def result(self):return tf.identity(self.true_postives)def reset_states(self):self.true_postives.assign(0.)model.compile(optimizer=keras.optimizers.RMSprop(1e-3),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[CatgoricalTruePostives()])model.fit(x_train, y_train,batch_size=64, epochs=3)
# 以定义网络层的方式添加网络loss
class ActivityRegularizationLayer(layers.Layer):def call(self, inputs):self.add_loss(tf.reduce_sum(inputs) * 0.1)return inputsinputs = keras.Input(shape=(784,), name='mnist_input')
h1 = layers.Dense(64, activation='relu')(inputs)
h1 = ActivityRegularizationLayer()(h1)
h1 = layers.Dense(64, activation='relu')(h1)
outputs = layers.Dense(10, activation='softmax')(h1)
model = keras.Model(inputs, outputs)
# keras.utils.plot_model(model, 'net001.png', show_shapes=True)model.compile(optimizer=keras.optimizers.RMSprop(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[keras.metrics.SparseCategoricalAccuracy()])
model.fit(x_train, y_train, batch_size=32, epochs=1)
# 也可以以定义网络层的方式添加要统计的metric
class MetricLoggingLayer(layers.Layer):def call(self, inputs):self.add_metric(keras.backend.std(inputs),name='std_of_activation',aggregation='mean')return inputsinputs = keras.Input(shape=(784,), name='mnist_input')
h1 = layers.Dense(64, activation='relu')(inputs)
h1 = MetricLoggingLayer()(h1)
h1 = layers.Dense(64, activation='relu')(h1)
outputs = layers.Dense(10, activation='softmax')(h1)
model = keras.Model(inputs, outputs)
# keras.utils.plot_model(model, 'net001.png', show_shapes=True)model.compile(optimizer=keras.optimizers.RMSprop(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[keras.metrics.SparseCategoricalAccuracy()])
model.fit(x_train, y_train, batch_size=32, epochs=1)
# 也可以直接在model上面加
# 也可以以定义网络层的方式添加要统计的metric
class MetricLoggingLayer(layers.Layer):def call(self, inputs):self.add_metric(keras.backend.std(inputs),name='std_of_activation',aggregation='mean')return inputsinputs = keras.Input(shape=(784,), name='mnist_input')
h1 = layers.Dense(64, activation='relu')(inputs)
h2 = layers.Dense(64, activation='relu')(h1)
outputs = layers.Dense(10, activation='softmax')(h2)
model = keras.Model(inputs, outputs)model.add_metric(keras.backend.std(inputs),name='std_of_activation',aggregation='mean')
model.add_loss(tf.reduce_sum(h1)*0.1)# keras.utils.plot_model(model, 'net001.png', show_shapes=True)model.compile(optimizer=keras.optimizers.RMSprop(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[keras.metrics.SparseCategoricalAccuracy()])
model.fit(x_train, y_train, batch_size=32, epochs=1)

处理使用validation_data传入测试数据,还可以使用validation_split划分验证数据

ps:validation_split只能在用numpy数据训练的情况下使用

model.fit(x_train, y_train, batch_size=32, epochs=1, validation_split=0.2)

3.使用tf.data构造数据

def get_compiled_model():inputs = keras.Input(shape=(784,), name='mnist_input')h1 = layers.Dense(64, activation='relu')(inputs)h2 = layers.Dense(64, activation='relu')(h1)outputs = layers.Dense(10, activation='softmax')(h2)model = keras.Model(inputs, outputs)model.compile(optimizer=keras.optimizers.RMSprop(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=[keras.metrics.SparseCategoricalAccuracy()])return model
model = get_compiled_model()
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)# model.fit(train_dataset, epochs=3)
# steps_per_epoch 每个epoch只训练几步
# validation_steps 每次验证,验证几步
model.fit(train_dataset, epochs=3, steps_per_epoch=100,validation_data=val_dataset, validation_steps=3)

4.样本权重和类权重

“样本权重”数组是一个数字数组,用于指定批处理中每个样本在计算总损失时应具有多少权重。 它通常用于不平衡的分类问题(这个想法是为了给予很少见的类更多的权重)。 当使用的权重是1和0时,该数组可以用作损失函数的掩码(完全丢弃某些样本对总损失的贡献)。

“类权重”dict是同一概念的更具体的实例:它将类索引映射到应该用于属于该类的样本的样本权重。 例如,如果类“0”比数据中的类“1”少两倍,则可以使用class_weight = {0:1.,1:0.5}。

# 增加第5类的权重
import numpy as np
# 类权重
model = get_compiled_model()
class_weight = {i:1.0 for i in range(10)}
class_weight[5] = 2.0
print(class_weight)
model.fit(x_train, y_train,class_weight=class_weight,batch_size=64,epochs=4)
# 样本权重
model = get_compiled_model()
sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0
model.fit(x_train, y_train,sample_weight=sample_weight,batch_size=64,epochs=4)
# tf.data数据
model = get_compiled_model()sample_weight = np.ones(shape=(len(y_train),))
sample_weight[y_train == 5] = 2.0train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train,sample_weight))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)model.fit(train_dataset, epochs=3, )

5.多输入多输出模型

image_input = keras.Input(shape=(32, 32, 3), name='img_input')
timeseries_input = keras.Input(shape=(None, 10), name='ts_input')x1 = layers.Conv2D(3, 3)(image_input)
x1 = layers.GlobalMaxPooling2D()(x1)x2 = layers.Conv1D(3, 3)(timeseries_input)
x2 = layers.GlobalMaxPooling1D()(x2)x = layers.concatenate([x1, x2])score_output = layers.Dense(1, name='score_output')(x)
class_output = layers.Dense(5, activation='softmax', name='class_output')(x)model = keras.Model(inputs=[image_input, timeseries_input],outputs=[score_output, class_output])
keras.utils.plot_model(model, 'multi_input_output_model.png', show_shapes=True)
# 可以为模型指定不同的loss和metrics
model.compile(optimizer=keras.optimizers.RMSprop(1e-3),loss=[keras.losses.MeanSquaredError(),keras.losses.CategoricalCrossentropy()])# 还可以指定loss的权重
model.compile(optimizer=keras.optimizers.RMSprop(1e-3),loss={'score_output': keras.losses.MeanSquaredError(),'class_output': keras.losses.CategoricalCrossentropy()},metrics={'score_output': [keras.metrics.MeanAbsolutePercentageError(),keras.metrics.MeanAbsoluteError()],'class_output': [keras.metrics.CategoricalAccuracy()]},loss_weight={'score_output': 2., 'class_output': 1.})# 可以把不需要传播的loss置0
model.compile(optimizer=keras.optimizers.RMSprop(1e-3),loss=[None, keras.losses.CategoricalCrossentropy()])# Or dict loss version
model.compile(optimizer=keras.optimizers.RMSprop(1e-3),loss={'class_output': keras.losses.CategoricalCrossentropy()})

6.使用回调

Keras中的回调是在训练期间(在epoch开始时,batch结束时,epoch结束时等)在不同点调用的对象,可用于实现以下行为:

  • 在培训期间的不同时间点进行验证(超出内置的每个时期验证)
  • 定期检查模型或超过某个精度阈值
  • 在训练似乎平稳时改变模型的学习率
  • 在训练似乎平稳时对顶层进行微调
  • 在培训结束或超出某个性能阈值时发送电子邮件或即时消息通知等等。

可使用的内置回调有

  • ModelCheckpoint:定期保存模型。
  • EarlyStopping:当训练不再改进验证指标时停止培训。
  • TensorBoard:定期编写可在TensorBoard中显示的模型日志(更多细节见“可视化”)。
  • CSVLogger:将丢失和指标数据流式传输到CSV文件。
  • 等等

6.1回调使用

model = get_compiled_model()callbacks = [keras.callbacks.EarlyStopping(# 是否有提升关注的指标monitor='val_loss',# 不再提升的阈值min_delta=1e-2,# 2个epoch没有提升就停止patience=2,verbose=1)
]
model.fit(x_train, y_train,epochs=20,batch_size=64,callbacks=callbacks,validation_split=0.2)
# checkpoint模型回调
model = get_compiled_model()
check_callback = keras.callbacks.ModelCheckpoint(filepath='mymodel_{epoch}.h5',save_best_only=True,monitor='val_loss',verbose=1
)model.fit(x_train, y_train,epochs=3,batch_size=64,callbacks=[check_callback],validation_split=0.2)
# 动态调整学习率
initial_learning_rate = 0.1
lr_schedule = keras.optimizers.schedules.ExponentialDecay(initial_learning_rate,decay_steps=10000,decay_rate=0.96,staircase=True
)
optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)
# 使用tensorboard
tensorboard_cbk = keras.callbacks.TensorBoard(log_dir='./full_path_to_your_logs')
model.fit(x_train, y_train,epochs=5,batch_size=64,callbacks=[tensorboard_cbk],validation_split=0.2)

6.2创建自己的回调方法

class LossHistory(keras.callbacks.Callback):def on_train_begin(self, logs):self.losses = []def on_epoch_end(self, batch, logs):self.losses.append(logs.get('loss'))print('nloss:',self.losses[-1])model = get_compiled_model()callbacks = [LossHistory()
]
model.fit(x_train, y_train,epochs=3,batch_size=64,callbacks=callbacks,validation_split=0.2)

7.自己构造训练和验证循环

# 构建一个全连接网络.
inputs = keras.Input(shape=(784,), name='digits')
x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
x = layers.Dense(64, activation='relu', name='dense_2')(x)
outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
model = keras.Model(inputs=inputs, outputs=outputs)# 优化器.
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# 损失函数.
loss_fn = keras.losses.SparseCategoricalCrossentropy()# 准备数据.
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)# 自己构造循环
for epoch in range(3):print('epoch: ', epoch)for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):# 开一个gradient tape, 计算梯度with tf.GradientTape() as tape:logits = model(x_batch_train)loss_value = loss_fn(y_batch_train, logits)grads = tape.gradient(loss_value, model.trainable_variables)optimizer.apply_gradients(zip(grads, model.trainable_variables))if step % 200 == 0:print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))print('Seen so far: %s samples' % ((step + 1) * 64))

训练并验证

# 训练并验证
# 获取模型
inputs = keras.Input(shape=(784,), name='digits')
x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
x = layers.Dense(64, activation='relu', name='dense_2')(x)
outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
model = keras.Model(inputs=inputs, outputs=outputs)# sgd优化器
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# 分类损失函数
loss_fn = keras.losses.SparseCategoricalCrossentropy()# 设定统计参数
train_acc_metric = keras.metrics.SparseCategoricalAccuracy()
val_acc_metric = keras.metrics.SparseCategoricalAccuracy()# 准备训练数据
batch_size = 64
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)# 准备验证数据
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)# 迭代训练
for epoch in range(3):print('Start of epoch %d' % (epoch,))for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):with tf.GradientTape() as tape:logits = model(x_batch_train)loss_value = loss_fn(y_batch_train, logits)grads = tape.gradient(loss_value, model.trainable_variables)optimizer.apply_gradients(zip(grads, model.trainable_variables))# 更新统计传输train_acc_metric(y_batch_train, logits)# 输出if step % 200 == 0:print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))print('Seen so far: %s samples' % ((step + 1) * 64))# 输出统计参数的值train_acc = train_acc_metric.result()print('Training acc over epoch: %s' % (float(train_acc),))# 重置统计参数train_acc_metric.reset_states()# 用模型进行验证for x_batch_val, y_batch_val in val_dataset:val_logits = model(x_batch_val)# 根据验证的统计参数val_acc_metric(y_batch_val, val_logits)val_acc = val_acc_metric.result()val_acc_metric.reset_states()print('Validation acc: %s' % (float(val_acc),))

添加自己构造的loss

## 添加自己构造的loss, 每次只能看到最新一次训练增加的loss
class ActivityRegularizationLayer(layers.Layer):def call(self, inputs):self.add_loss(1e-2 * tf.reduce_sum(inputs))return inputsinputs = keras.Input(shape=(784,), name='digits')
x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
# Insert activity regularization as a layer
x = ActivityRegularizationLayer()(x)
x = layers.Dense(64, activation='relu', name='dense_2')(x)
outputs = layers.Dense(10, activation='softmax', name='predictions')(x)model = keras.Model(inputs=inputs, outputs=outputs)
logits = model(x_train[:64])
print(model.losses)
logits = model(x_train[:64])
logits = model(x_train[64: 128])
logits = model(x_train[128: 192])
print(model.losses)
# 将loss添加进求导中
optimizer = keras.optimizers.SGD(learning_rate=1e-3)for epoch in range(3):print('Start of epoch %d' % (epoch,))for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):with tf.GradientTape() as tape:logits = model(x_batch_train)loss_value = loss_fn(y_batch_train, logits)# 添加额外的lossloss_value += sum(model.losses)grads = tape.gradient(loss_value, model.trainable_variables)optimizer.apply_gradients(zip(grads, model.trainable_variables))# 每200个batch输出一次学习.if step % 200 == 0:print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))print('Seen so far: %s samples' % ((step + 1) * 64))




推荐阅读
  • 本文探讨了在Qt框架下实现TCP多线程服务器端的方法,解决了一个常见的问题:服务器端仅能与最后一个连接的客户端通信。通过继承QThread类并利用socketDescriptor标识符,实现了多个客户端与服务器端的同时通信。 ... [详细]
  • 本文详细介绍了如何通过配置 Chrome 和 VS Code 来实现对 Vue 项目的高效调试。步骤包括启用 Chrome 的远程调试功能、安装 VS Code 插件以及正确配置 launch.json 文件。 ... [详细]
  • 字符、字符串和文本的处理之Char类型
    .NetFramework中处理字符和字符串的主要有以下这么几个类:(1)、System.Char类一基础字符串处理类(2)、System.String类一处理不可变的字符串(一经 ... [详细]
  • ECharts图表绘制函数集
    本文档提供了使用ECharts库创建柱状图、饼图和双折线图的JavaScript函数。每个函数都详细列出了参数说明,并通过示例展示了如何调用这些函数以生成不同类型的图表。 ... [详细]
  • 本文详细介绍了Python中的流程控制与条件判断技术,包括数据导入、数据变换、统计描述、假设检验、可视化以及自定义函数的创建等方面的内容。 ... [详细]
  • 使用Objective-C实现苹果官方NSLayoutConstraint页面布局
    本文详细介绍了如何在iOS开发中使用Objective-C语言通过NSLayoutConstraint来实现页面布局。示例代码展示了如何创建和应用约束,以确保界面元素能够正确地响应不同屏幕尺寸的变化。 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • Activity跳转动画 无缝衔接
    Activity跳转动画 无缝衔接 ... [详细]
  • 万事起于配置开发环境
    万事起于配置开发环境 ... [详细]
  • 深入理解AutoMapper:.NET中的高效对象映射工具
    AutoMapper 是一个用于 .NET 平台的对象映射库,它能够简化不同对象模型之间的数据转换过程。本文将详细介绍 AutoMapper 的基本功能、应用场景及配置方法。 ... [详细]
  • 本文介绍了多种将多行数据合并为单行的方法,包括使用动态SQL、函数、CTE等技术,适用于不同的SQL Server版本。 ... [详细]
  • VMware 15.5.7 中文版激活方法
    本文提供了一种有效的方法来激活 VMware 15.5.7 的中文版本,同时介绍了如何利用最新的激活码进行操作,确保用户能够顺利使用。 ... [详细]
  • C基本语法C程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。对象-对象具有状态和行为 ... [详细]
  • 本文介绍了如何使用Workman框架构建一个功能全面的即时通讯系统,该系统不仅支持一对一聊天、群组聊天,还集成了视频会议和实时音视频通话功能,同时提供了红包发送等附加功能。 ... [详细]
  • [编程题] LeetCode上的Dynamic Programming(动态规划)类型的题目
    继上次把backTracking的题目做了一下之后:backTracking,我把LeetCode的动态规划的题目又做了一下,还有几道比较难的Medium的题和Hard的题没做出来,后面会继续 ... [详细]
author-avatar
-起司Cheese-
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有