MachineLearning入门---第4章---TensorFlow示例(cifar图⽚数据建模流程示例)

指导教程: https://github.com/lyhue1991/eat_tensorflow2_in_30_days

python版本 3.7.5  下载地址 https://www.python.org/ftp/python/3.7.5/python-3.7.5-amd64.exe
tensorflow 2.7.0 cpu版 : pip install tensorflow-cpu==2.7.0
开发环境: Idea + python插件

代码中所用到的数据:https://github.com/lyhue1991/eat_tensorflow2_in_30_days/tree/master/data/cifar2

# -*- coding: utf-8 -*-
import os

import tensorflow as tf
from matplotlib import pyplot as plt
import datetime
from tensorboard import notebook
import pandas as pd

BATCH_SIZE = 100

'''
    cifar图片分类案例
    准备数据
    定义
    训练
    评估
    使用
    保存
'''


def load_image(img_path, size=(32, 32)):
    label = tf.constant(1, tf.int8) if tf.strings.regex_full_match(img_path, ".*automobile.*") \
        else tf.constant(0, tf.int8)
    img = tf.io.read_file(img_path)
    img = tf.image.decode_jpeg(img)  # 注意此处为jpeg格式
    img = tf.image.resize(img, size) / 255.0
    return img, label


# 获取数据 使用并行化预处理num_parallel_calls 和预存数据prefetch来提升性能
def get_train_data():
    ds_train = tf.data.Dataset.list_files("./data/cifar2/train/*/*.jpg") \
        .map(load_image, num_parallel_calls=tf.data.experimental.AUTOTUNE) \
        .shuffle(buffer_size=1000).batch(BATCH_SIZE) \
        .prefetch(tf.data.experimental.AUTOTUNE)
    return ds_train


def get_test_data():
    ds_test = tf.data.Dataset.list_files("./data/cifar2/test/*/*.jpg") \
        .map(load_image, num_parallel_calls=tf.data.experimental.AUTOTUNE) \
        .batch(BATCH_SIZE) \
        .prefetch(tf.data.experimental.AUTOTUNE)
    return ds_test


# 展示部分样本
def show_sample(show_data):
    plt.figure(figsize=(8, 8))
    for i, (img, label) in enumerate(show_data.unbatch().take(16)):
        ax = plt.subplot(4, 4, i + 1)
        ax.imshow(img.numpy())
        ax.set_title("label = %d" % label)
        ax.set_xticks([])
        ax.set_yticks([])
    plt.show()


def show_by_tensorboard():
    # 在tensorboard中查看模型
    notebook.list()
    notebook.start("--logdir ./data/keras_model")


def show_by_pandas(history):
    dfhistory = pd.DataFrame(history.history)
    dfhistory.index = range(1, len(dfhistory) + 1)
    dfhistory.index.name = 'epoch'
    print(dfhistory)


# 显示评估模型
def plot_metric(history, metric):
    train_metrics = history.history[metric]
    val_metrics = history.history['val_' + metric]
    epochs = range(1, len(train_metrics) + 1)
    plt.plot(epochs, train_metrics, 'bo--')
    plt.plot(epochs, val_metrics, 'ro-')
    plt.title('Training and validation ' + metric)
    plt.xlabel("Epochs")
    plt.ylabel(metric)
    plt.legend(["train_" + metric, 'val_' + metric])
    plt.show()


# tensorflow流程
def tf_process():
    # 获取样本数据
    ds_train = get_train_data()
    ds_test = get_test_data()
    # 展示部分样本
    # show_sample(ds_train)

    #
    # 定义模型 使用函数式API构建任意结构模型,继承Model基类构建自定义模型。
    #
    # 销毁当前的TF图并创建一个新图 有助于避免旧模型/图层混乱。
    tf.keras.backend.clear_session()

    inputs = tf.keras.layers.Input(shape=(32, 32, 3))  # 只是定义输入的数据的形状 一个形状元组(由整数组成)
    x = tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3))(inputs)  # 这是一个卷积函数 filters: 卷积核数目   kernel_size: 过滤器的大小
    x = tf.keras.layers.MaxPool2D()(x)

    # 2D卷积层 filters:输出空间的维数(即卷积中的滤波器数) kernel_size: 2个整数的整数或元组/列表,指定2D卷积窗口的高度和宽度
    x = tf.keras.layers.Conv2D(filters=64, kernel_size=(5, 5))(x)

    x = tf.keras.layers.MaxPool2D()(x)  # 创建2D最大池化层
    x = tf.keras.layers.Dropout(rate=0.1)(x)  # Dropout包括在每次更新期间随机将输入单位的分数rate设置为0,这有助于防止过度拟合(overfitting)
    x = tf.keras.layers.Flatten()(x)    # 于将输入层的数据压成一维的数据,一般用在卷积层和全连接层之间

    # 添加全连接层  units 输出维度   activation激活函数
    x = tf.keras.layers.Dense(units=32, activation='relu')(x)
    outputs = tf.keras.layers.Dense(units=1, activation='sigmoid')(x)
    model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
    model.summary()

    # 配置训练方法
    # model.compile()方法用于在配置训练方法时,告知训练时用的优化器、损失函数和准确率评测标准
    # optimizer = 优化器 , loss = 损失函数 , metrics = ["准确率”]
    model.compile(
        optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
        loss=tf.keras.losses.binary_crossentropy,
        metrics=["accuracy"]
    )

    #
    logdir = os.path.join('data', 'autograph', datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
    tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)

    # 使用内置fit方法 训练  # epochs 迭代次数太耗费时间 迭代次数可以少一点
    history = model.fit(ds_train, epochs=5, validation_data=ds_test,
                        callbacks=[tensorboard_callback], workers=4)

    # 在tensorboard中查看模型
    # show_by_tensorboard()

    # 使用pandas查看模型
    show_by_pandas(history)

    # 显示评估模型
    plot_metric(history, "loss")
    plot_metric(history, "accuracy")

    # 可以使用evaluate对数据进行评估
    val_loss, val_accuracy = model.evaluate(ds_test, workers=4)
    print("使用evaluate对数据进行评估")
    print(val_loss, val_accuracy)

    #
    #
    #
    # 使用model.predict(ds_test)进行预测
    predict = model.predict(ds_test)
    print("使用predict(ds_test)进行预测")
    print(predict)

    # 使用model.predict_on_batch(x_test)对一个批量进行预测
    # for x, y in ds_test.take(1):
    #   print(model.predict_on_batch(x[0:20]))

    #
    #  保存模型: TensorFlow原⽣⽅式保存
    #
    # 保存模型结构与模型参数到⽂件,该⽅式保存的模型具有跨平台性便于部署
    model.save('./data/tf_model_savedmodel', save_format="tf")
    del model  # 删除现有模型
    print('重新加载模型')
    model_loaded = tf.keras.models.load_model('./data/tf_model_savedmodel')

    # 使用测试数据 验证
    loaded_evaluate = model_loaded.predict(ds_test)
    print('重新加载模型 验证数据结果')
    print(loaded_evaluate)


if __name__ == '__main__':
    tf_process()

其实到现并不清楚上面的代码能干什么, 大概知道每一行是干啥的,但具体怎么用还不是很清楚!
继续!!!

上一篇:深度学习 | TensorFlow 2.x 和 1.x 限制显存(超详细)


下一篇:03.调度器分析