1. 模型简介
C3D模型广泛用于3D视觉任务。C3D网络的构造类似于常见的2D卷积网,主要区别在于C3D使用像卷积3D这样的3D操作,而2D卷积网则是通常的2D架构。要了解有关C3D网络的更多信息,您可以阅读原始论文学习3D卷积网络的时空特征。
3D卷积图示:
深度学习在图像领域的成功应用产生了多个优秀预训练特征提取模型。提取的特征基本都是网络后面FC层的激活值,并且在迁移学习任务上表现良好。但是,基于图像训练的深度特征因为没有编码运动特征,并不适合用在视频上。本文就提出了一种可以学习spatial-temporal特征的深度3D ConvNet。虽然3D卷积并不是本文首次提出,但是本文基于大规模的监督训练数据集和深度网络架构,在不同视频分析任务中本文都取得了不错的效果。C3D提取出的特征将视频中物体信息、场景信息和动作信息都隐式编码进特征,使得不需要根据特定任务进行finetune都可以取得不错的效果。并且C3D拥有上述提到的好的视频特征描述子应具有的四个特征。
2.模型结构
C3D网络有8个卷积,5个最大池化和2个完全连接的层,然后是softmax输出层。所有 3D 卷积核都是 3 × 3 × 3,在空间和时间维度上都步幅为 1。3D 池化图层表示为从池 1 到池5。所有池化内核均为 2 × 2 × 2,但池 1 为 1 × 2 × 2。每个完全连接的层有 4096 个输出单元。
网络结构代码
C3D功能函数说明:
数据预处理:
VideoResize:改变输入视频大小
VideoRescale:此运算符将使用给定的重新缩放和移位来重新缩放输入视频帧。output=image*rescale+shift重新缩放输入视频。
VideoRandomCrop:在随机位置裁剪给定的视频序列(t x h x w x c)
VideoRandomHorizontalFlip:以给定的概率翻转视频的每一帧
VideoReOrder:重新排列数据的维度顺序
参数:
in_d:输入数据的深度,它可以被视为视频的帧数。默认值:16。
in_h:输入帧的高度。默认值:112。
in_w:输入帧的宽度。默认值:112。
in_channel(int):输入数据的通道数。默认值:3。
kernel_size(Union[int,Tuple[int]]):C3D中每个conv3d层的卷积核大小。
默认值:(3,3,3)。
head_channel(Tuple[int]):两个全连接层大小。默认值:[4096,4096]。
num_classes(int):类的数量,它是每个样本的分类得分大小,即:math:CLASSES_{out}
。默认值:400。
keep_prob(Tuple[int]):multi-dense-layer头部的dropout概率,概率数等于multi-dense-layer的数量。
pretrained(bool):如果为“True”,它将创建一个预训练模型,预训练模型将被加载
从网络。如果为“False”,它将创建一个c3d模型,并对权重和偏差进行统一初始化。
Inputs:
Tensor of shape :math:(N, C_{in}, D_{in}, H_{in}, W_{in})
.
Outputs:
Tensor of shape :math:(N, CLASSES_{out})
.
执行案例
from mindspore import nn
from mindspore.train import Model
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor
from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits
from mindspore.nn.metrics import Accuracy
from msvideo.data.transforms import VideoRandomCrop, VideoRescale, VideoResize, VideoReOrder, VideoRandomHorizontalFlip, VideoCenterCrop
from msvideo.utils.check_param import Validator,Rel
数据集加载
通过基于VideoDataset编写的UCF101类来加载UCF101数据集。
from msvideo.data.ucf101 import UCF101
dataset = UCF101(path='/home/publicfile/UCF101-dataset/data',
split="train",
seq=16,
num_parallel_workers=4,
shuffle=True,
batch_size=16,
repeat_num=1,
)
ckpt_save_dir = './c3d'
数据处理
用VideoShortEdgeResize根据短边来进行Resize,再用VideoRandomCrop对Resize后的视频进行随机裁剪,再用VideoRandomHorizontalFlip根据概率对视频进行水平翻转,通过VideoRescale对视频进行缩放,利用VideoReOrder对维度进行变换,再用VideoNormalize进行归一化处理。文章来源:https://www.toymoban.com/news/detail-436456.html
from msvideo.data.transforms import VideoNormalize, VideoShortEdgeResize, VideoReOrder,VideoCenterCrop, VideoRescale, VideoResize, VideoReOrder,VideoRandomCrop, VideoRandomHorizontalFlip, VideoRescale
transforms = [VideoResize([128, 171]),
VideoRescale(shift="/home/chenjy/zjut_mindvideo/tutorials/classification/c3d/resized_mean_sports1m.npy"),
VideoCenterCrop([112, 112]),
VideoReOrder([3, 0, 1, 2])]
dataset.transform = transforms
dataset_train = dataset.run()
Validator.check_int(dataset_train.get_dataset_size(), 0, Rel.GT)
step_size = dataset_train.get_dataset_size()
网络构建
from msvideo.models.c3d import C3D
network= C3D(num_classes=101)
from msvideo.schedule.lr_schedule import warmup_cosine_annealing_lr_v1
learning_rate = warmup_cosine_annealing_lr_v1(lr=0.0125,
steps_per_epoch=step_size,
warmup_epochs=35,
max_epoch=100,
t_max=100,
eta_min=0)
network_opt = nn.SGD(network.trainable_params(),
learning_rate,
momentum=0.9,
weight_decay=0.00005)
network_loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean")
ckpt_config = CheckpointConfig(
save_checkpoint_steps=step_size,
keep_checkpoint_max=10)
ckpt_callback = ModelCheckpoint(prefix='c3d',
directory=ckpt_save_dir,
config=ckpt_config)
# Init the model.
model = Model(network,
loss_fn=network_loss,
optimizer=network_opt,
metrics={"Accuracy": Accuracy()})
# Begin to train.
print('[Start training `{}`]'.format('c3d_ucf101'))
print("=" * 80)
model.train(100,
dataset_train,
callbacks=[ckpt_callback, LossMonitor()],
dataset_sink_mode=False)
print('[End of training `{}`]'.format('c3d_ucf101'))
评估流程
from mindspore import context
from mindspore.train.callback import Callback
class PrintEvalStep(Callback):
""" print eval step """
def step_end(self, run_context):
""" eval step """
cb_params = run_context.original_args()
print("eval: {}/{}".format(cb_params.cur_step_num, cb_params.batch_num))
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
from msvideo.data.ucf101 import UCF101
dataset_eval = UCF101(path="/home/publicfile/UCF101-dataset/data",
split="val",
seq=16,
num_parallel_workers=8,
shuffle=False,
batch_size=16,
repeat_num=1,
)
from msvideo.data.transforms import VideoReOrder, VideoRescale, VideoNormalize
from msvideo.data.transforms import VideoCenterCrop, VideoShortEdgeResize
transforms = [VideoResize([128, 171]),
VideoRescale(shift="/home/chenjy/zjut_mindvideo/tutorials/classification/c3d/resized_mean_sports1m.npy"),
VideoCenterCrop([112, 112]),
VideoReOrder([3, 0, 1, 2])]
dataset_eval.transform = transforms
dataset_eval = dataset_eval.run()
from mindspore import nn
from mindspore.train import Model
from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits
from mindspore import load_checkpoint, load_param_into_net
from msvideo.models.c3d import C3D
network = C3D(num_classes=101)
# Define loss function.
network_loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean")
# Load pretrained model.
param_dict = load_checkpoint(ckpt_file_name='/home/chenjy/c3d.ckpt')
load_param_into_net(network, param_dict)
# Define eval_metrics.
eval_metrics = {'Loss': nn.Loss(),
'Top_1_Accuracy': nn.Top1CategoricalAccuracy(),
'Top_5_Accuracy': nn.Top5CategoricalAccuracy()}
print_cb = PrintEvalStep()
# Init the model.
model = Model(network, loss_fn=network_loss, metrics=eval_metrics)
# Begin to eval.
print('[Start eval `{}`]'.format('c3d_ucf101'))
result = model.eval(dataset_eval,
callbacks=[print_cb],
dataset_sink_mode=False)
print(result)
Code
Gitee文章来源地址https://www.toymoban.com/news/detail-436456.html
到了这里,关于C3D网络介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!