UCF101视频分类之CNN-LSTM-Code总结

'harvitronix/five-video-classification-methods'视频分类-Code总结

  • 环境要求
    • 准备工作
      • 提取视频帧
      • CNN提取视频帧特征
      • LSTM
        • 验证模型
          • 扩展

Code: https://github.com/harvitronix/five-video-classification-methods.

环境要求

requirements:

Keras>=2.0.2
numpy>=1.12.1
pandas>=0.19.2
tqdm>=4.11.2
matplotlib>=2.0.0
Pillow>=2.1.0
h5py>=2.7.0

项目文件目录概览:
UCF101视频分类之CNN-LSTM-Code总结_第1张图片

准备工作

1)下载UCF101数据集压缩包并减压至data文件夹。
2)在data文件夹创建train、test 、sequences、checkpoints四个文件。

提取视频帧

1、UCF101数据集是由101类视频组成的,首先通过运行1_move_files.py将101类视频按照ucfTrainTestlist文件夹下的数据标签将101视频分别移至train、test文件夹。

Lable:
UCF101视频分类之CNN-LSTM-Code总结_第2张图片
这里有个坑!!
1_move_files.py 第58行:

            
            if not os.path.exists(filename):
                print("Can't find %s to move. Skipping." % (filename))
                continue

            # Move it.
            dest = os.path.join(group, classname, filename)
            print("Moving %s to %s" % (filename, dest))
            os.rename(filename, dest)

    print("Done.")

未将UCF101数据集读取!
UCF101视频分类之CNN-LSTM-Code总结_第3张图片
修改后的代码:

  			filename_input = os.path.join('UCF-101', classname, filename)
            if not os.path.exists(filename_input):
                print("Can't find %s to move. Skipping." % (filename))
                continue

            # Move it.
            dest = os.path.join(group, classname, filename)
            print("Moving %s to %s" % (filename, dest))
            os.rename(filename_input, dest)

    print("Done.")

2、现在通过运行2_extract_files.py提取train、test文件夹中视频的视频帧,并生成一个CSV文件 。该CSV文件为之后特征提取及网络训练时数据读取提供帮助:

    def get_data():
        """Load our data from file."""
        with open(os.path.join('data', 'data_file.csv'), 'r') as fin:
            reader = csv.reader(fin)
            data = list(reader)

        return data

CNN提取视频帧特征

通过运行extract_features.py提取视频帧特征。

seq_length = 40
class_limit = 101

seq_length:每个视频段考虑的视频帧数目
class_limit:限制分类数
举个例子:一个视频段input_list有240帧,seq_length = 40,首先判断input_list是否大于seq_length即 assert len(input_list) >= seq_length。然后将input_list与seq_length做地板除即: skip = len(input_list) // size,本例中skip = 6,即每隔6帧从input_list中取一帧以列表的形式保存到output即:output = [input_list[i] for i in range(0, len(input_list), skip)],最终取得40帧。

 def rescale_list(input_list, size):
        assert len(input_list) >= size
        
        skip = len(input_list) // size
        
        output = [input_list[i] for i in range(0, len(input_list), skip)]

        return output[:size]

在Imagenet上预训练好的InceptionV3卷积网络提取这40帧特征作为该视频段的特征。并将特征保存在sequences文件夹,numpy会自动在末尾添加 .npy

path = os.path.join('data', 'sequences', video[2] + '-' + str(seq_length) + \
        '-features')

LSTM

将提取到的序列特征送入LSTM网络进行训练。通过运行 train.py生成 .hdf5文件,并将模型保存到checkpoints文件夹,并且会在logs文件夹生成一个 .log 训练日志文件,用来可视化训练过程中acc与loss的变化。

获取由CNN提取的序列特征:

 def get_extracted_sequence(self, data_type, sample):
        """Get the saved extracted features."""
        filename = sample[2]
        path = os.path.join(self.sequence_path, filename + '-' + str(self.seq_length) + \'-' + data_type + '.npy')
        if os.path.isfile(path):
            return np.load(path)
        else:
            return None

LSTM网络模型:

    def lstm(self):
        model = Sequential()
        model.add(LSTM(2048, return_sequences=False,
                       input_shape=self.input_shape,
                       dropout=0.5))
        model.add(Dense(512, activation='relu'))
        model.add(Dropout(0.5))
        model.add(Dense(self.nb_classes, activation='softmax'))

        return model

用来可视化训练过程的plot_trainlog.py:

import csv
import matplotlib.pyplot as plt

def main(training_log):
    with open(training_log) as fin:
        reader = csv.reader(fin)
        next(reader, None)  # skip the header
        accuracies = []
        Val_acc = []
        cnn_benchmark = []  # this is ridiculous
        for epoch,acc,loss,val_acc,val_loss in reader:
            accuracies.append(float(acc))
            Val_acc.append(float(val_acc))
            cnn_benchmark.append(0.65)  # ridiculous

        plt.plot(accuracies)
        plt.plot(Val_acc)
        plt.plot(cnn_benchmark)
        plt.show()

if __name__ == '__main__':
    training_log = 'data/logs/lstm-training-1617251893.3342032.log'
    main(training_log)

绿线:cnn_benchmark
橘黄线:Val_acc
蓝线:accuracies
UCF101视频分类之CNN-LSTM-Code总结_第4张图片

验证模型

通过运行validate_rnn.py将保存在checkpoints文件夹的模型加载进来验证模型准确度。结果如图:
UCF101视频分类之CNN-LSTM-Code总结_第5张图片

扩展

若要将一段视频进行分段处理,十帧作为一个序列,首先送入CNN提取基础特征,后送入LSTM提取时间-空间特征,会遇到什么问题?能否完成视频分段任务?是否过拟合?模型鲁棒性如何?

你可能感兴趣的:(深度学习,python,人工智能)