深度学习与视频编解码算法一
論文《Variational image compression with a scale hyperprior》
大牛Johannes Ballé寫的,必須要讀。
通過自編碼器把圖像壓縮成latent representation(大小變為原始圖像1/16 * 1/16)
然后把latent representation通過統計概率使用熵編碼進行編碼。
在熵編碼由于不知道真實的字符概率,所以需要可以統計這些信息,可以把這些信息傳到解碼端。
在訓練中采用端到端的訓練,需要把平衡side信息與熵模型的提升。以達到總體的碼字編碼降低。
訓練時,由于量化引入了誤差,使用梯度下降無法進行,因此把量化當作是均勻噪聲。
由于latent representation具有分布特性,因此引入條件Z(概率分布情況),使用它來壓縮圖像, 通過編碼端傳遞到碼流中,然后解碼端根據Z得到latent representation分布,進而得到重新圖像。如下圖中的右邊部分。
熵編碼
Cumulative distribution function累積分布函數(cdf)
累積分布函數(cumulative distribution function)定義:對連續函數,所有小于等于a的值,其出現概率的和。F(a)=P(x<=a)
參考:https://blog.csdn.net/sinat_26599509/article/details/52882769
y_tilde, likelihoods = entropy_bottleneck(y, training=True)
訓練主要調用entropy_models.py文件中函數 def call(self, inputs, training),其中主要是對y 加上noise得到y_tilde.
以及對y_tilde計算累積概率,進而得到 likelihoods(似然估計)值。
邊緣概率分布(the marginal distribution)
某一組概率的加和,叫邊緣概率。邊緣概率的分布情況,就叫邊緣分布。和“邊緣”兩個字本身沒太大關系,因為是求和,在表格中往往將這種值放在margin(表頭)的位置,所以叫margin distribution。
marginal distribution,邊緣分布(有時也翻譯成邊界分布)。
如果我們把每一個變量的概率分布稱為一個概率分布,那么邊緣分布就是若干個變量的概率加和所表現出的分布。舉個例子,假設P(B),P?,P(A|B),P(A|C)已知,求P(A)。那么P(A)=sum(P(B)*P(A|B),P?*P(A|C))。
再舉個簡單的例子:對于一個任意大小(n*n)的概率矩陣X,每一個元素表示一個概率,對于其中任一行或任一列求和,得到的概率就是邊緣概率。如果寫成式子,就是第i行有以下邊緣分布:P(i)=sum(P(i,j),for each j in n)。
這個函數即是模擬概率分布函PMF,這些參數是預先訓練得到,表示每一個可能值的概率。例如128值的分布概率最高。具體計算方法如下:
lower = self._logits_cumulative(samples - half, stop_gradient=True)
upper = self._logits_cumulative(samples + half, stop_gradient=True)
# Flip signs if we can move more towards the left tail of the sigmoid.
sign = -math_ops.sign(math_ops.add_n([lower, upper]))
pmf = abs(math_ops.sigmoid(sign * upper) - math_ops.sigmoid(sign * lower))
# Add tail masses to first and last bin of pmf, as we clip values for
# compression, meaning that out-of-range values get mapped to these bins.
pmf = array_ops.concat([
math_ops.add_n([pmf[:, 0, :1], math_ops.sigmoid(lower[:, 0, :1])]),
pmf[:, 0, 1:-1],
math_ops.add_n([pmf[:, 0, -1:], math_ops.sigmoid(-upper[:, 0, -1:])]),
], axis=-1)
通過PMF可以計算得到CDF累計分布。通過這個可以調用range_decode就可以進行碼字的編碼與解碼。
cumFreq0 = [0, 4, 5, 6] //表示累記頻率。
sequence = [0, 0, 0, 0, 1, 2; 0, 0, 0, 0, 1, 2; 0, 0, 0, 0, 1, 2]
encoder.encode(data0, sequence )
論文《end-to-tend optimized image compression》
如下圖所示,通過優化 R + lambda * D 值,即使編碼端與解碼端優化對應的參數。
對于量化,采用一個損失函數來代替(proxy loss function based on a continuous relaxation of the probability model),防止梯度為0.
實現一個真實的碼率輸出bit數目,加入到訓練中,這是一個最大的創新點。碼率的輸出采用Dirac delta functions函數,即
碼率的大小決定下面的字符分布統計,如果分布越集中,碼率越小。這個需要訓練得到對應的參數。
量化損失是與碼就有關:
變換是為了減少數據的相關性,在變換過程中采用歸一化,能夠提高性,因此提出了generalized divisive normalization(GDN)變換。
y_tilde, likelihoods = entropy_bottleneck(y, training=True) 此片主要是對Y加噪聲得到y_tilde,以及得到分布概率,進而計算出碼率。由于量化部分維度非常高,我們采用了正布分布的噪聲來代替。
訓練時,分為二部分損失
train_mse = tf.reduce_mean(tf.squared_difference(x, x_tilde))
train_mse *= 255 ** 2
train_bpp = tf.reduce_sum(tf.log(likelihoods)) / (-np.log(2) * num_pixels)
train_loss = args.lmbda * train_mse + train_bpp //rdo損失
entropy_bottleneck.losses[0] //熵相關部分損失,這部分還沒有理解清楚,估計是熵重建損失。
entropy_bottleneck.updates[0]//還沒有理解清楚。
train_op = tf.group(main_step, aux_step, entropy_bottleneck.updates[0])
把這三部分聯合在一些一起訓練,同時進行減少。
由于訓練時量化時梯度為 0,因為使用uniform noise來代替量化過程,有利于數據的訓練。
總結
以上是生活随笔為你收集整理的深度学习与视频编解码算法一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟机分区扩容
- 下一篇: 梳理百年深度学习发展史-七月在线机器学习