Keras 实现卷积神经网络识别手写数字、迁移学习以及tf.keras.applications使用

短命女 2023-07-17 04:45 54阅读 0赞

日萌社" class="reference-link">20191009191333910.png日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


4.4 案例:CNN进行分类

4.4.1 卷积神经网络构建识别手写数字

卷积神经网络包含一个或多个卷积层(Convolutional Layer)、池化层(Pooling Layer)和全连接层(Fully-connected Layer)。

4.4.1.1 使用 Keras 实现卷积神经网络

卷积神经网络的一个实现现如下所示,新加入了一些卷积层和池化层。当然这个网络可以增加、删除或调整 CNN 的网络结构和参数,以达到更好效果。

  1. class CNN(tf.keras.Model):
  2. def __init__(self):
  3. super().__init__()
  4. self.conv1 = tf.keras.layers.Conv2D(
  5. filters=32, # 卷积层神经元(卷积核)数目
  6. kernel_size=[5, 5], # 卷积核大小
  7. padding='same', # padding策略(vaild 或 same)
  8. activation=tf.nn.relu # 激活函数
  9. )
  10. self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  11. self.conv2 = tf.keras.layers.Conv2D(
  12. filters=64,
  13. kernel_size=[5, 5],
  14. padding='same',
  15. activation=tf.nn.relu
  16. )
  17. self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  18. self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
  19. self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu)
  20. self.dense2 = tf.keras.layers.Dense(units=10)
  21. def call(self, inputs):
  22. x = self.conv1(inputs) # [batch_size, 28, 28, 32]
  23. x = self.pool1(x) # [batch_size, 14, 14, 32]
  24. x = self.conv2(x) # [batch_size, 14, 14, 64]
  25. x = self.pool2(x) # [batch_size, 7, 7, 64]
  26. x = self.flatten(x) # [batch_size, 7 * 7 * 64]
  27. x = self.dense1(x) # [batch_size, 1024]
  28. x = self.dense2(x) # [batch_size, 10]
  29. output = tf.nn.softmax(x)
  30. return output

将前节的 model = MLP() 更换成 model = CNN() ,训练结束以及预测输出:

  1. 批次 4682: 损失 0.010545
  2. 批次 4683: 损失 0.003783
  3. 批次 4684: 损失 0.000980
  4. 测试准确率: 0.990600

可以发现准确率相较于之前的多层感知机有非常显著的提高。

我们来看一个个问题如果我们要做一个具体场景的计算机视觉任务,那么从头开始训练一个网络是合适的选择吗?怎么样才能避免浪费过多的计算时间?


keras_mlp.py

  1. import tensorflow as tf
  2. import numpy as np
  3. import os
  4. os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
  5. num_epochs = 5
  6. batch_size = 64
  7. learning_rate = 0.001
  8. class MnistLoader(object):
  9. """数据加载处理类
  10. """
  11. def __init__(self):
  12. # 1、获取数据
  13. (self.train_data, self.train_label), (self.test_data, self.test_label) = \
  14. tf.keras.datasets.mnist.load_data()
  15. # 2、处理数据, 归一化,维度拓展,类型
  16. self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1)
  17. self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)
  18. self.train_label = self.train_label.astype(np.int32)
  19. self.test_label = self.test_label.astype(np.int32)
  20. # 获取一个变量接收数据量
  21. self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]
  22. def get_batch(self, batch_size):
  23. """按照训练获取指定大小数据的批次数据
  24. :param batch_size: 每批次数据的大小
  25. :return:
  26. """
  27. # 获取随机生成的batch_size大小的下标
  28. index = np.random.randint(0, self.train_data.shape[0], batch_size)
  29. return self.train_data[index, :], self.train_label[index]
  30. class MLP(tf.keras.Model):
  31. """自定义MLP类
  32. """
  33. def __init__(self):
  34. super().__init__()
  35. # 卷积到全连接层的数据形状处理
  36. self.flatten = tf.keras.layers.Flatten()
  37. self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)
  38. self.dense2 = tf.keras.layers.Dense(units=10)
  39. def call(self, inputs):
  40. """
  41. :param inputs: 模型的输入
  42. :return:
  43. """
  44. # 此例子中输入[batch_size, 28 ,28, 1]
  45. x = self.flatten(inputs)
  46. x = self.dense1(x)
  47. x = self.dense2(x)
  48. # 经过softmax计算[batch_size, 10]
  49. output = tf.nn.softmax(x)
  50. return output
  51. class CNN(tf.keras.Model):
  52. """自定义CNN类,两层卷积池化+两个全连接层
  53. """
  54. def __init__(self):
  55. super().__init__()
  56. # 两层卷积池化+两个全连接层
  57. # [batch_size, 28 ,28, 1]--->[batch_size, 14, 14, 32]
  58. # 第一层:32个filter, 5 * 5, padding=same
  59. self.conv1 = tf.keras.layers.Conv2D(
  60. filters=32, # 卷积核数量
  61. kernel_size=[5, 5], # 卷积核大小
  62. padding='same', # 领填充方式
  63. activation=tf.nn.relu # 激活函数
  64. )
  65. self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  66. # 第二层:64个filter, 5 * 5, padding=same
  67. # [batch_size, 14 ,14, 32]--->[batch_size, 7, 7, 64]
  68. self.conv2 = tf.keras.layers.Conv2D(
  69. filters=64, # 卷积核数量
  70. kernel_size=[5, 5], # 卷积核大小
  71. padding='same', # 领填充方式
  72. activation=tf.nn.relu # 激活函数
  73. )
  74. self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  75. # 经过一个形状变化在输入到全连接层网络
  76. self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
  77. self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu)
  78. self.dense2 = tf.keras.layers.Dense(units=10)
  79. def call(self, inputs):
  80. """模型输入输出构建
  81. :param inputs: 输入[batch_size, 28 ,28, 1]
  82. :return:
  83. """
  84. x = self.conv1(inputs)
  85. x = self.pool1(x)
  86. x = self.conv2(x)
  87. x = self.pool2(x)
  88. x = self.flatten(x)
  89. x = self.dense1(x)
  90. x = self.dense2(x)
  91. output = tf.nn.softmax(x)
  92. return output
  93. def train():
  94. """模型训练逻辑
  95. :return:
  96. """
  97. # 1、从 DataLoader 中随机取一批训练数据,并且初始化模型
  98. mnist = MnistLoader()
  99. # model = MLP()
  100. model = CNN()
  101. optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
  102. # 2、将这批数据送入模型,计算出模型的预测值;
  103. # 总共样本len(train_data), 迭代次数epoches表示所有数据过几遍,batch_size:每批次训练的样本32, 64
  104. # 一共需要多少批次 len(train_data)/ batch_size * epoches举例 1000/10 = 10批次才训练完成,10 * 5
  105. num_batches = int(mnist.num_train_data // batch_size * num_epochs)
  106. for batch_index in range(num_batches):
  107. X, y = mnist.get_batch(batch_size)
  108. with tf.GradientTape() as tape:
  109. y_pred = model(X)
  110. # 3、将模型预测值与真实值进行比较,计算损失函数(loss)。这里使用
  111. # tf.keras.losses 中的交叉熵函数作为损失函数;
  112. loss = tf.reduce_mean(tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred))
  113. print("批次 %d: 损失 %f" % (batch_index, loss.numpy()))
  114. # 4、计算损失函数关于模型变量的导数;
  115. grads = tape.gradient(loss, model.variables)
  116. # 5、将求出的导数值传入优化器,使用优化器的 apply_gradients 方法更新模型参数以最小化损失函数(优化器的详细使用方法见 前章 )。
  117. optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
  118. # 3、对测试数据及进行评估
  119. y_pred = model.predict(mnist.test_data)
  120. # 初始化一个metrics
  121. sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
  122. sparse_categorical_accuracy.update_state(y_true=mnist.test_label, y_pred=y_pred)
  123. print("测试准确率:%f" % (sparse_categorical_accuracy.result()))
  124. return None
  125. if __name__ == '__main__':
  126. # mnist = MnistLoader()
  127. # train_data, train_label = mnist.get_batch(64)
  128. # print(train_data, train_label)
  129. train()

4.4.2 迁移学习(Transfer Learning)-Keras 中预定义的经典卷积神经网络结构

4.4.2.1 介绍

  • 定义

    • 迁移学习就是利用数据、任务或模型之间的相似性,将在旧的领域学习过或训练好的模型,应用于新的领域这样的一个过程。
    • 两个任务的输入属于同一性质:要么同是图像、要么同是语音或其他

迁移学习到底在什么情况下使用呢?有两个方面需要我们考虑的

  • 1、当我们有海量的数据资源时,可以不需要迁移学习,机器学习系统很容易从海量数据中学习到一个鲁棒性很强的模型。但通常情况下,我们需要研究的领域可获得的数据极为有限,在少量的训练样本上精度极高,但是泛化效果极差。
  • 2、训练成本,很少去从头开始训练一整个深度卷积网络,从头开始训练一个卷积网络通常需要较长时间且依赖于强大的 GPU 计算资源。

4.4.2.2 方法

  • 最常见的称呼叫做fine tuning,即微调

    • 已训练好的模型,称之为Pre-trained model

通常我们需要加载以训练好的模型,这些可以是一些机构或者公司在ImageNet等类似比赛上进行训练过的模型。TensorFlow同样也提供了相关模型地址以及API:https://www.tensorflow.org/api_docs/python/tf/keras/applications

下图是其中包含的一些模型:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ppbWlhbzU1MjE0NzU3Mg_size_16_color_FFFFFF_t_70

2.5.1.3 过程

这里我们举一个例子,假设有两个任务A和B,任务 A 拥有海量的数据资源且已训练好,但并不是我们的目标任务,任务 B 是我们的目标任务。下面的网络模型假设是已训练好的1000个类别模型

20200319162009375.png

而B任务假设是某个具体场景如250个类别的食物识别,那么该怎么去做

  • 1、建立自己的网络,在A的基础上,修改最后输出结构,并加载A的模型参数
  • 2、根据数据大小调整

    • 如果B任务数据量小,那么我们可以选择将A模型的所有的层进行freeze(可以通过Tensorflow的trainable=False参数实现),而剩下的输出层部分可以选择调整参数训练
    • 如果B任务的数据量大,那么我们可以将A中一半或者大部分的层进行freeze,而剩下部分的layer可以进行新任务数据基础上的微调

4.4.2 使用

tf.keras.applications 中有一些预定义好的经典卷积神经网络结构,如 VGG16 、 VGG19 、 ResNet 、 MobileNet 等。我们可以直接调用这些经典的卷积神经网络结构(甚至载入预训练的参数),而无需手动定义网络结构。

  • 支持以下结构:

    • densenet module: DenseNet models for Keras.
    • imagenet_utils module: Utilities for ImageNet data preprocessing & prediction decoding.
    • inception_resnet_v2 module: Inception-ResNet V2 model for Keras.
    • inception_v3 module: Inception V3 model for Keras.
    • mobilenet module: MobileNet v1 models for Keras.
    • mobilenet_v2 module: MobileNet v2 models for Keras.
    • nasnet module: NASNet-A models for Keras.
    • resnet module: ResNet models for Keras.
    • resnet50 module: Public API for tf.keras.applications.resnet50 namespace.
    • resnet_v2 module: ResNet v2 models for Keras.
    • vgg16 module: VGG16 model for Keras.
    • vgg19 module: VGG19 model for Keras.
    • xception module: Xception V1 model for Keras.
  • 我们可以使用以下代码来实例化一个 MobileNetV2 网络结构:

    • model = tf.keras.applications.MobileNetV2()
    • input_shape :输入张量的形状(不含第一维的 Batch),大多默认为 224 × 224 × 3 。一般而言,模型对输入张量的大小有下限,长和宽至少为 32 × 32 或 75 × 75 ;
    • include_top :在网络的最后是否包含全连接层,默认为 True ;
    • weights :预训练权值,默认为 ‘imagenet’ ,即为当前模型载入在 ImageNet 数据集上预训练的权值。如需随机初始化变量可设为 None ;
    • classes :分类数,默认为 1000。修改该参数需要 include_top 参数为 True 且 weights 参数为 None 。

当执行以上代码时,TensorFlow 会自动从网络上下载 MobileNetV2 网络结构,因此在第一次执行代码时需要具备网络连接。

可以使用 MobileNetV2 网络对相关数据集进行训练看看效果

  1. model = tf.keras.applications.MobileNetV2(weights=None, classes=5)

4.4.3 总结

  • 掌握keras卷积网络相关API
  • 卷机网络的构建
  • 迁移学习以及tf.keras.applications使用

transfer_learning.py

  1. import tensorflow as tf
  2. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  3. from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
  4. import numpy as np
  5. import os
  6. os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
  7. class TransferModel(object):
  8. """VGG迁移学习做5个类别图片识别
  9. """
  10. def __init__(self):
  11. # 初始化训练集和测试集的迭代器
  12. self.train_generator = ImageDataGenerator(rescale=1.0 / 255.0,
  13. shear_range=0.2,
  14. zoom_range=0.2,
  15. horizontal_flip=True)
  16. self.test_generator = ImageDataGenerator(rescale=1.0 / 255.0)
  17. # 数据目录
  18. self.train_dir = "./data/train"
  19. self.test_dir = "./data/test"
  20. # 定义输入数据的大小和批次大小
  21. self.image_size = (224, 224)
  22. self.batch_size = 32
  23. # 初始化VGG基础模型,
  24. self.base_model = VGG16(weights='imagenet', include_top=False)
  25. self.label_dict = {
  26. '0': 'bus',
  27. '1': 'dinosaurs',
  28. '2': 'elephants',
  29. '3': 'flowers',
  30. '4': 'horse'
  31. }
  32. def get_local_data(self):
  33. """读取本地的图片数据以及类别标签
  34. :return:
  35. """
  36. # 1、datagen.flow_from_directory
  37. train_gen = self.train_generator.flow_from_directory(self.train_dir,
  38. target_size=self.image_size,
  39. batch_size=self.batch_size,
  40. class_mode='binary',
  41. shuffle=True)
  42. test_gen = self.train_generator.flow_from_directory(self.test_dir,
  43. target_size=self.image_size,
  44. batch_size=self.batch_size,
  45. class_mode='binary',
  46. shuffle=True)
  47. return train_gen, test_gen
  48. def refine_base_model(self):
  49. """
  50. 修改VGG的模型,在VGG的5个block,[None, ?, ?, 512]--->全局平均池化-->两个全连接层1024, 5
  51. :return: 新的迁移学习模型
  52. """
  53. # 1、获取VGG模型的输出,不包含原有模型的top结构
  54. x = self.base_model.outputs[0]
  55. # 2、在VGG的输出之后定义自己的模型
  56. x = tf.keras.layers.GlobalAveragePooling2D()(x)
  57. # 两个全连接层
  58. x = tf.keras.layers.Dense(1024, activation=tf.nn.relu)(x)
  59. y_predict = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)
  60. # 3、使用Model封装新的模型返回
  61. transfer_model = tf.keras.models.Model(inputs=self.base_model.inputs, outputs=y_predict)
  62. return transfer_model
  63. def freeze_vgg_model(self):
  64. """
  65. 冻结VGG的前面卷积结构,不参与训练
  66. :return:
  67. """
  68. # 循环获取base_model当中的层
  69. for layer in self.base_model.layers:
  70. layer.trainable = False
  71. return None
  72. def compile(self, model):
  73. """
  74. 编译模型,指定优化器损失计算方式,准确率衡量
  75. :return:
  76. """
  77. model.compile(optimizer=tf.keras.optimizers.Adam(),
  78. loss=tf.keras.losses.sparse_categorical_crossentropy,
  79. metrics=['accuracy'])
  80. return None
  81. def fit_generator(self, model, train_gen, test_gen):
  82. """进行模型训练,注意使用fit_generator,不是fit
  83. :param model:
  84. :param train_gen:
  85. :param test_gen:
  86. :return:
  87. """
  88. modelckpt = tf.keras.callbacks.ModelCheckpoint('./ckpt/transfer_{epoch:02d}-{val_accuracy:.2f}.h5',
  89. monitor='val_accuracy',
  90. save_best_only=True,
  91. save_weights_only=False,
  92. mode='auto',
  93. period=1)
  94. model.fit_generator(train_gen, epochs=3, validation_data=test_gen, callbacks=[modelckpt])
  95. return None
  96. def predict(self, model):
  97. """预测输入图片的类别
  98. :return:
  99. """
  100. # 1、加载模型训练好的权重
  101. model.load_weights("./ckpt/transfer_01-0.84.h5")
  102. # 2、读取图片处理图片数据,形状,数据归一化
  103. image = tf.io.read_file("./data/test/dinosaurs/402.jpg")
  104. image_decoded = tf.image.decode_jpeg(image)
  105. image_resized = tf.image.resize(image_decoded, [224, 224]) / 255.0
  106. # 3维-->4维的形状改变
  107. img = tf.reshape(image_resized, (1, image_resized.shape[0], image_resized.shape[1], image_resized.shape[2]))
  108. print("修改之后的形状:", img.shape)
  109. # 3、输入数据做预测
  110. y_predict = model.predict(img)
  111. index = np.argmax(y_predict, axis=1)
  112. print(self.label_dict[str(index[0])])
  113. return None
  114. if __name__ == '__main__':
  115. tm = TransferModel()
  116. # # 训练模型步骤
  117. # # 1、读取数据
  118. # train_gen, test_gen = tm.get_local_data()
  119. # # print(train_gen, test_gen)
  120. # # 2、定义模型去微调模型和冻结模型
  121. # # 3、模型的compile和训练
  122. # model = tm.refine_base_model()
  123. # print(model.summary())
  124. # tm.freeze_vgg_model()
  125. # tm.compile(model)
  126. # tm.fit_generator(model, train_gen, test_gen)
  127. # 测试数据
  128. transfer_model = tm.refine_base_model()
  129. tm.predict(transfer_model)

fashion_mnist.py

  1. import tensorflow as tf
  2. import numpy as np
  3. import os
  4. os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
  5. num_epochs = 10
  6. batch_size = 64
  7. learning_rate = 0.001
  8. class MnistLoader(object):
  9. """数据加载处理类
  10. """
  11. def __init__(self):
  12. # 1、获取数据
  13. (self.train_data, self.train_label), (self.test_data, self.test_label) = \
  14. tf.keras.datasets.fashion_mnist.load_data()
  15. # 2、处理数据, 归一化,维度拓展,类型
  16. self.train_data = np.expand_dims(self.train_data.astype(np.float32) / 255.0, axis=-1)
  17. self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)
  18. self.train_label = self.train_label.astype(np.int32)
  19. self.test_label = self.test_label.astype(np.int32)
  20. # 获取一个变量接收数据量
  21. self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]
  22. def get_batch(self, batch_size):
  23. """按照训练获取指定大小数据的批次数据
  24. :param batch_size: 每批次数据的大小
  25. :return:
  26. """
  27. # 获取随机生成的batch_size大小的下标
  28. index = np.random.randint(0, self.train_data.shape[0], batch_size)
  29. return self.train_data[index, :], self.train_label[index]
  30. class MLP(tf.keras.Model):
  31. """自定义MLP类
  32. """
  33. def __init__(self):
  34. super().__init__()
  35. # 卷积到全连接层的数据形状处理
  36. self.flatten = tf.keras.layers.Flatten()
  37. self.dense1 = tf.keras.layers.Dense(units=128, activation=tf.nn.relu)
  38. self.dense2 = tf.keras.layers.Dense(units=10)
  39. def call(self, inputs):
  40. """
  41. :param inputs: 模型的输入
  42. :return:
  43. """
  44. # 此例子中输入[batch_size, 28 ,28, 1]
  45. x = self.flatten(inputs)
  46. x = self.dense1(x)
  47. x = self.dense2(x)
  48. # 经过softmax计算[batch_size, 10]
  49. output = tf.nn.softmax(x)
  50. return output
  51. class CNN(tf.keras.Model):
  52. """自定义CNN类,两层卷积池化+两个全连接层
  53. """
  54. def __init__(self):
  55. super().__init__()
  56. # 两层卷积池化+两个全连接层
  57. # [batch_size, 28 ,28, 1]--->[batch_size, 14, 14, 32]
  58. # 第一层:32个filter, 5 * 5, padding=same
  59. self.conv1 = tf.keras.layers.Conv2D(
  60. filters=32, # 卷积核数量
  61. kernel_size=[3, 3], # 卷积核大小
  62. padding='same', # 领填充方式
  63. activation=tf.nn.relu, # 激活函数
  64. kernel_regularizer=tf.keras.regularizers.l2(0.0001)
  65. )
  66. self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  67. # 第二层:64个filter, 5 * 5, padding=same
  68. # [batch_size, 14 ,14, 32]--->[batch_size, 7, 7, 64]
  69. self.conv2 = tf.keras.layers.Conv2D(
  70. filters=64, # 卷积核数量
  71. kernel_size=[3, 3], # 卷积核大小
  72. padding='same', # 领填充方式
  73. activation=tf.nn.relu, # 激活函数
  74. kernel_regularizer=tf.keras.regularizers.l2(0.0001)
  75. )
  76. self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
  77. # 经过一个形状变化在输入到全连接层网络
  78. self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
  79. self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu, kernel_regularizer=tf.keras.regularizers.l2(0.0001))
  80. self.dropout = tf.keras.layers.Dropout(rate=0.4)
  81. self.dense2 = tf.keras.layers.Dense(units=10)
  82. def call(self, inputs):
  83. """模型输入输出构建
  84. :param inputs: 输入[batch_size, 28 ,28, 1]
  85. :return:
  86. """
  87. x = self.conv1(inputs)
  88. x = self.pool1(x)
  89. x = self.conv2(x)
  90. x = self.pool2(x)
  91. x = self.flatten(x)
  92. x = self.dense1(x)
  93. # x = self.dropout(x, training=True)
  94. x = self.dense2(x)
  95. output = tf.nn.softmax(x)
  96. return output
  97. def train():
  98. """模型训练逻辑
  99. :return:
  100. """
  101. # 1、从 DataLoader 中随机取一批训练数据,并且初始化模型
  102. mnist = MnistLoader()
  103. # model = MLP()
  104. model = CNN()
  105. optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
  106. # 2、将这批数据送入模型,计算出模型的预测值;
  107. # 总共样本len(train_data), 迭代次数epoches表示所有数据过几遍,batch_size:每批次训练的样本32, 64
  108. # 一共需要多少批次 len(train_data)/ batch_size * epoches举例 1000/10 = 10批次才训练完成,10 * 5
  109. num_batches = int(mnist.num_train_data // batch_size * num_epochs)
  110. for batch_index in range(num_batches):
  111. X, y = mnist.get_batch(batch_size)
  112. with tf.GradientTape() as tape:
  113. y_pred = model(X)
  114. # 3、将模型预测值与真实值进行比较,计算损失函数(loss)。这里使用
  115. # tf.keras.losses 中的交叉熵函数作为损失函数;
  116. loss = tf.reduce_mean(tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred))
  117. print("批次 %d: 损失 %f" % (batch_index, loss.numpy()))
  118. # 4、计算损失函数关于模型变量的导数;
  119. grads = tape.gradient(loss, model.variables)
  120. # 5、将求出的导数值传入优化器,使用优化器的 apply_gradients 方法更新模型参数以最小化损失函数(优化器的详细使用方法见 前章 )。
  121. optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
  122. # 3、对测试数据及进行评估
  123. y_pred = model.predict(mnist.test_data)
  124. # 初始化一个metrics
  125. sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
  126. sparse_categorical_accuracy.update_state(y_true=mnist.test_label, y_pred=y_pred)
  127. print("测试准确率:%f" % (sparse_categorical_accuracy.result()))
  128. return None
  129. if __name__ == '__main__':
  130. # mnist = MnistLoader()
  131. # train_data, train_label = mnist.get_batch(64)
  132. # print(train_data, train_label)
  133. train()

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ppbWlhbzU1MjE0NzU3Mg_size_16_color_FFFFFF_t_70 1

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ppbWlhbzU1MjE0NzU3Mg_size_16_color_FFFFFF_t_70 2

发表评论

表情:
评论列表 (有 0 条评论,54人围观)

还没有评论,来说两句吧...

相关阅读