本文共 4970 字,大约阅读时间需要 16 分钟。
计算机视觉领域的应用前景无限,视频分类作为其中的一个重要任务,正在受到越来越多的关注。视频数据与图像数据相比,具有动态特性,但在核心处理方法上并没有本质区别。因此,我们可以借鉴图像分类的成功经验,利用计算机视觉和深度学习技术来构建视频分类模型。
在本文中,我们将使用Python语言,基于UCF101动作识别数据集,构建一个视频分类模型。这个数据集包含13,320个视频片段,涵盖101个不同的类别。我们将从数据集准备、模型设计到训练与评估,逐步展开视频分类任务。
视频可以看作是一组按时间顺序排列的图像帧(frames)。每一帧都可以通过类似图像分类的方法进行处理。因此,视频分类的核心步骤包括:
UCF101数据集的视频分组特性使得训练和测试集的划分尤为重要。同一组的视频通常来自于同一个较长的视频,因此在训练集和测试集中共享这些视频可以显著提升模型性能。
UCF101数据集的视频文件采用RAR格式下载后,需要先解压。创建一个新文件夹“Video”来存储所有视频。使用以下命令提取视频文件:
unrar e UCF101.rar Videos/
官方文档指出,训练集和测试集的视频分组方式至关重要。因此,我们将按照官方建议使用提供的训练/测试集划分文件,将视频文件分配到训练集和测试集中。
训练集和测试集的视频文件分别存放在不同的文件夹中。接下来,我们将创建包含视频文件名的DataFrame,并为每个视频添加相应的标签。
# 读取训练集合的视频文件名with open("trainlist01.txt", "r") as f: temp = f.read()train_videos = temp.split('\n')# 创建训练集 DataFrametrain = pd.DataFrame()train["video_name"] = train_videos[:-1]# 为训练集添加标签train_video_tags = []for i in range(train.shape[0]): tag = train["video_name"][i].split('/')[0] train_video_tags.append(tag)train["tags"] = train_video_tags# 同样处理测试集with open("testlist01.txt", "r") as f: temp = f.read()test_videos = temp.split('\n')# 创建测试集 DataFrametest = pd.DataFrame()test["video_name"] = test_videos[:-1]# 为测试集添加标签test_video_tags = []for i in range(test.shape[0]): tag = test["video_name"][i].split('/')[0] test_video_tags.append(tag)test["tags"] = test_video_tags 接下来,我们需要从训练集的视频中提取帧,并将这些帧与对应的标签一起存储。为此,我们创建一个名为"train_1"的文件夹,存储所有提取的帧。
# 提取训练集视频的帧for i in tqdm(range(train.shape[0])): video_file = train["video_name"][i] cap = cv2.VideoCapture(f'UCF/{video_file.split("_")[0].split("/")[1]}') frame_rate = cap.get(cv2.CAP_PROP_FRAME_COUNT) // cap.get(cv2.CAP_PROP_FPS) frame_id = 1 while cap.isOpened(): ret, frame = cap.read() if not ret: break if frame_id % math.floor(frame_rate) == 0: # 保存帧 filename = f'train_1/{video_file.split("_")[0].split("/")[1]}_frame{frame_id}.jpg' cv2.imwrite(filename, frame) frame_id += 1 cap.release()# 将提取的帧存储到 CSV 文件中images = glob("train_1/*.jpg")train_image = []train_class = []for i in range(len(images)): image_name = images[i].split('/')[1] train_image.append(image_name) class_name = image_name.split('_')[1] train_class.append(class_name)# 创建 DataFrame 并保存到 CSV 文件train_data = pd.DataFrame({ 'image': train_image, 'class': train_class})train_data.to_csv('UCF/train_new.csv', index=False) 为了构建视频分类模型,我们使用预训练的VGG-16模型,并对其进行微调。模型结构如下:
from keras import backend as Kfrom keras.layers import Dense, Dropout, InputLayer, Flattenfrom keras.layers import Conv2D, MaxPooling2D, GlobalMaxPooling2Dfrom keras.preprocessing import image# 创建预训练的 VGG-16 模型base_model = VGG16(weights='imagenet', include_top=False)base_model.summary()# 从训练集提取特征X_train = base_model.predict(train_images)X_train = X_train.reshape(X_train.shape[0], 7 * 7 * 512)X_train = X_train / X_train.max()# 创建模型架构model = Sequential()model.add(Dense(1024, activation='relu', input_shape=(25088,)))model.add(Dropout(0.5))model.add(Dense(512, activation='relu'))model.add(Dropout(0.5))model.add(Dense(256, activation='relu'))model.add(Dropout(0.5))model.add(Dense(128, activation='relu'))model.add(Dropout(0.5))model.add(Dense(101, activation='softmax'))
# 编译模型model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])# 训练模型model.fit(X_train, y_train, epochs=200, validation_data=(X_test, y_test), callbacks=[mcp_save], batch_size=128)
在评估阶段,我们使用测试集对模型进行验证,并通过准确率衡量模型性能。UCF101数据集的官方准确率为43.9%,而我们的模型在测试集上达到了44.8%的准确率。
from sklearn.metrics import accuracy_score# 加载预测模型base_model = VGG16(weights='imagenet', include_top=False)model.load_weights("weights.hdf5")model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])# 读取测试集数据test_videos = test_videos[:-1]# 提取测试集视频的帧for i in tqdm(range(len(test_videos))): video_file = test_videos[i] cap = cv2.VideoCapture(f'UCF/{video_file.split("_")[0].split("/")[1]}') frame_id = 1 while cap.isOpened(): ret, frame = cap.read() if not ret: break if frame_id % math.floor(frame_rate) == 0: # 保存帧 filename = f'temp/_frame{frame_id}.jpg' cv2.imwrite(filename, frame) frame_id += 1 cap.release()# 读取预测的帧 prediction_images = np.array(prediction_images) prediction_images = base_model.predict(prediction_images) prediction_images = prediction_images.reshape(prediction_images.shape[0], 7 * 7 * 512) prediction = model.predict_classes(prediction_images)# 计算准确率accuracy = accuracy_score(y_pred, y_true) * 100print(f"准确率:{accuracy:.4f}%") 通过本文的步骤,我们成功构建并训练了一个视频分类模型,能够对UCF101数据集中的视频进行分类。虽然当前的准确率为44.8%,但我们仍有提升空间。未来的改进方向包括引入更先进的网络架构(如3D卷积网络)和更高效的数据增强方法,以进一步提高分类性能。
如果你对视频分类感兴趣,可以继续探索视频序列建模等更复杂的方法。我们也建议你关注PyTorch等其他深度学习框架的应用,毕竟灵活性和可扩展性是现代深度学习框架的重要特点。
转载地址:http://npofk.baihongyu.com/