• 售前

  • 售后

热门帖子
入门百科

TensorFlow2.0利用keras练习模型的实现

[复制链接]
wzyu638116 显示全部楼层 发表于 2021-10-25 19:48:05 |阅读模式 打印 上一主题 下一主题
目次


  • 1.一般的模子构造、训练、测试流程
  • 2.自定义损失和指标
  • 3.利用tf.data构造数据
  • 4.样本权重和类权重
  • 5.多输入多输出模子
  • 6.利用回 调

    • 6.1回调利用
    • 6.2创建自己的回调方法

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

1.一般的模子构造、训练、测试流程
  1. # 模型构造
  2. inputs = keras.Input(shape=(784,), name='mnist_input')
  3. h1 = layers.Dense(64, activation='relu')(inputs)
  4. h1 = layers.Dense(64, activation='relu')(h1)
  5. outputs = layers.Dense(10, activation='softmax')(h1)
  6. model = keras.Model(inputs, outputs)
  7. # keras.utils.plot_model(model, 'net001.png', show_shapes=True)
  8. model.compile(optimizer=keras.optimizers.RMSprop(),
  9.     loss=keras.losses.SparseCategoricalCrossentropy(),
  10.     metrics=[keras.metrics.SparseCategoricalAccuracy()])
  11. # 载入数据
  12. (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
  13. x_train = x_train.reshape(60000, 784).astype('float32') /255
  14. x_test = x_test.reshape(10000, 784).astype('float32') /255
  15. x_val = x_train[-10000:]
  16. y_val = y_train[-10000:]
  17. x_train = x_train[:-10000]
  18. y_train = y_train[:-10000]
  19. # 训练模型
  20. history = model.fit(x_train, y_train, batch_size=64, epochs=3,
  21.    validation_data=(x_val, y_val))
  22. print('history:')
  23. print(history.history)
  24. result = model.evaluate(x_test, y_test, batch_size=128)
  25. print('evaluate:')
  26. print(result)
  27. pred = model.predict(x_test[:2])
  28. print('predict:')
  29. 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),重新初始化度量的状态。
  1. # 这是一个简单的示例,显示如何实现CatgoricalTruePositives指标,该指标计算正确分类为属于给定类的样本数量
  2. class CatgoricalTruePostives(keras.metrics.Metric):
  3. def __init__(self, name='binary_true_postives', **kwargs):
  4.   super(CatgoricalTruePostives, self).__init__(name=name, **kwargs)
  5.   self.true_postives = self.add_weight(name='tp', initializer='zeros')
  6.   
  7. def update_state(self, y_true, y_pred, sample_weight=None):
  8.   y_pred = tf.argmax(y_pred)
  9.   y_true = tf.equal(tf.cast(y_pred, tf.int32), tf.cast(y_true, tf.int32))
  10.   
  11.   y_true = tf.cast(y_true, tf.float32)
  12.   
  13.   if sample_weight is not None:
  14.    sample_weight = tf.cast(sample_weight, tf.float32)
  15.    y_true = tf.multiply(sample_weight, y_true)
  16.    
  17.   return self.true_postives.assign_add(tf.reduce_sum(y_true))
  18. def result(self):
  19.   return tf.identity(self.true_postives)
  20. def reset_states(self):
  21.   self.true_postives.assign(0.)
  22.   
  23. model.compile(optimizer=keras.optimizers.RMSprop(1e-3),
  24.     loss=keras.losses.SparseCategoricalCrossentropy(),
  25.     metrics=[CatgoricalTruePostives()])
  26. model.fit(x_train, y_train,
  27.    batch_size=64, epochs=3)
复制代码
  1. # 以定义网络层的方式添加网络loss
  2. class ActivityRegularizationLayer(layers.Layer):
  3. def call(self, inputs):
  4.   self.add_loss(tf.reduce_sum(inputs) * 0.1)
  5.   return inputs
  6. inputs = keras.Input(shape=(784,), name='mnist_input')
  7. h1 = layers.Dense(64, activation='relu')(inputs)
  8. h1 = ActivityRegularizationLayer()(h1)
  9. h1 = layers.Dense(64, activation='relu')(h1)
  10. outputs = layers.Dense(10, activation='softmax')(h1)
  11. model = keras.Model(inputs, outputs)
  12. # keras.utils.plot_model(model, 'net001.png', show_shapes=True)
  13. model.compile(optimizer=keras.optimizers.RMSprop(),
  14.     loss=keras.losses.SparseCategoricalCrossentropy(),
  15.     metrics=[keras.metrics.SparseCategoricalAccuracy()])
  16. model.fit(x_train, y_train, batch_size=32, epochs=1)
复制代码
  1. # 也可以以定义网络层的方式添加要统计的metric
  2. class MetricLoggingLayer(layers.Layer):
  3. def call(self, inputs):
  4.   self.add_metric(keras.backend.std(inputs),
  5.       name='std_of_activation',
  6.       aggregation='mean')
  7.   
  8.   return inputs
  9. inputs = keras.Input(shape=(784,), name='mnist_input')
  10. h1 = layers.Dense(64, activation='relu')(inputs)
  11. h1 = MetricLoggingLayer()(h1)
  12. h1 = layers.Dense(64, activation='relu')(h1)
  13. outputs = layers.Dense(10, activation='softmax')(h1)
  14. model = keras.Model(inputs, outputs)
  15. # keras.utils.plot_model(model, 'net001.png', show_shapes=True)
  16. model.compile(optimizer=keras.optimizers.RMSprop(),
  17.     loss=keras.losses.SparseCategoricalCrossentropy(),
  18.     metrics=[keras.metrics.SparseCategoricalAccuracy()])
  19. model.fit(x_train, y_train, batch_size=32, epochs=1)
复制代码
  1. # 也可以直接在model上面加
  2. # 也可以以定义网络层的方式添加要统计的metric
  3. class MetricLoggingLayer(layers.Layer):
  4. def call(self, inputs):
  5.   self.add_metric(keras.backend.std(inputs),
  6.       name='std_of_activation',
  7.       aggregation='mean')
  8.   
  9.   return inputs
  10. inputs = keras.Input(shape=(784,), name='mnist_input')
  11. h1 = layers.Dense(64, activation='relu')(inputs)
  12. h2 = layers.Dense(64, activation='relu')(h1)
  13. outputs = layers.Dense(10, activation='softmax')(h2)
  14. model = keras.Model(inputs, outputs)
  15. model.add_metric(keras.backend.std(inputs),
  16.       name='std_of_activation',
  17.       aggregation='mean')
  18. model.add_loss(tf.reduce_sum(h1)*0.1)
  19. # keras.utils.plot_model(model, 'net001.png', show_shapes=True)
  20. model.compile(optimizer=keras.optimizers.RMSprop(),
  21.     loss=keras.losses.SparseCategoricalCrossentropy(),
  22.     metrics=[keras.metrics.SparseCategoricalAccuracy()])
  23. model.fit(x_train, y_train, batch_size=32, epochs=1)
复制代码
处理利用validation_data传入测试数据,还可以利用validation_split划分验证数据
ps:validation_split只能在用numpy数据训练的环境下利用
  1. model.fit(x_train, y_train, batch_size=32, epochs=1, validation_split=0.2)
复制代码
3.利用tf.data构造数据

  1. def get_compiled_model():
  2. inputs = keras.Input(shape=(784,), name='mnist_input')
  3. h1 = layers.Dense(64, activation='relu')(inputs)
  4. h2 = layers.Dense(64, activation='relu')(h1)
  5. outputs = layers.Dense(10, activation='softmax')(h2)
  6. model = keras.Model(inputs, outputs)
  7. model.compile(optimizer=keras.optimizers.RMSprop(),
  8.      loss=keras.losses.SparseCategoricalCrossentropy(),
  9.      metrics=[keras.metrics.SparseCategoricalAccuracy()])
  10. return model
  11. model = get_compiled_model()
  12. train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  13. train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
  14. val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
  15. val_dataset = val_dataset.batch(64)
  16. # model.fit(train_dataset, epochs=3)
  17. # steps_per_epoch 每个epoch只训练几步
  18. # validation_steps 每次验证,验证几步
  19. model.fit(train_dataset, epochs=3, steps_per_epoch=100,
  20.    validation_data=val_dataset, validation_steps=3)
复制代码
4.样本权重和类权重


“样本权重”数组是一个数字数组,用于指定批处理中每个样本在计算总损失时应具有多少权重。 它通常用于不均衡的分类题目(这个想法是为了给予很少见的类更多的权重)。 当利用的权重是1和0时,该数组可以用作损失函数的掩码(完全抛弃某些样本对总损失的贡献)。
“类权重”dict是同一概念的更详细的实例:它将类索引映射到应该用于属于该类的样本的样本权重。 比方,假如类“0”比数据中的类“1”少两倍,则可以利用class_weight = {0:1.,1:0.5}。
  1. # 增加第5类的权重
  2. import numpy as np
  3. # 样本权重
  4. model = get_compiled_model()
  5. class_weight = {i:1.0 for i in range(10)}
  6. class_weight[5] = 2.0
  7. print(class_weight)
  8. model.fit(x_train, y_train,
  9.    class_weight=class_weight,
  10.    batch_size=64,
  11.    epochs=4)
  12. # 类权重
  13. model = get_compiled_model()
  14. sample_weight = np.ones(shape=(len(y_train),))
  15. sample_weight[y_train == 5] = 2.0
  16. model.fit(x_train, y_train,
  17.    sample_weight=sample_weight,
  18.    batch_size=64,
  19.    epochs=4)
复制代码
  1. # tf.data数据
  2. model = get_compiled_model()
  3. sample_weight = np.ones(shape=(len(y_train),))
  4. sample_weight[y_train == 5] = 2.0
  5. train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train,
  6.              sample_weight))
  7. train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
  8. val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
  9. val_dataset = val_dataset.batch(64)
  10. model.fit(train_dataset, epochs=3, )
复制代码
5.多输入多输出模子

  1. image_input = keras.Input(shape=(32, 32, 3), name='img_input')
  2. timeseries_input = keras.Input(shape=(None, 10), name='ts_input')
  3. x1 = layers.Conv2D(3, 3)(image_input)
  4. x1 = layers.GlobalMaxPooling2D()(x1)
  5. x2 = layers.Conv1D(3, 3)(timeseries_input)
  6. x2 = layers.GlobalMaxPooling1D()(x2)
  7. x = layers.concatenate([x1, x2])
  8. score_output = layers.Dense(1, name='score_output')(x)
  9. class_output = layers.Dense(5, activation='softmax', name='class_output')(x)
  10. model = keras.Model(inputs=[image_input, timeseries_input],
  11.      outputs=[score_output, class_output])
  12. keras.utils.plot_model(model, 'multi_input_output_model.png'
  13.       , show_shapes=True)
复制代码
  1. # 可以为模型指定不同的loss和metrics
  2. model.compile(
  3. optimizer=keras.optimizers.RMSprop(1e-3),
  4. loss=[keras.losses.MeanSquaredError(),
  5.    keras.losses.CategoricalCrossentropy()])
  6. # 还可以指定loss的权重
  7. model.compile(
  8. optimizer=keras.optimizers.RMSprop(1e-3),
  9. loss={'score_output': keras.losses.MeanSquaredError(),
  10.    'class_output': keras.losses.CategoricalCrossentropy()},
  11. metrics={'score_output': [keras.metrics.MeanAbsolutePercentageError(),
  12.         keras.metrics.MeanAbsoluteError()],
  13.     'class_output': [keras.metrics.CategoricalAccuracy()]},
  14. loss_weight={'score_output': 2., 'class_output': 1.})
  15. # 可以把不需要传播的loss置0
  16. model.compile(
  17. optimizer=keras.optimizers.RMSprop(1e-3),
  18. loss=[None, keras.losses.CategoricalCrossentropy()])
  19. # Or dict loss version
  20. model.compile(
  21. optimizer=keras.optimizers.RMSprop(1e-3),
  22. loss={'class_output': keras.losses.CategoricalCrossentropy()})
复制代码
6.利用回 调


Keras中的回调是在训练期间(在epoch开始时,batch竣事时,epoch竣事时等)在差别点调用的对象,可用于实现以下举动:
      
  • 在培训期间的差别时间点举行验证(超出内置的每个时期验证)  
  • 定期查抄模子或超过某个精度阈值  
  • 在训练好像平稳时改变模子的学习率  
  • 在训练好像平稳时对顶层举行微调  
  • 在培训竣事或超出某个性能阈值时发送电子邮件或即时消息关照等等。
可利用的内置回调有
      
  • ModelCheckpoint:定期保存模子。  
  • EarlyStopping:当训练不再改进验证指标时制止培训。  
  • TensorBoard:定期编写可在TensorBoard中显示的模子日记(更多细节见“可视化”)。  
  • CSVLogger:将丢失和指标数据流式传输到CSV文件。  
  • 等等

6.1回调利用

  1. model = get_compiled_model()
  2. callbacks = [
  3. keras.callbacks.EarlyStopping(
  4.   # Stop training when `val_loss` is no longer improving
  5.   monitor='val_loss',
  6.   # "no longer improving" being defined as "no better than 1e-2 less"
  7.   min_delta=1e-2,
  8.   # "no longer improving" being further defined as "for at least 2 epochs"
  9.   patience=2,
  10.   verbose=1)
  11. ]
  12. model.fit(x_train, y_train,
  13.    epochs=20,
  14.    batch_size=64,
  15.    callbacks=callbacks,
  16.    validation_split=0.2)
复制代码
  1. # checkpoint模型回调
  2. model = get_compiled_model()
  3. check_callback = keras.callbacks.ModelCheckpoint(
  4. filepath='mymodel_{epoch}.h5',
  5. save_best_only=True,
  6. monitor='val_loss',
  7. verbose=1
  8. )
  9. model.fit(x_train, y_train,
  10.    epochs=3,
  11.    batch_size=64,
  12.    callbacks=[check_callback],
  13.    validation_split=0.2)
复制代码
  1. # 动态调整学习率
  2. initial_learning_rate = 0.1
  3. lr_schedule = keras.optimizers.schedules.ExponentialDecay(
  4. initial_learning_rate,
  5. decay_steps=10000,
  6. decay_rate=0.96,
  7. staircase=True
  8. )
  9. optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)
复制代码
  1. # 使用tensorboard
  2. tensorboard_cbk = keras.callbacks.TensorBoard(log_dir='./full_path_to_your_logs')
  3. model.fit(x_train, y_train,
  4.    epochs=5,
  5.    batch_size=64,
  6.    callbacks=[tensorboard_cbk],
  7.    validation_split=0.2)
复制代码
6.2创建自己的回调方法

  1. class LossHistory(keras.callbacks.Callback):
  2. def on_train_begin(self, logs):
  3.   self.losses = []
  4. def on_epoch_end(self, batch, logs):
  5.   self.losses.append(logs.get('loss'))
  6.   print('\nloss:',self.losses[-1])
  7.   
  8. model = get_compiled_model()
  9. callbacks = [
  10. LossHistory()
  11. ]
  12. model.fit(x_train, y_train,
  13.    epochs=3,
  14.    batch_size=64,
  15.    callbacks=callbacks,
  16.    validation_split=0.2)
复制代码
7.自己构造训练和验证循环

  1. # Get the model.
  2. inputs = keras.Input(shape=(784,), name='digits')
  3. x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
  4. x = layers.Dense(64, activation='relu', name='dense_2')(x)
  5. outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
  6. model = keras.Model(inputs=inputs, outputs=outputs)
  7. # Instantiate an optimizer.
  8. optimizer = keras.optimizers.SGD(learning_rate=1e-3)
  9. # Instantiate a loss function.
  10. loss_fn = keras.losses.SparseCategoricalCrossentropy()
  11. # Prepare the training dataset.
  12. batch_size = 64
  13. train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  14. train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)
  15. # 自己构造循环
  16. for epoch in range(3):
  17. print('epoch: ', epoch)
  18. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
  19.   # 开一个gradient tape, 计算梯度
  20.   with tf.GradientTape() as tape:
  21.    logits = model(x_batch_train)
  22.    
  23.    loss_value = loss_fn(y_batch_train, logits)
  24.    grads = tape.gradient(loss_value, model.trainable_variables)
  25.    optimizer.apply_gradients(zip(grads, model.trainable_variables))
  26.    
  27.   if step % 200 == 0:
  28.    print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))
  29.    print('Seen so far: %s samples' % ((step + 1) * 64))
复制代码
  1. # 训练并验证
  2. # Get model
  3. inputs = keras.Input(shape=(784,), name='digits')
  4. x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
  5. x = layers.Dense(64, activation='relu', name='dense_2')(x)
  6. outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
  7. model = keras.Model(inputs=inputs, outputs=outputs)
  8. # Instantiate an optimizer to train the model.
  9. optimizer = keras.optimizers.SGD(learning_rate=1e-3)
  10. # Instantiate a loss function.
  11. loss_fn = keras.losses.SparseCategoricalCrossentropy()
  12. # Prepare the metrics.
  13. train_acc_metric = keras.metrics.SparseCategoricalAccuracy()
  14. val_acc_metric = keras.metrics.SparseCategoricalAccuracy()
  15. # Prepare the training dataset.
  16. batch_size = 64
  17. train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  18. train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size)
  19. # Prepare the validation dataset.
  20. val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val))
  21. val_dataset = val_dataset.batch(64)
  22. # Iterate over epochs.
  23. for epoch in range(3):
  24. print('Start of epoch %d' % (epoch,))
  25. # Iterate over the batches of the dataset.
  26. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
  27. with tf.GradientTape() as tape:
  28.   logits = model(x_batch_train)
  29.   loss_value = loss_fn(y_batch_train, logits)
  30. grads = tape.gradient(loss_value, model.trainable_variables)
  31. optimizer.apply_gradients(zip(grads, model.trainable_variables))
  32.   
  33. # Update training metric.
  34. train_acc_metric(y_batch_train, logits)
  35. # Log every 200 batches.
  36. if step % 200 == 0:
  37.   print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))
  38.   print('Seen so far: %s samples' % ((step + 1) * 64))
  39. # Display metrics at the end of each epoch.
  40. train_acc = train_acc_metric.result()
  41. print('Training acc over epoch: %s' % (float(train_acc),))
  42. # Reset training metrics at the end of each epoch
  43. train_acc_metric.reset_states()
  44. # Run a validation loop at the end of each epoch.
  45. for x_batch_val, y_batch_val in val_dataset:
  46. val_logits = model(x_batch_val)
  47. # Update val metrics
  48. val_acc_metric(y_batch_val, val_logits)
  49. val_acc = val_acc_metric.result()
  50. val_acc_metric.reset_states()
  51. print('Validation acc: %s' % (float(val_acc),))
复制代码
  1. ## 添加自己构造的loss, 每次只能看到最新一次训练增加的loss
  2. class ActivityRegularizationLayer(layers.Layer):
  3. def call(self, inputs):
  4. self.add_loss(1e-2 * tf.reduce_sum(inputs))
  5. return inputs
  6. inputs = keras.Input(shape=(784,), name='digits')
  7. x = layers.Dense(64, activation='relu', name='dense_1')(inputs)
  8. # Insert activity regularization as a layer
  9. x = ActivityRegularizationLayer()(x)
  10. x = layers.Dense(64, activation='relu', name='dense_2')(x)
  11. outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
  12. model = keras.Model(inputs=inputs, outputs=outputs)
  13. logits = model(x_train[:64])
  14. print(model.losses)
  15. logits = model(x_train[:64])
  16. logits = model(x_train[64: 128])
  17. logits = model(x_train[128: 192])
  18. print(model.losses)
复制代码
  1. # 将loss添加进求导中
  2. optimizer = keras.optimizers.SGD(learning_rate=1e-3)
  3. for epoch in range(3):
  4. print('Start of epoch %d' % (epoch,))
  5. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
  6. with tf.GradientTape() as tape:
  7.   logits = model(x_batch_train)
  8.   loss_value = loss_fn(y_batch_train, logits)
  9.   # Add extra losses created during this forward pass:
  10.   loss_value += sum(model.losses)
  11.   
  12. grads = tape.gradient(loss_value, model.trainable_variables)
  13. optimizer.apply_gradients(zip(grads, model.trainable_variables))
  14. # Log every 200 batches.
  15. if step % 200 == 0:
  16.   print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value)))
  17.   print('Seen so far: %s samples' % ((step + 1) * 64))
复制代码
到此这篇关于TensorFlow2.0利用keras训练模子的实现的文章就先容到这了,更多相干TensorFlow2.0 keras训练模子内容请搜索草根技术分享以前的文章或继续欣赏下面的相干文章希望大家以后多多支持草根技术分享!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作