CS20si 第10課: 變分自編碼器(VAE)

第10課: 變分自編碼器(VAE)

CS20si課程資料和代碼Github地址

變分推斷(Variational Inference)

關(guān)于變分推斷的基礎(chǔ)概念可以先參照這篇文章制轰。

學(xué)習(xí)未知的變量

圖像由數(shù)百萬像素組成倚喂,但可能有更緊湊的內(nèi)容表示方式(對象、位置等)油狂。

找到這個表示的映射可以使我們找出語義相似的圖像,甚至生成新的圖像衅码。

我們叫這種緊湊表示為z损同,它對應(yīng)的像素點集合為x。我們的N張圖片都是一樣的結(jié)構(gòu)逐纬。

image

假設(shè)模型中的x由隱含變量z生成,我們想要找到解釋數(shù)據(jù)的隱含變量削樊。

image

但是我們不能直接計算數(shù)據(jù)的最大似然豁生,因為它取決于隱含變量z而我們不知道它們的值。

θ* = argmax P_θ(x) = argmax ∫ P_θ(x|z)P(z) dz

我們定義一個先驗假設(shè)P(z),它是z的分布沛硅。

我們感興趣的是后驗概率P(z|x)眼刃,它依賴于相應(yīng)的數(shù)據(jù)點x。

變分下界: 概覽

迭代優(yōu)化近似的后驗概率Q(z)直到Q(z) ≈ P(z|x)

image

Q(z)的目標是變分下界

\begin{aligned} lnP(x) &≥ E_{Q(z)}[lnP(x,z) ? lnQ(z)] \\ &= E_{Q(z)}[lnP(x|z) + lnP(z) ? lnQ(z)] \\ &= E_{Q(z)}[lnP(x|z)] ? D_{KL}[Q(z)||P(z)] \end{aligned}

這是一個下界因為KL散度是非負的摇肌。

取 Q(z) ? ?? 為可微的采樣,常常取高斯分布仪际。KL散度是一個正則項围小。

變分下界: 算法

將隱含的P(z)初始化為固定的先驗概率,比如說0均值單位方差的高斯分布树碱。

初始化網(wǎng)絡(luò)權(quán)值 θ 和 Q(z) 的 μ 和 σ 肯适。

記住目標函數(shù) lnP(x) ≥ E_{Q(z)}[lnP_θ(x|z)] ? D_{KL}[Q(z)||P(z)]

迭代直到收斂:

  1. 從Q(z)中取樣一個zz = σε + μ ??(ε ~ N(0, 1))
  2. 用神經(jīng)網(wǎng)絡(luò)計算 P_θ(x|z)
  3. 計算Q(z)P(z)的KL散度
  4. 計算目標函數(shù)的梯度來優(yōu)化 θ, μ, σ

分段推斷: 概覽

我們可以通過梯度下降的方法成榜,為每個數(shù)據(jù)點學(xué)習(xí)足夠的Q(z)統(tǒng)計量框舔。但是每個數(shù)據(jù)點都需要多個求梯度的步驟,即使是在評價時赎婚。

我們可以使用一個編碼器網(wǎng)絡(luò)Q(z|x)學(xué)習(xí)這個過程的結(jié)果刘绣。想象一下怎樣為所有的數(shù)據(jù)點推斷隱含變量,反向傳播優(yōu)化編碼器的權(quán)重挣输,而不是后驗的統(tǒng)計量μ,σ纬凤。

分段推斷: 算法

將隱含的P(z)初始化為固定的先驗概率,比如說0均值單位方差的高斯分布撩嚼。

初始化編碼器的權(quán)值 ? 和解碼器的權(quán)值 θ 停士。

記住目標函數(shù) lnP(x) ≥ E_{Q(z)}[lnP_θ(x|z)] ? D_{KL}[Q_?(z|x)||P(z)]

迭代直到收斂:

  1. 選擇數(shù)據(jù)點x并用編碼器計算 Q?(z|x)
  2. 從Q(z|x)中取樣一個z完丽,z = σε + μ ??(ε ~ N(0, 1))
  3. 用解碼器計算 P_θ(x|z)
  4. 計算Q(z)P(z)的KL散度
  5. 計算目標函數(shù)的梯度來優(yōu)化 θ, ?

變分自編碼器(VAE, Variational Auto-Encoder)

編碼器用來分段推斷出Q(z|x), 解碼器用來生成模型P(x|z)恋技。
變分下界目標函數(shù) E_{Q(z|x)}[lnP(x|z)] ? D_{KL}[Q(z|x)||P(z)]

通過梯度下降訓(xùn)練端到端模型逻族。

image

貝葉斯神經(jīng)網(wǎng)絡(luò)

獨立隱含的Q(θ)是對角高斯分布蜻底。

條件生成模型P_θ(y|x)

image

變分下界目標函數(shù):E_{Q(θ)}[lnP_θ(y|x)] ? D_{KL}[Q(θ)||P(θ)]

將KL項除以數(shù)據(jù)集大小瓷耙,因為整個數(shù)據(jù)集的參數(shù)是共享的朱躺。

通過梯度下降訓(xùn)練一個端到端的模型。

image

TensorFlow實現(xiàn)

TensorFlow中的概率分布: 概覽

在TensorFlow中概率編程很容易搁痛!

Probabilistic programming made easy!

tfd = tf.contrib.distributions

mean = tf.layers.dense(hidden, 10, None)
stddev = tf.layers.dense(hidden, 10, tf.nn.softplus)
dist = tfd.MultivariateNormalDiag(mean, stddev)

samples = dist.sample()
dist.log_prob(samples)

other = tfd.MultivariateNormalDiag(
    tf.zeros_like(mean), tf.ones_like(stddev))
tfd.kl_divergence(dist, other)

TensorFlow中的概率分布: 回歸的例子

tfd = tf.contrib.distributions
hidden = tf.layers.dense(inputs, 100, tf.nn.relu)
mean = tf.layers.dense(hidden, 10, None)
dist = tfd.MultivariateNormalDiag(mean, tf.ones_like(mean))
loss = -dist.log_prob(label)  # Squared error
optimize = tf.train.AdamOptimizer().minimize(loss)

TensorFlow中的概率分布: 分類的例子

tfd = tf.contrib.distributions
hidden = tf.layers.dense(inputs, 100, tf.nn.relu)
logit = tf.layers.dense(hidden, 10, None)
dist = tfd.Categorical(logit)
loss = -dist.log_prob(label)  # Cross entropy
optimize = tf.train.AdamOptimizer().minimize(loss)

VAE的TensorFlow實現(xiàn): 概覽

tfd = tf.contrib.distributions
images = tf.placeholder(tf.float32, [None, 28, 28])
prior = make_prior()
posterior = make_encoder(images)
dist = make_decoder(posterior.sample())
elbo = dist.log_prob(images) - tfd.kl_divergence(posterior, prior)optimizer = tf.train.AdamOptimizer().minimize(-elbo)
samples = make_decoder(prior.sample(10)).mean()  # For visualization

VAE的TensorFlow實現(xiàn): Prior & encoder

def make_prior(code_size=2):
    mean, stddev = tf.zeros([code_size]), tf.ones([code_size])
    return tfd.MultivariateNormalDiag(mean, stddev)

def make_encoder(images, code_size=2):
    images = tf.layers.flatten(images)
    hidden = tf.layers.dense(images, 100, tf.nn.relu)
    mean = tf.layers.dense(hidden, code_size)
    stddev = tf.layers.dense(hidden, code_size, tf.nn.softplus)
    return tfd.MultivariateNormalDiag(mean, stddev)

VAE的TensorFlow實現(xiàn): 網(wǎng)絡(luò)

def make_decoder(code, data_shape=[28, 28]):
    hidden = tf.layers.dense(code, 100, tf.nn.relu)
    logit = tf.layers.dense(hidden, np.prod(data_shape))
    logit = tf.reshape(logit, [-1] + data_shape)
    return tfd.Independent(tfd.Bernoulli(logit), len(data_shape))

tfd.Independent(dist, 2)告訴TensorFlow將最后兩維視為數(shù)據(jù)維度长搀,而不是批處理維度。

這說明dist.log_prob(images)對每張圖片返回一個數(shù)字而不是每個點鸡典。

正如名稱tfd.independent()所表示源请,它只是將像素對數(shù)概率相加。

VAE的TensorFlow實現(xiàn): 結(jié)果

image

貝葉斯網(wǎng)絡(luò)的TensorFlow實現(xiàn)

def define_network(images, num_classes=10):
    mean = tf.get_variable('mean', [28 * 28, num_classes])
    stddev = tf.get_variable('stddev', [28 * 28, num_classes])
    prior = tfd.MultivariateNormalDiag(
        tf.zeros_like(mean), tf.ones_like(stddev))
    posterior = tfd.MultivariateNormalDiag(mean, tf.nn.softplus(stddev))
    bias = tf.get_variable('bias', [num_classes])  # Or Bayesian, too
    logit = tf.nn.relu(tf.matmul(posterior.sample(), images) + bias)
    return tfd.Categorical(logit), posterior, prior
dist, posterior, prior = define_network(images)
elbo = (tf.reduce_mean(dist.log_prob(label)) -
        tf.reduce_mean(tfd.kl_divergence(posterior, prior))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谁尸,隨后出現(xiàn)的幾起案子舅踪,更是在濱河造成了極大的恐慌,老刑警劉巖良蛮,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抽碌,死亡現(xiàn)場離奇詭異,居然都是意外死亡决瞳,警方通過查閱死者的電腦和手機货徙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皮胡,“玉大人痴颊,你說我怎么就攤上這事÷藕兀” “怎么了蠢棱?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長甩栈。 經(jīng)常有香客問我泻仙,道長,這世上最難降的妖魔是什么谤职? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任饰豺,我火速辦了婚禮,結(jié)果婚禮上允蜈,老公的妹妹穿的比我還像新娘冤吨。我一直安慰自己,他們只是感情好饶套,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布漩蟆。 她就那樣靜靜地躺著,像睡著了一般妓蛮。 火紅的嫁衣襯著肌膚如雪怠李。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天蛤克,我揣著相機與錄音捺癞,去河邊找鬼。 笑死构挤,一個胖子當(dāng)著我的面吹牛髓介,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筋现,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼唐础,長吁一口氣:“原來是場噩夢啊……” “哼箱歧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起一膨,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤呀邢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后豹绪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體价淌,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年森篷,在試婚紗的時候發(fā)現(xiàn)自己被綠了输钩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡仲智,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出姻氨,到底是詐尸還是另有隱情钓辆,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布肴焊,位于F島的核電站前联,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏娶眷。R本人自食惡果不足惜似嗤,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望届宠。 院中可真熱鬧烁落,春花似錦、人聲如沸豌注。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽轧铁。三九已至每聪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間齿风,已是汗流浹背药薯。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留救斑,地道東北人童本。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像系谐,于是被迫代替她去往敵國和親巾陕。 傳聞我的和親對象是個殘疾皇子讨跟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容