深度学习进阶,Keras视频分类,华为面试程序题

matplotlib :用于绘图。第 3 行设置后端,以便我们可以将训练图输出到 .png 图像文件。

tensorflow.keras:用于深度学习。也就是说,我们将使用 ResNet50 CNN。我们还将使用您可以在上周的教程中阅读的 ImageDataGenerator。

sklearn :从 scikit-learn,我们将使用他们的 LabelBinarizer 实现来对我们的类标签进行单热编码。

train_test_split 函数将我们的数据集分割成训练和测试分割。我们还将以传统格式打印分类报告。

path :包含用于列出给定路径中的所有图像文件的便利函数。从那里我们将能够将我们的图像加载到内存中。

numpy :Python 的事实上的数值处理库。

argparse :用于解析命令行参数。

pickle :用于将我们的标签二值化器序列化到磁盘。

cv2:OpenCV。

os :操作系统模块将用于确保我们获取与操作系统相关的正确文件/路径分隔符。

现在让我们继续解析我们的命令行参数:

construct the argument parser and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument(“-d”, “–dataset”, required=True,

help=“path to input dataset”)

ap.add_argument(“-m”, “–model”, required=True,

help=“path to output serialized model”)

ap.add_argument(“-l”, “–label-bin”, required=True,

help=“path to output label binarizer”)

ap.add_argument(“-e”, “–epochs”, type=int, default=25,

help=“# of epochs to train our network for”)

ap.add_argument(“-p”, “–plot”, type=str, default=“plot.png”,

help=“path to output loss/accuracy plot”)

args = vars(ap.parse_args())

我们的脚本接受五个命令行参数,其中前三个是必需的:

–dataset :输入数据集的路径。

–model :我们输出 Keras 模型文件的路径。

–label-bin :我们的输出标签二值化器pickle文件的路径。

–epochs :我们的网络要训练多少个时期——默认情况下,我们将训练 25 个时期,但正如我将在本教程后面展示的,50 个时期可以带来更好的结果。

–plot :我们的输出绘图图像文件的路径——默认情况下,它将被命名为 plot.png 并放置在与此训练脚本相同的目录中。

解析并掌握我们的命令行参数后,让我们继续初始化我们的 LABELS 并加载我们的数据:

initialize the set of labels from the spots activity dataset we are

going to train our network on

LABELS = set([“weight_lifting”, “tennis”, “football”])

grab the list of images in our dataset directory, then initialize

the list of data (i.e., images) and class images

print(“[INFO] loading images…”)

imagePaths = list(paths.list_images(args[“dataset”]))

data = []

labels = []

loop over the image paths

for imagePath in imagePaths:

extract the class label from the filename

label = imagePath.split(os.path.sep)[-2]

if the label of the current image is not part of of the labels

are interested in, then ignore the image

if label not in LABELS:

continue

load the image, convert it to RGB channel ordering, and resize

it to be a fixed 224x224 pixels, ignoring aspect ratio

image = cv2.imread(imagePath)

image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

image = cv2.resize(image, (224, 224))

update the data and labels lists, respectively

data.append(image)

labels.append(label)

定义类 LABELS 的集合。该集合中不存在的所有标签都将被排除在我们的数据集之外。为了节省训练时间,我们的数据集将只包含举重、网球和足球/足球。通过对 LABELS 集进行更改,您可以随意使用其他类。

初始化我们的数据和标签列表。

遍历所有 imagePath。

在循环中,首先我们从 imagePath 中提取类标签

忽略不在 LABELS 集合中的任何标签。

加载并预处理图像。预处理包括将 OpenCV 的颜色通道交换到 Keras 兼容性并将大小调整为 224×224px。在此处阅读有关调整 CNN 图像大小的更多信息。要了解有关预处理重要性的更多信息,请务必参阅使用 Python 进行计算机视觉深度学习。

然后分别将图像和标签添加到数据和标签列表中。

继续,我们将对我们的标签进行单热编码并分区我们的数据:

convert the data and labels to NumPy arrays

data = np.array(data)

labels = np.array(labels)

perform one-hot encoding on the labels

lb = LabelBinarizer()

labels = lb.fit_transform(labels)

partition the data into training and testing splits using 75% of

the data for training and the remaining 25% for testing

(trainX, testX, trainY, testY) = train_test_split(data, labels,

test_size=0.25, stratify=labels, random_state=42)

将我们的数据和标签列表转换为 NumPy 数组。

执行one-hot编码。one-hot编码是一种通过二进制数组元素标记活动类标签的方法。 例如,“足球”可能是 array([1, 0, 0]) 而“举重”可能是 array([0, 0, 1]) 。 请注意在任何给定时间只有一个类是“热的”。

按照4:1的比例,将我们的数据分成训练和测试部分。

初始化我们的数据增强对象:

initialize the training data augmentation object

trainAug = ImageDataGenerator(

rotation_range=30,

zoom_range=0.15,

width_shift_range=0.2,

height_shift_range=0.2,

shear_range=0.15,

horizontal_flip=True,

fill_mode=“nearest”)

initialize the validation/testing data augmentation object (which

we’ll be adding mean subtraction to)

valAug = ImageDataGenerator()

define the ImageNet mean subtraction (in RGB order) and set the

the mean subtraction value for each of the data augmentation

objects

mean = np.array([123.68, 116.779, 103.939], dtype=“float32”)

trainAug.mean = mean

valAug.mean = mean

初始化了两个数据增强对象——一个用于训练,一个用于验证。 在计算机视觉的深度学习中,几乎总是建议使用数据增强来提高模型泛化能力。

trainAug 对象对我们的数据执行随机旋转、缩放、移位、剪切和翻转。 您可以在此处阅读有关 ImageDataGenerator 和 fit 的更多信息。 正如我们上周强调的那样,请记住,使用 Keras,图像将即时生成(这不是附加操作)。

不会对验证数据 (valAug) 进行扩充,但我们将执行均值减法。

平均像素值,设置 trainAug 和 valAug 的均值属性,以便在训练/评估期间生成图像时进行均值减法。 现在,我们将执行我喜欢称之为“网络手术”的操作,作为微调的一部分:

load the ResNet-50 network, ensuring the head FC layer sets are left

off

baseModel = ResNet50(weights=“imagenet”, include_top=False,

input_tensor=Input(shape=(224, 224, 3)))

construct the head of the model that will be placed on top of the

the base model

headModel = baseModel.output

headModel = AveragePooling2D(pool_size=(7, 7))(headModel)

headModel = Flatten(name=“flatten”)(headModel)

headModel = Dense(512, activation=“relu”)(headModel)

headModel = Dropout(0.5)(headModel)

headModel = Dense(len(lb.classes_), activation=“softmax”)(headModel)

place the head FC model on top of the base model (this will become

the actual model we will train)

model = Model(inputs=baseModel.input, outputs=headModel)

loop over all layers in the base model and freeze them so they will

not be updated during the training process

for layer in baseModel.layers:

layer.trainable = False

加载用 ImageNet 权重预训练的 ResNet50,同时切掉网络的头部。

组装了一个新的 headModel 并将其缝合到 baseModel 上。

我们现在将冻结 baseModel,以便它不会通过反向传播进行训练。

让我们继续编译+训练我们的模型:

compile our model (this needs to be done after our setting our

layers to being non-trainable)

print(“[INFO] compiling model…”)

opt = SGD(lr=1e-4, momentum=0.9, decay=1e-4 / args[“epochs”])

model.compile(loss=“categorical_crossentropy”, optimizer=opt,

metrics=[“accuracy”])

train the head of the network for a few epochs (all other layers

are frozen) – this will allow the new FC layers to start to become

initialized with actual “learned” values versus pure random

print(“[INFO] training head…”)

H = model.fit(

x=trainAug.flow(trainX, trainY, batch_size=32),

steps_per_epoch=len(trainX) // 32,

validation_data=valAug.flow(testX, testY),

validation_steps=len(testX) // 32,

epochs=args[“epochs”])

以前,TensorFlow/Keras 需要使用一种名为 .fit_generator 的方法来完成数据增强。现在,.fit 方法也可以处理数据增强,从而使代码更加一致。这也适用于从 .predict_generator 到 .predict 的迁移。请务必查看我关于 fit 和 fit_generator 以及数据增强的文章。

使用随机梯度下降 (SGD) 优化器编译我们的模型,初始学习率为 1e-4,学习率衰减。我们使用“categorical_crossentropy”损失来训练多类。如果您只使用两个类,请务必使用“binary_crossentropy”损失。

在我们的模型上调用 fit_generator 函数用数据增强和均值减法训练我们的网络。 请记住,我们的 baseModel 已冻结,我们只训练头部。这被称为“微调”。要快速了解微调,请务必阅读我之前的文章。要更深入地了解微调,请获取使用 Python 进行计算机视觉深度学习的 Practitioner Bundle 的副本。

我们将通过评估我们的网络并绘制训练历史来开始总结:

evaluate the network

print(“[INFO] evaluating network…”)

predictions = model.predict(x=testX.astype(“float32”), batch_size=32)

print(classification_report(testY.argmax(axis=1),

predictions.argmax(axis=1), target_names=lb.classes_))

plot the training loss and accuracy

N = args[“epochs”]

plt.style.use(“ggplot”)

plt.figure()

plt.plot(np.arange(0, N), H.history[“loss”], label=“train_loss”)

plt.plot(np.arange(0, N), H.history[“val_loss”], label=“val_loss”)

plt.plot(np.arange(0, N), H.history[“accuracy”], label=“train_acc”)

plt.plot(np.arange(0, N), H.history[“val_accuracy”], label=“val_acc”)

plt.title(“Training Loss and Accuracy on Dataset”)

plt.xlabel(“Epoch #”)

plt.ylabel(“Loss/Accuracy”)

plt.legend(loc=“lower left”)

plt.savefig(args[“plot”])

为了使此绘图片段与 TensorFlow 2+ 兼容,更新了 H.history 字典键以完全拼出“accuracy”无“acc”(H.history[“val_accuracy”] 和 H.历史[“准确性”])。 “val”没有拼写为“validation”,这有点令人困惑; 我们必须学会热爱 API 并与之共存,并始终记住这是一项正在进行的工作,世界各地的许多开发人员都在为之做出贡献。

在我们在测试集上评估我们的网络并打印分类报告

之后,我们继续使用 matplotlib

绘制准确率/损失曲线。 该图通过第 164 行保存到磁盘。

最后将我们的模型和标签二值化器 (lb) 序列化到磁盘:

serialize the model to disk

print(“[INFO] serializing network…”)

model.save(args[“model”], save_format=“h5”)

serialize the label binarizer to disk

f = open(args[“label_bin”], “wb”)

f.write(pickle.dumps(lb))

f.close()

训练结果

===============================================================

在我们 使用我们的 CNN 对视频中的帧进行分类,然后) 利用我们的 CNN 进行视频分类之前,我们首先需要训练模型。

确保您已使用本教程的“下载”部分将源代码下载到此图像(以及下载运动类型数据集)。

从那里,打开一个终端并执行以下命令:

$ python train.py --dataset Sports-Type-Classifier/data --model model/activity.model \

–label-bin output/lb.pickle --epochs 50

[INFO] loading images…

[INFO] compiling model…

[INFO] training head…

Epoch 1/50

48/48 [==============================] - 10s 209ms/step - loss: 1.4184 - accuracy: 0.4421 - val_loss: 0.7866 - val_accuracy: 0.6719

Epoch 2/50

48/48 [==============================] - 10s 198ms/step - loss: 0.9002 - accuracy: 0.6086 - val_loss: 0.5476 - val_accuracy: 0.7832

Epoch 3/50

48/48 [==============================] - 9s 198ms/step - loss: 0.7188 - accuracy: 0.7020 - val_loss: 0.4690 - val_accuracy: 0.8105

Epoch 4/50

48/48 [==============================] - 10s 203ms/step - loss: 0.6421 - accuracy: 0.7375 - val_loss: 0.3986 - val_accuracy: 0.8516

Epoch 5/50

48/48 [==============================] - 10s 200ms/step - loss: 0.5496 - accuracy: 0.7770 - val_loss: 0.3599 - val_accuracy: 0.8652

Epoch 46/50

48/48 [==============================] - 9s 192ms/step - loss: 0.2066 - accuracy: 0.9217 - val_loss: 0.1618 - val_accuracy: 0.9336

Epoch 47/50

48/48 [==============================] - 9s 193ms/step - loss: 0.2064 - accuracy: 0.9204 - val_loss: 0.1622 - val_accuracy: 0.9355

Epoch 48/50

48/48 [==============================] - 9s 192ms/step - loss: 0.2092 - accuracy: 0.9217 - val_loss: 0.1604 - val_accuracy: 0.9375

Epoch 49/50

48/48 [==============================] - 9s 195ms/step - loss: 0.1935 - accuracy: 0.9290 - val_loss: 0.1620 - val_accuracy: 0.9375

Epoch 50/50

48/48 [==============================] - 9s 192ms/step - loss: 0.2109 - accuracy: 0.9164 - val_loss: 0.1561 - val_accuracy: 0.9395

[INFO] evaluating network…

precision recall f1-score support

football 0.93 0.96 0.95 196

tennis 0.92 0.92 0.92 179

weight_lifting 0.97 0.92 0.95 143

accuracy 0.94 518

macro avg 0.94 0.94 0.94 518

weighted avg 0.94 0.94 0.94 518

[INFO] serializing network…

image-20211029223546026

如您所见,在体育数据集上对 ResNet50 进行微调后,我们获得了约 94% 的准确率。 检查我们的模型目录,我们可以看到微调模型和标签二值化器已经序列化到磁盘:

使用 Keras 进行视频分类和滚动预测平均

=================================================================================

我们现在准备通过滚动预测精度使用 Keras 实现视频分类! 为了创建这个脚本,我们将利用视频的时间特性,特别是假设视频中的后续帧将具有相似的语义内容。 通过执行滚动预测准确性,我们将能够“平滑”预测并避免“预测闪烁”。 让我们开始吧——打开 predict_video.py 文件并插入以下代码:

import the necessary packages

from tensorflow.keras.models import load_model

from collections import deque

import numpy as np

import argparse

import pickle

import cv2

construct the argument parser and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument(“-m”, “–model”, required=True,

help=“path to trained serialized model”)

ap.add_argument(“-l”, “–label-bin”, required=True,

help=“path to label binarizer”)

ap.add_argument(“-i”, “–input”, required=True,

help=“path to our input video”)

ap.add_argument(“-o”, “–output”, required=True,

help=“path to our output video”)

ap.add_argument(“-s”, “–size”, type=int, default=128,

help=“size of queue for averaging”)

args = vars(ap.parse_args())

加载必要的包和模块。 特别是,我们将使用 Python 集合模块中的 deque 来协助我们的滚动平均算法。

然后,解析五个命令行参数,其中四个是必需的:

–model :从我们之前的训练步骤生成的输入模型的路径。

–label-bin :前一个脚本生成的序列化 pickle 格式标签二值化器的路径。

–input :用于视频分类的输入视频的路径。

–output :我们将保存到磁盘的输出视频的路径。

–size :滚动平均队列的最大大小(默认为 128)。 对于稍后的一些示例结果,我们将大小设置为 1,以便不执行平均。

有了我们的导入和命令行 args ,我们现在准备执行初始化:

load the trained model and label binarizer from disk

print(“[INFO] loading model and label binarizer…”)

model = load_model(args[“model”])

lb = pickle.loads(open(args[“label_bin”], “rb”).read())

initialize the image mean for mean subtraction along with the

predictions queue

mean = np.array([123.68, 116.779, 103.939][::1], dtype=“float32”)

Q = deque(maxlen=args[“size”])

加载我们的模型和标签二值化器。

然后设置我们的平均减法值。 我们将使用双端队列来实现我们的滚动预测平均。

我们的双端队列 Q 使用等于 args[“size”] 值的 maxlen 初始化。

让我们初始化我们的 cv2.VideoCapture 对象并开始循环视频帧:

initialize the video stream, pointer to output video file, and

frame dimensions

vs = cv2.VideoCapture(args[“input”])

writer = None

(W, H) = (None, None)

loop over frames from the video file stream

while True:

read the next frame from the file

(grabbed, frame) = vs.read()

if the frame was not grabbed, then we have reached the end

of the stream

if not grabbed:

break

if the frame dimensions are empty, grab them

if W is None or H is None:

(H, W) = frame.shape[:2]

抓取一个指向我们的输入视频文件流的指针。 我们使用 OpenCV 中的 VideoCapture 类从我们的视频流中读取帧。

然后,将我们的视频编写器和维度初始化为 None。

开始我们的视频分类 while 循环。

首先,我们抓取一个帧。 如果帧没有被抓取,那么我们已经到达了视频的结尾,此时我们将中断循环。

如果需要,然后设置我们的框架尺寸。 让我们预处理我们的框架:

clone the output frame, then convert it from BGR to RGB

ordering, resize the frame to a fixed 224x224, and then

perform mean subtraction

output = frame.copy()

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

frame = cv2.resize(frame, (224, 224)).astype(“float32”)

frame -= mean

我们的框架副本用于输出目的。

然后,我们使用与训练脚本相同的步骤对帧进行预处理,包括:

​ 交换颜色通道。

​ 调整为 224×224px。

​ 平均减法。

接下来是帧分类推理和滚动预测平均:

make predictions on the frame and then update the predictions

queue

preds = model.predict(np.expand_dims(frame, axis=0))[0]

Q.append(preds)

perform prediction averaging over the current history of

previous predictions

results = np.array(Q).mean(axis=0)

i = np.argmax(results)

label = lb.classes_[i]

对当前帧进行预测。 预测结果通过第 64 行添加到 Q。

从那里,对 Q 历史执行预测平均,从而为滚动平均值生成一个类标签。 分解后,这些线在平均预测中找到具有最大对应概率的标签。

现在我们有了结果标签,让我们注释我们的输出帧并将其写入磁盘:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
img

在这里插入图片描述

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

6381401c05e862fe4e9.png)

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
[外链图片转存中…(img-YU83GgSO-1712958403704)]

在这里插入图片描述

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-VOm3OSx0-1712958403704)]

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值