Page 385 - 《软件学报》2025年第9期
P. 385

4296                                                       软件学报  2025  年第  36  卷第  9  期


                 3.2.3    压 缩
                    在获取训练完成的编码器后, NCQT          将其与算术编码结合来对字符进行编码. 完整的压缩过程如算法                      2  所示.
                 首先, 将数据拆为长度为       c 的窗口  (默认为   32). 由于第  1  个窗口的数据无法使用前       c 个字符预测其概率, 所以将其
                 按照固定的均匀分布概率由算术编码生成表示. 然后, 使用训练后的模型对每个窗口的下一个字符进行预测, 并得
                 到相应的概率估计. 生成的概率和下一个字符将输入到算术编码器中更新数据的编码区间. 以上步骤循环进行直
                 至所有字符完成预测与编码.

                 算法  2. 压缩过程.

                 输入: 输入序列    x = {x 0 , x 1 , x 2 , …, x end }, 窗口长度  c;
                 输出: 压缩文件.
                 1. i ← 0
                 2. while 0 ≤ i < c do
                 3.   Arithmetic Encode(x i , 1/23) // 以固定概率编码前 c 个字符
                 4.   i ← i + 1
                 5. end
                 6. Model.initialize() // 初始化模型
                 7. while c ≤ i ≤ end do
                 8.   P (x i |x i−c , …, x i−1 ) ← Model.forward(x i−c , …, x i−1 ) // 计算条件概率
                 9.   Arithmetic Encode(x i , P(x i |x i−c , …, x i−1 )) // 编码第 i 个字符
                 10.    Model.backward(x i , P(x i |x i−c , …, x i−1 ), loss function) // 根据预测结果动态更新模型参数
                 11.    i ← i + 1
                 12. end
                    窗口长度    c 决定了模型预测时的上下文长度. 本文提出的方法采用神经网络模型进行数据压缩, 这时如果
                 设置的窗口太小, 则可能会导致模型无法充分利用上下文信息, 难以捕捉到长距离的依赖关系, 导致预测效果降
                 低. 同时, 窗口太小会使得方法需要更多的循环次数来处理整个序列, 可能会导致整体效率降低. 如果设置的窗
                 口太大, 较大的输入维度会使模型训练更加复杂, 可能需要更长的训练时间和更多的计算资源, 而且容易过拟
                 合. Bellard  等人  [31] 对不同的窗口大小进行了对比, 较小的窗口长度下的模型参数量更少, 预测时间较短且资源
                 消耗较低, 而较大的窗口大小下模型通常具有更高的预测准确率. 在实际使用过程中, 应该综合考虑资源数量以
                 及待压缩追踪数据的平均长度选择合适的窗口大小, 以权衡资源消耗、模型泛化能力以及模型的上下文捕捉
                 能力.
                    在预测过程中, 神经网络生成每个字符在前置窗口下的条件概率. 在编码过程中, 算术编码将待编码的数据映
                 射到一个位于     (0, 1) 的实数区间中, 并输出一个位于区间内的小数以表示全部数据. 具体而言, 编码器初始设置实
                 数区间   (L, H) 为  (0, 1) 以存储中间结果, 其中  L  为区间的下界, H  为区间的上界. 对于第       i 个需要编码的字符     s i , 根
                                          i
                 据预测过程生成的概率统计表           y  = {  y y ,  , …,  y i   }进行编码, 其中  N  为字符的数量. 然后, 通过应用以下公式进行
                                              i
                                                 i
                                              1  2    N
                 编码:

                                                           ∑ j
                                                               y i
                                              
                                                ( )             k
                                                             k=1
                                                  i     i
                                                                 , i ∈ {1,...,n}
                                                         j
                                                   t
                                              arg y = s i , o = ∑ N
                                              
                                                                i
                                                               y
                                                                k                                    (2)
                                                             k=1
                                              
                                              
                                                                i
                                              L i = L i−1 +(H i−1 − L i−1 )·o
                                              
                                                                t−1
                                              
                                              
                                                                i
                                              
                                               H i = L i−1 +(H i−1 − L i−1 )·o t
                 其中, n  为总字符数, t 表示   s i 在统计表中的位置. 在对所有      n  个字符执行上述过程后, 编码器可以得到一个最终的
   380   381   382   383   384   385   386   387   388   389   390