TensorFlow2.0使用keras训练模型的实现


Posted in Python onFebruary 20, 2021

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') /255

x_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 inputs

inputs = 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 inputs

inputs = 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 inputs

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.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.0

train_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(
  # Stop training when `val_loss` is no longer improving
  monitor='val_loss',
  # "no longer improving" being defined as "no better than 1e-2 less"
  min_delta=1e-2,
  # "no longer improving" being further defined as "for at least 2 epochs"
  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.自己构造训练和验证循环

# Get the model.
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)

# Instantiate an optimizer.
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# Instantiate a loss function.
loss_fn = keras.losses.SparseCategoricalCrossentropy()

# Prepare the training dataset.
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))
# 训练并验证
# Get model
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)

# Instantiate an optimizer to train the model.
optimizer = keras.optimizers.SGD(learning_rate=1e-3)
# Instantiate a loss function.
loss_fn = keras.losses.SparseCategoricalCrossentropy()

# Prepare the metrics.
train_acc_metric = keras.metrics.SparseCategoricalAccuracy() 
val_acc_metric = keras.metrics.SparseCategoricalAccuracy()

# Prepare the training dataset.
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)

# Prepare the validation dataset.
val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
val_dataset = val_dataset.batch(64)


# Iterate over epochs.
for epoch in range(3):
 print('Start of epoch %d' % (epoch,))
 
 # Iterate over the batches of the dataset.
 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))
  
 # Update training metric.
 train_acc_metric(y_batch_train, logits)

 # Log every 200 batches.
 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))

 # Display metrics at the end of each epoch.
 train_acc = train_acc_metric.result()
 print('Training acc over epoch: %s' % (float(train_acc),))
 # Reset training metrics at the end of each epoch
 train_acc_metric.reset_states()

 # Run a validation loop at the end of each epoch.
 for x_batch_val, y_batch_val in val_dataset:
 val_logits = model(x_batch_val)
 # Update val metrics
 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
class ActivityRegularizationLayer(layers.Layer):
 
 def call(self, inputs):
 self.add_loss(1e-2 * tf.reduce_sum(inputs))
 return inputs
 
inputs = 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)

  # Add extra losses created during this forward pass:
  loss_value += sum(model.losses)
  
 grads = tape.gradient(loss_value, model.trainable_variables)
 optimizer.apply_gradients(zip(grads, model.trainable_variables))

 # Log every 200 batches.
 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))

到此这篇关于TensorFlow2.0使用keras训练模型的实现的文章就介绍到这了,更多相关TensorFlow2.0 keras训练模型内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python编程实现及时获取新邮件的方法示例
Aug 10 Python
python图像常规操作
Nov 11 Python
python查询mysql,返回json的实例
Mar 26 Python
Python处理菜单消息操作示例【基于win32ui模块】
May 09 Python
对TensorFlow中的variables_to_restore函数详解
Jul 30 Python
python实现祝福弹窗效果
Apr 07 Python
python切片的步进、添加、连接简单操作示例
Jul 11 Python
Python实现的远程文件自动打包并下载功能示例
Jul 12 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
Aug 30 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
Feb 29 Python
Python Opencv轮廓常用操作代码实例解析
Sep 01 Python
Python confluent kafka客户端配置kerberos认证流程详解
Oct 12 Python
tensorflow2.0教程之Keras快速入门
Feb 20 #Python
在Pycharm中安装Pandas库方法(简单易懂)
Feb 20 #Python
Python3爬虫RedisDump的安装步骤
Feb 20 #Python
python爬取2021猫眼票房字体加密实例
Feb 19 #Python
Python之Sklearn使用入门教程
Feb 19 #Python
Python爬虫UA伪装爬取的实例讲解
Feb 19 #Python
Pycharm制作搞怪弹窗的实现代码
Feb 19 #Python
You might like
php 文件状态缓存带来的问题
2008/12/14 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
2013/01/13 PHP
php使用反射插入对象示例分享
2014/03/11 PHP
PHP下载文件的函数实例代码
2016/05/18 PHP
php 判断页面或图片是否经过gzip压缩的方法
2017/04/05 PHP
Laravel框架FormRequest中重写错误处理的方法
2019/02/18 PHP
javascript+css 网页每次加载不同样式的实现方法
2009/12/27 Javascript
JavaScript prototype 使用介绍
2013/08/29 Javascript
JS之Date对象和获取系统当前时间详解
2014/01/13 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
JS实现鼠标滑过折叠与展开菜单效果代码
2015/09/06 Javascript
原生JS实现仿淘宝网左侧商品分类菜单效果代码
2015/09/10 Javascript
分享javascript计算时间差的示例代码
2020/03/19 Javascript
在AngularJS框架中处理数据建模的方式解析
2016/03/05 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
解决ionic和angular上拉加载的问题
2017/08/03 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
解决Layui中layer报错的问题
2019/09/03 Javascript
深入理解 ES6中的 Reflect用法
2020/07/18 Javascript
Python使用scrapy抓取网站sitemap信息的方法
2015/04/08 Python
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
python 生成器协程运算实例
2017/09/04 Python
解决安装tensorflow遇到无法卸载numpy 1.8.0rc1的问题
2018/06/13 Python
python实现电子产品商店
2019/02/26 Python
Python supervisor强大的进程管理工具的使用
2019/04/24 Python
NumPy 数组使用大全
2019/04/25 Python
Python实现最大子序和的方法示例
2019/07/05 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
在Python中使用turtle绘制多个同心圆示例
2019/11/23 Python
非常震撼的纯CSS3人物行走动画
2016/02/24 HTML / CSS
民族学专业职业生涯规划范文:积跬步以至千里
2014/09/11 职场文书
办公用房租赁协议书
2014/11/29 职场文书
护士年终个人总结
2015/02/13 职场文书
mysql事务对效率的影响分析总结
2021/10/24 MySQL