TensorFlow 1.x 深度学习秘籍:1~5(3)https://developer.aliyun.com/article/1426764
使用膨胀的卷积网络,WaveNet 和 NSynth 生成音乐
WaveNet 是用于生成原始音频波形的深度生成模型。 Google DeepMind 已引入了这一突破性技术,以教授如何与计算机通话。 结果确实令人印象深刻,在网上可以找到合成语音的示例,计算机可以在其中学习如何与名人的声音(例如 Matt Damon)交谈。
因此,您可能想知道为什么学习合成音频如此困难。 嗯,我们听到的每个数字声音都是基于每秒 16,000 个样本(有时是 48,000 个或更多),并且要建立一个预测模型,在此模型中,我们学会根据以前的所有样本来复制样本是一个非常困难的挑战。 尽管如此,仍有实验表明,WaveNet 改进了当前最先进的文本转语音(TTS)系统,使美国英语和中文普通话与人声的差异降低了 50%。
更酷的是,DeepMind 证明 WaveNet 也可以用于向计算机教授如何产生乐器声音(例如钢琴音乐)。
现在为一些定义。 TTS 系统通常分为两个不同的类别:
- 串联 TTS,其中单个语音语音片段首先被存储,然后在必须重现语音时重新组合。 但是,该方法无法扩展,因为可能只重现存储的语音片段,并且不可能重现新的扬声器或不同类型的音频而不从一开始就记住这些片段。
- 参数化 TTS,在其中创建一个模型来存储要合成的音频的所有特征。 在 WaveNet 之前,参数 TTS 生成的音频不如串联 TTS 生成的音频自然。 WaveNet 通过直接对音频声音的产生进行建模,而不是使用过去使用的中间信号处理算法,从而改善了现有技术。
原则上,WaveNet 可以看作是一维卷积层的栈(我们已经在第 4 章中看到了图像的 2D 卷积),步幅恒定为 1,没有池化层。 请注意,输入和输出在构造上具有相同的尺寸,因此卷积网络非常适合对顺序数据(例如音频)建模。 但是,已经显示出,为了在输出神经元中的接收场达到较大的大小,有必要使用大量的大型过滤器或过分增加网络的深度。 请记住,一层中神经元的接受场是前一层的横截面,神经元从该层提供输入。 因此,纯卷积网络在学习如何合成音频方面不是那么有效。
WaveNet 之外的主要直觉是所谓的因果因果卷积(有时称为原子卷积),这仅意味着在应用卷积层的滤波器时会跳过某些输入值。 Atrous 是法语表述为 à trous 的混蛋,意思是带有孔的。 因此,AtrousConvolution 是带孔的卷积。例如,在一个维度中,尺寸为 3 且扩张为 1 的滤波器w
将计算出以下总和。
简而言之,在 D 扩散卷积中,步幅通常为 1,但是没有任何东西可以阻止您使用其他步幅。 下图给出了一个示例,其中膨胀(孔)尺寸增大了 0、1、2:
扩张网络的一个例子
由于采用了引入“空洞”的简单思想,可以在不具有过多深度网络的情况下,使用指数级增长的滤波器堆叠多个膨胀的卷积层,并学习远程输入依赖项。
因此,WaveNet 是一个卷积网络,其中卷积层具有各种膨胀因子,从而使接收场随深度呈指数增长,因此有效覆盖了数千个音频时间步长。
当我们训练时,输入是从人类扬声器录制的声音。 波形被量化为固定的整数范围。 WaveNet 定义了一个初始卷积层,仅访问当前和先前的输入。 然后,有一堆散布的卷积网络层,仍然仅访问当前和以前的输入。 最后,有一系列密集层结合了先前的结果,然后是用于分类输出的 softmax 激活函数。
在每个步骤中,都会从网络预测一个值,并将其反馈到输入中。 同时,为下一步计算新的预测。 损失函数是当前步骤的输出与下一步的输入之间的交叉熵。
NSynth是 Google Brain 集团最近发布的 WaveNet 的改进版本,其目的不是查看因果关系,而是查看输入块的整个上下文。 神经网络是真正的,复杂的,如下图所示,但是对于本介绍性讨论而言,足以了解该网络通过使用基于减少编码/解码过程中的错误的方法来学习如何再现其输入。 阶段:
准备
对于本秘籍,我们不会编写代码,而是向您展示如何使用一些在线可用的代码和一些不错的演示,您可以从 Google Brain 找到。 有兴趣的读者还可以阅读以下文章:《使用 WaveNet 自编码器的音符的神经音频合成》(杰西·恩格尔,辛琼·雷斯尼克,亚当·罗伯茨,桑德·迪勒曼,道格拉斯·埃克,卡伦·西蒙扬,穆罕默德·诺鲁兹,4 月 5 日 2017)。
操作步骤
我们按以下步骤进行:
- 通过创建单独的 conda 环境来安装 NSynth。 使用支持 Jupyter Notebook 的 Python 2.7 创建并激活 Magenta conda 环境:
conda create -n magenta python=2.7 jupyter source activate magenta
- 安装
magenta
PIP 包和librosa
(用于读取音频格式):
pip install magenta pip install librosa
import os import numpy as np import matplotlib.pyplot as plt from magenta.models.nsynth import utils from magenta.models.nsynth.wavenet import fastgen from IPython.display import Audio %matplotlib inline %config InlineBackend.figure_format = 'jpg'
- 然后,我们加载从互联网下载的演示声音,并将其放置在与笔记本计算机相同的目录中。 这将在约 2.5 秒内将 40,000 个样本加载到计算机中:
# from https://www.freesound.org/people/MustardPlug/sounds/395058/ fname = '395058__mustardplug__breakbeat-hiphop-a4-4bar-96bpm.wav' sr = 16000 audio = utils.load_audio(fname, sample_length=40000, sr=sr) sample_length = audio.shape[0] print('{} samples, {} seconds'.format(sample_length, sample_length / float(sr)))
- 下一步是使用从互联网下载的预先训练的 NSynth 模型以非常紧凑的表示形式对音频样本进行编码。 每四秒钟音频将为我们提供
78 x 16
尺寸的编码,然后我们可以对其进行解码或重新合成。 我们的编码是张量(#files=1 x 78 x 16
):
%time encoding = fastgen.encode(audio, 'model.ckpt-200000', sample_length) INFO:tensorflow:Restoring parameters from model.ckpt-200000 CPU times: user 1min 4s, sys: 2.96 s, total: 1min 7s Wall time: 25.7 s print(encoding.shape) (1, 78, 16)
- 让我们保存以后将用于重新合成的编码。 另外,让我们用图形表示来快速查看编码形状是什么,并将其与原始音频信号进行比较。 如您所见,编码遵循原始音频信号中呈现的节拍:
np.save(fname + '.npy', encoding) fig, axs = plt.subplots(2, 1, figsize=(10, 5)) axs[0].plot(audio); axs[0].set_title('Audio Signal') axs[1].plot(encoding[0]); axs[1].set_title('NSynth Encoding')
我们观察到以下音频信号和 Nsynth 编码:
- 现在,让我们对刚刚产生的编码进行解码。 换句话说,我们试图从紧凑的表示中再现原始音频,目的是理解重新合成的声音是否类似于原始声音。 确实,如果您运行实验并聆听原始音频和重新合成的音频,它们听起来非常相似:
%time fastgen.synthesize(encoding, save_paths=['gen_' + fname], samples_per_save=sample_length)
工作原理
WaveNet 是一种卷积网络,其中卷积层具有各种扩张因子,从而使接收场随深度呈指数增长,因此有效覆盖了数千个音频时间步长。 NSynth 是 WaveNet 的演进,其中原始音频使用类似 WaveNet 的处理进行编码,以学习紧凑的表示形式。 然后,使用这种紧凑的表示来再现原始音频。
更多
一旦我们学习了如何通过膨胀卷积创建音频的紧凑表示形式,我们就可以玩这些学习并从中获得乐趣。 您会在互联网上找到非常酷的演示:
- 例如,您可以看到模型如何学习不同乐器的声音:
- 然后,您将看到如何将在一个上下文中学习的一个模型在另一个上下文中重新组合。 例如,通过更改说话者身份,我们可以使用 WaveNet 以不同的声音说同一件事。
- 另一个非常有趣的实验是学习乐器模型,然后以一种可以重新创建以前从未听说过的新乐器的方式对其进行重新混合。 这真的很酷,它为通往新的可能性开辟了道路,坐在我里面的前电台 DJ 无法抗拒超级兴奋。 例如,在此示例中,我们将西塔琴与电吉他结合在一起,这是一种很酷的新乐器。 不够兴奋? 那么,如何将弓弦低音与狗的吠声结合起来呢?玩得开心!:
回答有关图像的问题(可视化问答)
在本秘籍中,我们将学习如何回答有关特定图像内容的问题。 这是一种强大的 Visual Q&A,它结合了从预先训练的 VGG16 模型中提取的视觉特征和词聚类(嵌入)的组合。 然后将这两组异类特征组合成一个网络,其中最后一层由密集和缺失的交替序列组成。 此秘籍适用于 Keras 2.0+。
因此,本秘籍将教您如何:
- 从预先训练的 VGG16 网络中提取特征。
- 使用预构建的单词嵌入将单词映射到相邻相似单词的空间中。
- 使用 LSTM 层构建语言模型。 LSTM 将在第 6 章中讨论,现在我们将它们用作黑盒。
- 组合不同的异构输入特征以创建组合的特征空间。 对于此任务,我们将使用新的 Keras 2.0 函数式 API。
- 附加一些其他的密集和丢弃层,以创建多层感知机并增强我们的深度学习网络的功能。
为了简单起见,我们不会在 5 中重新训练组合网络,而是使用已经在线提供的预先训练的权重集。 有兴趣的读者可以在由 N 个图像,N 个问题和 N 个答案组成的自己的训练数据集上对网络进行再训练。 这是可选练习。 该网络的灵感来自《VQA:视觉问题解答》(Aishwarya Agrawal,Jiasen Lu,Stanislaw Antol,Margaret Mitchell,C.Lawrence Zitnick,Dhruv Batra,Devi Parikh,2015 年):
在视觉问题回答论文中看到的 Visual Q&A 示例
我们这种情况的唯一区别是,我们将图像层产生的特征与语言层产生的特征连接起来。
操作步骤
我们可以按照以下步骤进行操作:
- 加载秘籍所需的所有 Keras 模块。 其中包括用于词嵌入的 spaCy,用于图像特征提取的 VGG16 和用于语言建模的 LSTM。 其余的几个附加模块非常标准:
%matplotlib inline import os, argparse import numpy as np import cv2 as cv2 import spacy as spacy import matplotlib.pyplot as plt from keras.models import Model, Input from keras.layers.core import Dense, Dropout, Reshape from keras.layers.recurrent import LSTM from keras.layers.merge import concatenate from keras.applications.vgg16 import VGG16 from keras.preprocessing import image from keras.applications.vgg16 import preprocess_input from sklearn.externals import joblib import PIL.Image
- 定义一些常量。 请注意,我们假设我们的问题语料库具有
max_length_questions = 30
,并且我们知道我们将使用 VGG16 提取 4,096 个描述输入图像的特征。 另外,我们知道单词嵌入在length_feature_space = 300
的空间中。 请注意,我们将使用从互联网下载的一组预训练权重:
# mapping id -> labels for categories label_encoder_file_name = '/Users/gulli/Books/TF/code/git/tensorflowBook/Chapter5/FULL_labelencoder_trainval.pkl' # max length across corpus max_length_questions = 30 # VGG output length_vgg_features = 4096 # Embedding outout length_feature_space = 300 # pre-trained weights VQA_weights_file = '/Users/gulli/Books/TF/code/git/tensorflowBook/Chapter5/VQA_MODEL_WEIGHTS.hdf5'
3.使用 VGG16 提取特征。 请注意,我们从 fc2 层中明确提取了它们。 给定输入图像,此函数返回 4,096 个特征:
'''image features''' def get_image_features(img_path, VGG16modelFull): '''given an image returns a tensor with (1, 4096) VGG16 features''' # Since VGG was trained as a image of 224x224, every new image # is required to go through the same transformation img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) # this is required because of the original training of VGG was batch # even if we have only one image we need to be consistent x = np.expand_dims(x, axis=0) x = preprocess_input(x) features = VGG16modelFull.predict(x) model_extractfeatures = Model(inputs=VGG16modelFull.input, outputs=VGG16modelFull.get_layer('fc2').output) fc2_features = model_extractfeatures.predict(x) fc2_features = fc2_features.reshape((1, length_vgg_features)) return fc2_features
请注意,VGG16 的定义如下:
Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) (None, 224, 224, 3) 0 _________________________________________________________________ block1_conv1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ block1_conv2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ block1_pool (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ block2_conv1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ block2_conv2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ block2_pool (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ block3_conv1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ block3_conv2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_conv3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ block3_pool (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ block4_pool (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ block5_pool (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc1 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc2 (Dense) (None, 4096) 16781312 _________________________________________________________________ predictions (Dense) (None, 1000) 4097000 ================================================================= Total params: 138,357,544 Trainable params: 138,357,544 Non-trainable params: 0 _________________________________________
- 使用 spaCy 获取单词嵌入,并将输入的问题映射到一个空格(
max_length_questions, 300
),其中max_length_questions
是我们语料库中问题的最大长度,而 300 是 spaCy 产生的嵌入的尺寸。 在内部,spaCy 使用一种称为 gloVe 的算法。 gloVe 将给定令牌简化为 300 维表示。 请注意,该问题使用右 0 填充填充到max_lengh_questions
:
'''embedding''' def get_question_features(question): ''' given a question, a unicode string, returns the time series vector with each word (token) transformed into a 300 dimension representation calculated using Glove Vector ''' word_embeddings = spacy.load('en', vectors='en_glove_cc_300_1m_vectors') tokens = word_embeddings(question) ntokens = len(tokens) if (ntokens > max_length_questions) : ntokens = max_length_questions question_tensor = np.zeros((1, max_length_questions, 300)) for j in xrange(len(tokens)): question_tensor[0,j,:] = tokens[j].vector return question_tensor
- 使用先前定义的图像特征提取器加载图像并获取其显着特征:
image_file_name = 'girl.jpg' img0 = PIL.Image.open(image_file_name) img0.show() #get the salient features model = VGG16(weights='imagenet', include_top=True) image_features = get_image_features(image_file_name, model) print image_features.shape
- 使用先前定义的句子特征提取器,编写一个问题并获得其显着特征:
question = u"Who is in this picture?" language_features = get_question_features(question) print language_features.shape
- 将两组异类特征组合为一个。 在这个网络中,我们有三个 LSTM 层,这些层将考虑我们语言模型的创建。 注意,LSTM 将在第 6 章中详细讨论,目前我们仅将它们用作黑匣子。 最后的 LSTM 返回 512 个特征,这些特征随后用作一系列密集层和缺失层的输入。 最后一层是具有 softmax 激活函数的密集层,其概率空间为 1,000 个潜在答案:
'''combine''' def build_combined_model( number_of_LSTM = 3, number_of_hidden_units_LSTM = 512, number_of_dense_layers = 3, number_of_hidden_units = 1024, activation_function = 'tanh', dropout_pct = 0.5 ): #input image input_image = Input(shape=(length_vgg_features,), name="input_image") model_image = Reshape((length_vgg_features,), input_shape=(length_vgg_features,))(input_image) #input language input_language = Input(shape=(max_length_questions,length_feature_space,), name="input_language") #build a sequence of LSTM model_language = LSTM(number_of_hidden_units_LSTM, return_sequences=True, name = "lstm_1")(input_language) model_language = LSTM(number_of_hidden_units_LSTM, return_sequences=True, name = "lstm_2")(model_language) model_language = LSTM(number_of_hidden_units_LSTM, return_sequences=False, name = "lstm_3")(model_language) #concatenate 4096+512 model = concatenate([model_image, model_language]) #Dense, Dropout for _ in xrange(number_of_dense_layers): model = Dense(number_of_hidden_units, kernel_initializer='uniform')(model) model = Dropout(dropout_pct)(model) model = Dense(1000, activation='softmax')(model) #create model from tensors model = Model(inputs=[input_image, input_language], outputs = model) return model
- 建立组合的网络并显示其摘要,以了解其内部外观。 加载预训练的权重并使用 rmsprop 优化器使用
categorical_crossentropy
损失函数来编译模型:
combined_model = build_combined_model() combined_model.summary() combined_model.load_weights(VQA_weights_file) combined_model.compile(loss='categorical_crossentropy', optimizer='rmsprop') ____________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== input_language (InputLayer) (None, 30, 300) 0 ____________________________________________________________________________________________________ lstm_1 (LSTM) (None, 30, 512) 1665024 input_language[0][0] ____________________________________________________________________________________________________ input_image (InputLayer) (None, 4096) 0 ____________________________________________________________________________________________________ lstm_2 (LSTM) (None, 30, 512) 2099200 lstm_1[0][0] ____________________________________________________________________________________________________ reshape_3 (Reshape) (None, 4096) 0 input_image[0][0] ____________________________________________________________________________________________________ lstm_3 (LSTM) (None, 512) 2099200 lstm_2[0][0] ____________________________________________________________________________________________________ concatenate_3 (Concatenate) (None, 4608) 0 reshape_3[0][0] lstm_3[0][0] ____________________________________________________________________________________________________ dense_8 (Dense) (None, 1024) 4719616 concatenate_3[0][0] ____________________________________________________________________________________________________ dropout_7 (Dropout) (None, 1024) 0 dense_8[0][0] ____________________________________________________________________________________________________ dense_9 (Dense) (None, 1024) 1049600 dropout_7[0][0] ____________________________________________________________________________________________________ dropout_8 (Dropout) (None, 1024) 0 dense_9[0][0] ____________________________________________________________________________________________________ dense_10 (Dense) (None, 1024) 1049600 dropout_8[0][0] ____________________________________________________________________________________________________ dropout_9 (Dropout) (None, 1024) 0 dense_10[0][0] ____________________________________________________________________________________________________ dense_11 (Dense) (None, 1000) 1025000 dropout_9[0][0] ==================================================================================================== Total params: 13,707,240 Trainable params: 13,707,240 Non-trainable params: 0
- 使用预训练的组合网络进行预测。 请注意,在这种情况下,我们使用该网络已经在线可用的权重,但是感兴趣的读者可以在自己的训练集中重新训练组合的网络:
y_output = combined_model.predict([image_features, language_features]) # This task here is represented as a classification into a 1000 top answers # this means some of the answers were not part of training and thus would # not show up in the result. # These 1000 answers are stored in the sklearn Encoder class labelencoder = joblib.load(label_encoder_file_name) for label in reversed(np.argsort(y_output)[0,-5:]): print str(round(y_output[0,label]*100,2)).zfill(5), "% ", labelencoder.inverse_transform(label)
工作原理
视觉问题解答的任务是通过结合使用不同的深度神经网络来解决的。 预训练的 VGG16 已用于从图像中提取特征,而 LSTM 序列已用于从先前映射到嵌入空间的问题中提取特征。 VGG16 是用于图像特征提取的 CNN,而 LSTM 是用于提取表示序列的时间特征的 RNN。 目前,这两种方法的结合是处理此类网络的最新技术。 然后,在组合模型的顶部添加一个具有丢弃功能的多层感知机,以形成我们的深度网络。
更多
在互联网上,您可以找到 Avi Singh 进行的更多实验,其中比较了不同的模型,包括简单的“袋装”语言的“单词”与图像的 CNN,仅 LSTM 模型以及 LSTM + CNN 模型-类似于本秘籍中讨论的模型。 博客文章还讨论了每种模型的不同训练策略。
除此之外,有兴趣的读者可以在互联网上找到一个不错的 GUI,它建立在 Avi Singh 演示的顶部,使您可以交互式加载图像并提出相关问题。 还提供了 YouTube 视频。
通过六种不同方式将预训练网络用于视频分类
对视频进行分类是一个活跃的研究领域,因为处理此类媒体需要大量数据。 内存需求经常达到现代 GPU 的极限,可能需要在多台机器上进行分布式训练。 目前,研究正在探索复杂性不断提高的不同方向,让我们对其进行回顾。
第一种方法包括一次将一个视频帧分类,方法是将每个视频帧视为使用 2D CNN 处理的单独图像。 这种方法只是将视频分类问题简化为图像分类问题。 每个视频帧产生分类输出,并且通过考虑每个帧的更频繁选择的类别对视频进行分类。
第二种方法包括创建一个单一网络,其中 2D CNN 与 RNN 结合在一起。 这个想法是 CNN 将考虑图像分量,而 RNN 将考虑每个视频的序列信息。 由于要优化的参数数量非常多,这种类型的网络可能很难训练。
第三种方法是使用 3D 卷积网络,其中 3D 卷积网络是在 3D 张量(time
,image_width
和image_height
)上运行的 2D 卷积网络的扩展。 这种方法是图像分类的另一个自然扩展,但同样,3D 卷积网络可能很难训练。
第四种方法基于智能直觉。 代替直接使用 CNN 进行分类,它们可以用于存储视频中每个帧的脱机特征。 想法是,如先前的秘籍所示,可以通过迁移学习使特征提取非常有效。 提取所有特征后,可以将它们作为一组输入传递到 RNN,该 RNN 将学习多个帧中的序列并发出最终分类。
第五种方法是第四种方法的简单变体,其中最后一层是 MLP 而不是 RNN。 在某些情况下,就计算要求而言,此方法可能更简单且成本更低。
第六种方法是第四种方法的变体,其中特征提取的阶段是通过提取空间和视觉特征的 3D CNN 实现的。 然后将这些特征传递给 RNN 或 MLP。
选择最佳方法严格取决于您的特定应用,没有明确的答案。 前三种方法通常在计算上更昂贵,而后三种方法则更便宜并且经常获得更好的表现。
在本秘籍中,我们将通过描述论文 Temporal Activity Detection in Untrimmed Videos with Recurrent Neural Networks 来描述如何使用第六种方法。 这项工作旨在解决 ActivityNet 挑战 。 这项挑战着重于从用户生成的视频中识别高水平和面向目标的活动,类似于在互联网门户网站中找到的那些活动。 该挑战针对两项不同任务中的 200 个活动类别量身定制:
- 未修剪的分类挑战:给定较长的视频,请预测视频中存在的活动的标签
- 检测挑战:给定较长的视频,预测视频中存在的活动的标签和时间范围
呈现的架构包括两个阶段,如下图所示。 第一阶段将视频信息编码为单个视频表示形式,以用于小型视频剪辑。 为此,使用了 C3D 网络。 C3D 网络使用 3D 卷积从视频中提取时空特征,这些视频先前已被分成 16 帧剪辑。
一旦提取了视频特征,第二阶段就是对每个剪辑的活动进行分类。 为了执行这种分类,使用了 RNN,更具体地说是一个 LSTM 网络,该网络试图利用长期相关性并执行视频序列的预测。 此阶段已被训练:
操作步骤
对于此秘籍,我们仅汇总在线呈现的结果:
- 第一步是克隆 git 仓库
git clone https://github.com/imatge-upc/activitynet-2016-cvprw.git
- 然后,我们需要下载 ActivityNet v1.3 数据集,其大小为 600 GB:
cd dataset # This will download the videos on the default directory sh download_videos.sh username password # This will download the videos on the directory you specify sh download_videos.sh username password /path/you/want
- 下一步是下载 CNN3d 和 RNN 的预训练权重:
cd data/models sh get_c3d_sports_weights.sh sh get_temporal_location_weights.sh
- 最后一步包括对视频进行分类:
python scripts/run_all_pipeline.py -i path/to/test/video.mp4
工作原理
如果您有兴趣在计算机上训练 CNN3D 和 RNN,则可以在互联网上找到此计算机管道使用的特定命令。
目的是介绍可用于视频分类的不同方法的高级视图。 同样,不仅有一个单一的秘籍,而且有多个选项,应根据您的特定需求仔细选择。
更多
CNN-LSTM 架构是新的 RNN 层,其中输入转换和循环转换的输入都是卷积。 尽管名称非常相似,但如上所述,CNN-LSTM 层与 CNN 和 LSTM 的组合不同。 该模型在论文《卷积 LSTM 网络:降水临近预报的机器学习方法》(史兴建,陈周荣,王浩,杨天彦,黄伟坚,胡旺春,2015 年)中进行了描述,并且在 2017 年,有些人开始尝试使用此模块进行视频实验,但这仍然是一个活跃的研究领域。