视频分类数据集转图片分类数据集在vgg16上的分类效果

数据集处理 

最近在做的实验需要将视频分类数据集抽帧变成图片分类的数据集,然后放入已有模型进行训练和评估。

该篇参考博文详细介绍了搭建视频分类模型的过程,但主要以处理数据集为主。所以我的实验借鉴了这篇博文对数据集处理的方法,但对个别内容有修改,并补充了一些理解。

便于处理,只取了UCF101的前10个类别,主要为了测试视频抽帧处理成图片分类数据集的效果,暂不考虑其他因素。

要点一:给每一个视频加标签

大佬博客是按照视频类名划分出标签的,但实际也可以按照视频后面给出的数字划分,这样,后面就不用单独将文字标签转为数字标签了。

大佬划分:

# 为训练视频创建标签
train_video_tag = []#标签列表
for i in range(train.shape[0]):#shape[0],遍历每条视频名(从后往前)
    train_video_tag.append(train['video_name'][i].split('/')[0])#按照数据帧第['video_name']列每一行的“/”划分取第0维并加入标签列表
    
train['tag'] = train_video_tag#给数据帧增加一列并起名类别,把标签列表赋值给这列
train.head()#显示前5行

效果:

按数字划分:

# 为训练视频创建标签
train_video_tag = []#标签列表
for i in range(train.shape[0]):
    train_video_tag.append(train['video_name'][i].split('avi')[1])
    
train['tag'] = train_video_tag
train.head()

效果:

我觉得这里就是看自己需要选择,而我绕了一圈用了大佬的方法。

要点二:从训练组视频里提取帧

这块是核心代码,但是博主代码的缩进问题还是什么原因一直出不来结果。于是我整个换掉了,非常成功。参考

# 保存从训练视频中提取的帧
for i in tqdm(range(train.shape[0])):#tqmd进度条提取过程
    count = 0
    videoFile = train['trainvideo_name'][i]#数据帧里视频名

    # 全局变量
    VIDEO_PATH = 'Desktop/UCF10/videos_10/'+videoFile.split(' ')[0]# 视频地址,用空格划分出了视频名
    EXTRACT_FOLDER = 'Desktop/UCF10/train_1/' # 存放帧图片的位置 
    EXTRACT_FREQUENCY = 50 # 帧提取频率(每秒划过多少帧,一个视频是25帧/s,故抽到的帧数少)


    def extract_frames(video_path, dst_folder, index):
        # 主操作
        import cv2
        video = cv2.VideoCapture()#打开视频或摄像头等
        if not video.open(video_path):
            print("can not open the video")
            exit(1)
        count = 1
        while True:
            _, frame = video.read()#按帧读取视频
            #视频读完退出
            if frame is None:
                break
            #每过50帧抽取一张
            if count % EXTRACT_FREQUENCY == 0:
                #帧的存储格式,根据需要改,最好和视频名保持一致
                save_path ='Desktop/UCF10/train_1/'+videoFile.split('/')[1].split(' ')[0] +"_frame%d.jpg" % count
                cv2.imwrite(save_path, frame)#存帧
            count += 1
        video.release()
        # 打印出所提取帧的总数
        print("Totally save {:d} pics".format(index-1))

    def main():
        '''
        批量生成图片,可以不要这块代码
        '''
    #     # 递归删除之前存放帧图片的文件夹,并新建一个
    #     import shutil
    #     try:
    #         shutil.rmtree(EXTRACT_FOLDER)
    #     except OSError:
    #         pass
    #     import os
    #     os.mkdir(EXTRACT_FOLDER)
        # 抽取帧图片,并保存到指定路径
        extract_frames(VIDEO_PATH, EXTRACT_FOLDER, 1)

    if __name__ == '__main__':
        main()

效果:

要点三:把帧的名称和相对应的标签保存在.csv文件里。创建这个文件可以帮助我们读取在下一阶段要用到的帧

from tqdm import tqdm
from glob import glob
import pandas as pd
# 获得所有图像的名称
images = glob("Desktop/UCF10/train_1_50/*.jpg")
train_image = []
train_class = []
for i in tqdm(range(len(images))):
    # 创建图像的名称
    train_image.append(images[i].split('50\\')[1])
    # 创建图像的标签
    train_class.append(images[i].split('v_')[1].split('_')[0])

    # 将图像和它们的标签保存到数据帧里
    train_data = pd.DataFrame()
    train_data['image'] = train_image
    train_data['class'] = train_class
    # 将数据帧转为csv.文件
    train_data.to_csv('Desktop/UCF10/train_new.csv',header=True, index=False)

这步在创建图像和标签名称那里的字符串划分可以适当修改,我用大佬的划分不出来。。。

读取该csv文件:

import pandas as pd
train = pd.read_csv('Desktop/UCF10/train_new.csv')
train.head()

效果:

要点四:利用这个.csv文件,提取出帧储存为一个Numpy 数组。这里做了改进多张图片转成一个.npy文件存储

要点五:划分训练集验证集及相应标签

import pandas as pd
from sklearn.model_selection import train_test_split

#读取存有图片名和对应类别名的.csv文件
train = pd.read_csv('train_new.csv')
# 区分目标
y = train['class']
# 创建训练集和验证集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2, stratify = y)

 之后大佬的文章是搭建vgg16的分类模型,并给训练集和验证集创建了目标变量的数据列。但我只需要数据集,所以把上面的结果保存即可。

保存训练集和验证集

import numpy as np
np.save("Desktop/UCF10/train1/Xtr01", X_train)
np.save("Desktop/UCF10/train1/Ytr01", y_train)
np.save("Desktop/UCF10/test1/Xte01",  X_test)
np.save("Desktop/UCF10/test1/Yte01", y_test)

最后,将文字标签转换成数字标签,如果划分标签的时候按照数字划分,就不用这一步。

数据集放入模型测试

已有vgg16模型的超参设置是用来跑cifar_10的,learning_rate = 0.02,batch_size = 100,epoch = 1,momentuma = 0.5

但输入这个处理过的数据集,结果,损失是nan,迭代一次精度只有11%左右,而且每次测试精度都一模一样。

于是调整超参数:learning_rate = 0.002,batch_size = 20,epoch = 1,momentuma = 0.5

得到测试的损失和精度分别为:

然后可以查看下真实标签和预测标签的结果:

查看实际上没什么意义,老师说看标签对不对,其实看测试精度就可以了。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
以下是使用PyTorch实现VGG16对Fashion MNIST数据集进行分类的代码示例: ``` import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as datasets import torchvision.transforms as transforms # Define the VGG16 model class VGG16(nn.Module): def __init__(self): super(VGG16, self).__init__() self.features = nn.Sequential( nn.Conv2d(1, 64, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(64, 64, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(64, 128, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(128, 128, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(128, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(256, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(512, 512, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2) ) self.avgpool = nn.AdaptiveAvgPool2d((7, 7)) self.classifier = nn.Sequential( nn.Linear(512 * 7 * 7, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 10) ) def forward(self, x): x = self.features(x) x = self.avgpool(x) x = torch.flatten(x, 1) x = self.classifier(x) return x # Define the training parameters batch_size = 64 learning_rate = 0.0001 num_epochs = 10 # Load Fashion MNIST dataset train_dataset = datasets.FashionMNIST(root='./data', train=True, download=True, transform=transforms.ToTensor()) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_dataset = datasets.FashionMNIST(root='./data', train=False, download=True, transform=transforms.ToTensor()) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False) # Initialize the model, loss function and optimizer model = VGG16() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) # Train the model for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): # Forward pass outputs = model(images) loss = criterion(outputs, labels) # Backward and optimize optimizer.zero_grad() loss.backward() optimizer.step() # Print training progress if (i+1) % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, len(train_loader), loss.item())) # Test the model model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the model on the test images: {:.4f}%'.format(100 * correct / total)) ``` 此代码使用Fashion MNIST数据集进行训练和测试,与常见的MNIST数据集相似,但包含更多的类别和更复杂的图像。该模型的训练和测试代码与标准的PyTorch代码相似,只是使用了VGG16模型进行分类

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醪糟小丸子

小小帮助,不足挂齿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值