TensorFlow入门教程(21)分心驾驶行为检测

#
#作者:韦访
#博客:https://blog.csdn.net/rookie_wei
#微信:1007895847
#添加微信的备注一下是CSDN的
#欢迎大家一起学习
#

1、概述

通过前面20讲的内容,应该对TensorFlow有一点了解了。很久没更新博客了,现在早已换了人间,已经开始属于TensorFlow2的时代了。那么,这讲就做个分心驾驶行为检测来初识TensorFlow2,顺便学习怎么通过微调别人的模型来用到自己的任务中。

环境配置:

操作系统:Win10 64位

显卡:GTX 1080ti

Python:Python3.7

TensorFlow:2.3.0

2、数据集

我们这里用kaggle的state-farm-distracted-driver-detection数据集。网址如下,注册个账号就可以下载了:

https://www.kaggle.com/c/state-farm-distracted-driver-detection

下载完数据集以后,解压,根目录得到一个文件夹个两个文件。

先来看文件夹下有什么。

根据以往的经验,根据文件名大致也能猜出,test用于测试的,train用于训练的。先来看train文件夹,

Train文件夹下共有10个子文件夹,每个子文件夹下的图片属于同类,每类共有两千多张图片。这10类及其含义如下:

  • c0: safe driving
  • c1: texting - right
  • c2: talking on the phone - right
  • c3: texting - left
  • c4: talking on the phone - left
  • c5: operating the radio
  • c6: drinking
  • c7: reaching behind
  • c8: hair and makeup
  • c9: talking to passenger

再来看test文件夹,

Test文件夹下直接是图片,接近8万张,但是每个文件分别属于哪类并不知道。

一般需要有个验证集来验证模型准确率,而且验证集的数据不能是训练集里的数据,所以我们新建一个valid的文件夹,跟train文件夹一样包含10个文件名为c0到c9的子文件夹,

为了简单起见,将train文件夹下的每个子文件夹下的30张图片剪切到valid文件夹下对应的子文件夹。

这样,我们就做好了验证集。

3、导入数据

数据集做好以后,我们就来写代码,导入它们。使用image_dataset_from_directory函数很容易就可以导入了,比较简单,代码如下,

import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf

from tensorflow.keras.preprocessing import image_dataset_from_directory

# 数据集中的训练和验证数据集
ROOT_DIR = "./dataset"
train_dir = os.path.join(ROOT_DIR, 'train')
valid_dir = os.path.join(ROOT_DIR, 'valid')


# 设置送入模型的图片的尺寸
IMG_SIZE = (160, 160)
# 因为我们验证集中每类只有30张图片,所以这里batch size就设置得小些,直接设置成10就好了
train_dataset = image_dataset_from_directory(train_dir, shuffle=True, batch_size=32, image_size=IMG_SIZE)
valid_dataset = image_dataset_from_directory(valid_dir, shuffle=True, batch_size=10, image_size=IMG_SIZE)

# 默认文件名即为我们的类别名,这里打印出来看看
class_names = train_dataset.class_names
num_classes = len(class_names)
print(class_names)
print(valid_dataset.class_names)

# prefetch提供了pipeline的方式读取数据,更高效
# 参考: https://tensorflow.google.cn/guide/data_performance
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
valid_dataset = valid_dataset.prefetch(buffer_size=AUTOTUNE)

# 把它们显示出来看看对不对
plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
  for i in range(9):
    ax = plt.subplot(3, 3, i + 1)
    plt.imshow(images[i].numpy().astype("uint8"))
    plt.title(class_names[labels[i]])
    plt.axis("off")

plt.show()

运行结果如下,

4、导入MobileNetV2模型

因为这里做的是分类任务,分类任务中有很多优秀、成熟的网络,比如MobileNet,VGG,ResNet等等,我们直接拿来用就好了,而且我们也不需要从头到尾自己训练,可以用别人通过ImageNet这种大型数据集训练好的模型。我们这里使用MobileNet网络,TensorFlow2也集成了这些API,很方便调用,代码如下,

#Create the base model from the pre-trained model MobileNet V2
IMG_SHAPE = IMG_SIZE + (3,)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE, include_top=False, weights='imagenet')
base_model.summary()

如果第一次运行,TensorFlow会自动将已经训练好的网络下载并加载。通过summary函数就可以打印网络结构。运行结果如下,

5、构建网络

上面的MobileNet网络只是我们网络中的一部分,所以现在我们要结合它来构建我们的网络,

# 数据增强操作
data_augmentation = tf.keras.Sequential([
  tf.keras.layers.experimental.preprocessing.RandomFlip('horizontal'),
  tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
])

# 数据进入MobileNetV2之前要先经过preprocess_input处理
preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input
# 全局平均池化层,参考: https://www.cnblogs.com/hutao722/p/10008581.html
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
# 输出层
prediction_layer = tf.keras.layers.Dense(num_classes)
# 输入
inputs = tf.keras.Input(shape=IMG_SHAPE)
x = data_augmentation(inputs)
x = preprocess_input(x)
x = base_model(x, training=False)
x = global_average_layer(x)
x = tf.keras.layers.Dropout(0.2)(x)
outputs = prediction_layer(x)
model = tf.keras.Model(inputs, outputs)
# 让MobileNetV2变得可训练
base_model.trainable = True
# 但是,前100层的参数让它冻结,我们只训练后面层的参数
fine_tune_at = 100
# Freeze all the layers before the `fine_tune_at` layer
for layer in base_model.layers[:fine_tune_at]:
  layer.trainable =  False

6、定义损失函数,优化器

接下来定义损失函数和优化器,

# 定义损失函数
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
# 定义学习率
base_learning_rate = 0.00001
# 定义优化器
optimizer = tf.keras.optimizers.RMSprop(lr=base_learning_rate)

7、训练和保存模型

最后,训练和保存模型即可,

model.compile(loss=loss,
              optimizer = optimizer,
              metrics=['accuracy'])

# 开始训练
total_epochs =  50
history = model.fit(train_dataset,
                    epochs=total_epochs,
                    validation_data=valid_dataset)


# 在验证集里验证模型准确率
loss0, accuracy0 = model.evaluate(valid_dataset)
print("initial loss: {:.2f}".format(loss0))
print("initial accuracy: {:.2f}".format(accuracy0))

# 模型保存路径
MODEL_DIR = "./models/"
if not os.path.exists(MODEL_DIR):
  os.makedirs(MODEL_DIR)

# 保存模型
h5_dir = os.path.join(MODEL_DIR, 'ddd_mobilenet_v2.h5')
model.save(h5_dir)

# 我们将保持好的模型再导入,再在验证集里查看它的准确率
new_model = tf.keras.models.load_model(h5_dir)
for images, labels in valid_dataset.take(1):
  for i in range(10):
    img = np.expand_dims(images[i], axis=0)
    predictions = new_model.predict(img)    
    predictions = np.argmax(predictions[0])
    print("pred:", class_names[predictions], " label:" , class_names[labels[i]])

运行结果,

可以看到,在训练集中的准确率能到99.58%,在测试集中的准确率为98.72%。

8、完整代码

完整代码链接如下,

https://mianbaoduo.com/o/bread/aZqUkpY=

  • 5
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值