基于神经网络的视频编码NNVC(1):帧内预测

在H.266/VVC发布后,基于传统编码框架提升压缩率越来越难,随着深度学习的发展,研究人员开始尝试将神经网络引入编码器。为此,JVET工作组在2020年成立AHG11小组来专门进行基于神经网络的视频编码的研究。

为了方便研究,工作组基于VTM-11.0开发了参考软件NNVC,包含了编码器、解码器、训练、推理等相关代码。目前NNVC中集成了的神经网络相关的模块主要是loop filter、帧内预测、超分辨率等。目前NNVC已经发展到4.0版本,相比于VTM-11.0在RA、low-delay和all-intra配置下{Y,Cb,Cr}的BD-rate分别达到{-11.94%,-21.86%,-22.59%},{-9.18%,-19.76%,-20.92%}和{-10.63%,-21.56%,-23.02%}。本文主要介绍其中的NN-Based Intra Prediction模块。

Framework

NN-Based Intra Prediction共包含7个模型,分别用于不同尺寸的块{4x4,4x8,4x16,4x32,8x8,8x16,16x16}。

对于wxh的块Y使用NN-Based Intra Prediction模型预测的过程如Fig.1。首先获取Y的上下文X,X通过前处理过程得到\tilde{X},然后作为NN模型f_{h,w}( .;\theta _{h,w})的输入,模型输出\tilde{Y},经过后处理得到wxh的预测块\hat{Y}。其中Y的参考像素X由Y的上方n_{a} \times ( n_{l} +2w+e_{w})和左侧( 2h+e_{h}) \times n_{l}的重建像素构成。NN模型的输出还包括grpIdx1、grpIdx2和repIdx,其中grpIdx和LFNST的参数选择有关。repIdx对应传统的67个帧内预测模式和MPM构建相关。

NN-Based Intra Prediction中的模型都是全连接神经网络,不包含卷积层。

If min⁡(h,w)≤8  && hw<256:
    n_a=n_l=min⁡(h,w)
otherwise:
    if h>8:
                n_a=h⁄2
    otherwise:
        n_a=h
    if w>8:
        n_l=w⁄2
    otherwise:
        n_l=w

If h≤8, e_h=4. Otherwise, e_h=0.
If w≤8, e_w=4. Otherwise, e_w=0.

前处理和后处理

在上面的流程中,上下文X经过前处理后再输入NN模型,前处理过程可分为4步:

  1. 当前块Y的上下文X可分为2个部分,可参考部分\overline{X}和不可参考部分X_{u},如Fig.2,可参考部分减去其对应的均值u。

  2. 上下文X内的像素乘以\rho =1/\left( 2^{b-8}\right),b是bitdepth,在VVC中是10。

  3. 所有不可参考像素X_{u}置零。

  4. 上面得到的结果展平为一维向量,长度为n_{a}( n_{l} +2w+e_{w}) +( 2h+e_{h}) n_{l}

对于NN模型的输出的后处理过程和前处理过程相反,将一维向量reshape为wxh尺寸,像素除以p,可参考部分像素加上均值u,然后clip到正常像素范围,整个过程可以描述如下:

\hat{Y} =min\left( max\left(\frac{reshape\left(\tilde{Y}\right)}{\rho } +u,0\right) ,2^{b} -1\right)

注意上述前处理和后处理过程是浮点精度。对于signed-integers的NN模型,\rho =2^{Q_{in} -b-8},对于int16,Qin=7,对于int32,Qin=23。

MPM列表构建

使用MPM对intra模式进行预测可以减少编码intra模式的码率,在VVC中MPM列表包含6个候选项,来自当前块上方和左侧intra块的模式。在开启NN-Based Intra Prediction后,若当前块采用传统intra模式,而其相邻块采用NN-based模式,那如何构建当前块的MPM列表?这里就需要Fig.1中NN模型的输出repIdx,若相邻块采用NN-based模式则将其输出的repIdx加入当前块的MPM列表。

上下文变换

前面提到NN-Based Intra Prediction共包含7个模型,分别用于不同尺寸的块{4x4,4x8,4x16,4x32,8x8,8x16,16x16}。但是有的编码块可能不属于这7个尺寸,为了解决整个问题可以对其上下文X进行变换,变换后满足这7个尺寸,可以在垂直方向下采样δ和/或在水平方向下采样γ,还可以进行转置,NN模型处理完后对后处理的结果再进行上采样和转置得到最终预测结果。表1中是各个尺寸块进行变换的具体参数,例如对于32x8的块在垂直方向进行2倍下采样然后转置得到8x16的块,使用8x16的模型对它处理。对于不在表1中的尺寸的块(h,w)不允许使用NN模式。

NN-Based Intra Prediction模式的传输

亮度:对于不在表1中的尺寸不允许使用NN模式,对于表1中的尺寸的块设置标志位nnFlagY,nnFlagY=1表示使用NN模式,nnFlagY=0表示使用传统的intra模式。如Fig.3所示。

色度:在VVC中色度intra模式编码中,若色度模式和亮度模式相同则采用DM模式否则需要编码色度模式。如果色度对应的亮度块使用NN模式且色度块满足表1的尺寸则DM模式表示NN模式否则DM模式表示PLANAR模式。如果亮度块不是NN模式且色度块满足表1尺寸,则需要编码标志位nnFlagC,nnFlagC=1表示使用NN模式,nnFlagC=0表示不使用NN模式。

注意如果使用NN模式但是当前块的上下文超出图像边界,如x< n_{l} ||y< n_{a},则当前块使用PLANAR模式。

训练

模型的训练需要进行4轮迭代训练:

  1. cycle0,使用VTM-11.0作为anchor生成训练需要的块Y和对应的上下文X组成数据对(Y,X)。将7个模型参数随机初始化然后在这些数据上训练。

  2. cycle1,VTM-11.0_nnvc使用cycle0的参数再次生成训练数据,7个模式使用cycle0的结果初始化参数然后再训练。

  3. cycle2,VTM-11.0_nnvc使用cycle1的参数再次生成训练数据,7个模式使用cycle1的结果初始化参数然后再训练。然后使用相同的训练数据,恢复这7个神经网络的训练,这一次对它们的权重引入了稀疏性约束

  4. cycle3,VTM-11.0_nnvc使用cycle2的参数再次生成训练数据,7个模式使用cycle2的结果初始化参数,然后在这7个神经网络中分别对计算grpIdx1和grpIdx2的部分进行训练

NNVC的代码中包含了这些训练代码。

推理

推理采用SADL框架,SADL是工作组开发的框架用c++写成,它没有额外的依赖,可以直接集成进VTM中调用模型进行推理。

SADL既可以进行浮点推理也可以进行定点推理,下面是NNVC中的训练好的模型,可以看到每个尺寸既有float版本也有int16版本。

### 使用Python实现神经网络视频编码(NNVC) 对于希望了解如何利用Python来实施神经网络视频编码NNVC)的人来说,可以探索一些特定资源和技术路径。一种方法是从理解基础概念开始,即什么是Python及其应用领域[^1]。 为了深入研究NNVC的具体实践,在线存在多种开源项目和学术论文提供了宝贵的见解。例如,激活地图集是一种由谷歌和OpenAI研究人员开发的技术,它有助于更直观地解析神经网络内部的工作机制,这可能间接帮助于构建更加高效的视频编码模型[^2]。 下面是一些推荐的学习材料: #### 学习资源 - **书籍**: 查找专注于机器学习特别是深度学习以及计算机视觉方面的书籍,这些通常会覆盖到基于神经网络的数据处理技巧。 - **在线课程平台** 如Coursera、Udacity等提供有关深度学习专项课程,其中某些模块可能会涉及到图像/视频压缩算法的设计思路。 - **GitHub仓库搜索** 可以通过关键词`Neural Network Video Coding`, `Deep Learning Video Compression` 来查找相关的代码库,很多开发者会在README文件里给出详细的安装指南与使用说明。 #### 实践案例分享 考虑到实际操作的重要性,这里展示一段简化版的框架搭建过程作为入门指导: ```python import torch from torchvision import transforms, datasets from torch.utils.data import DataLoader import pytorch_lightning as pl class SimpleVideoCompressor(pl.LightningModule): def __init__(self): super().__init__() # 定义编码器结构... def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return decoded def training_step(self, batch, batch_idx): data, _ = batch output = self(data) loss = F.mse_loss(output, data) # 均方误差损失函数 return {'loss': loss} # 数据预处理部分省略... if __name__ == '__main__': model = SimpleVideoCompressor() trainer = pl.Trainer(gpus=1 if torch.cuda.is_available() else None) trainer.fit(model, train_loader) ``` 此段代码仅作为一个非常基本的例子,并未涉及具体的优化细节或是完整的训练流程设置;真正的NNVC解决方案往往更为复杂,需要考虑更多因素如时间维度上的依赖关系建模等问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值