天天看點

深度學習生成舞蹈影片02之MDN代碼練習

閱讀難度:★★★★☆

技能要求:機器學習基礎、Keras、numpy、matplotlib

字數:960字

閱讀時長:5分鐘

本文接上一期,補充一些MDN的代碼練習。本教程開發環境是python+jupyter,引用了一個用keras寫的mdn包,目标是拟合反正弦函數曲線:

y=7.0sin(0.85x)+0.5x+r

該函數在每個點都有多個解,是以要求ANN模型需要有能力處理它的損失函數。 MDN是預測這些多輸出值的好方法。

1

引入相關依賴

import keras
import mdn
import numpy as np
import matplotlib.pyplot as plt           

複制

2

生成模拟資料

#y=7.0sin(0.85x)+0.5x+r
#r标準的高斯随機噪聲

NSAMPLE = 3000

y_data = np.float32(np.random.uniform(-10.5, 10.5, NSAMPLE))

r_data = np.random.normal(size=NSAMPLE)

x_data = np.sin(0.85 * y_data) * 7.0 + y_data * 0.5 + r_data * 1.0

x_data = x_data.reshape((NSAMPLE, 1))

plt.figure(figsize=(4, 4))

plt.plot(x_data,y_data,'ro', alpha=0.3,markersize = 1)

plt.show()           

複制

深度學習生成舞蹈影片02之MDN代碼練習

3

模組化

接下來,我們在Keras中建構MDN模型。 使用了Keras中的Sequential模型,其中MDN層位于一個或多個Dense層之後。 您需要為MDN定義輸出次元和混合狀态的數量,比如:

MDN(output_dimension,number_mixtures)

對于本教程的問題,我們隻需要定義輸出次元為1,因為我們預測的y值次元為1。 添加更多的混合狀态數量會增加更多參數(模型更複雜,需要更長時間訓練),但可能有助于使預測結果更好。 你可以從訓練資料中看到曲線評估混合狀态的數量有5個,是以設定混合狀态的數量N_MIXES = 5是比較好的方式。

對于MDN,我們需定義适合的損失函數,使其可以處理混合狀态參數,損失函數必須考慮輸出維數和混合狀态的數量。

N_HIDDEN = 12
N_MIXES = 6

model = keras.Sequential()

model.add(keras.layers.Dense(N_HIDDEN, batch_input_shape=(None, 1), activation='relu'))

model.add(keras.layers.Dense(N_HIDDEN, activation='relu'))

model.add(mdn.MDN(1, N_MIXES))

model.compile(loss=mdn.get_mixture_loss_func(1,N_MIXES), optimizer=keras.optimizers.Adam())

model.summary()           

複制

網絡結果如下圖所示:

深度學習生成舞蹈影片02之MDN代碼練習

4

訓練模型

history = model.fit(x=x_data, y=y_data, batch_size=128, epochs=500, validation_split=0.2)           

複制

5

可視化

我們通過圖表的方式檢視模型是如何訓練的。 從下圖,我們可以看到,經過一定的訓練後,訓練效果的提升相當緩慢。對于本教程,1.5左右的損失值産生了相當好的結果。

深度學習生成舞蹈影片02之MDN代碼練習

代碼如下:

plt.figure(figsize=(10, 5))
plt.ylim([0,9])
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.show()           

複制

6

預測

現在我們可以通過在x軸上産生3000個均勻間隔點來預測y軸的數值,測試下訓練好的模型。注意,y_test包含分布的參數,而不是圖上的實際點。要在圖上找到點,我們需要從每個分布中進行采樣,采樣後的結果為y_samples。

x_test = np.float32(np.arange(-15,15,0.01))

NTEST = x_test.size

print("Testing:", NTEST, "samples.")

x_test = x_test.reshape(NTEST,1) 

y_test = model.predict(x_test)

y_samples = np.apply_along_axis(mdn.sample_from_output, 1, y_test, 1, N_MIXES,temp=1.0)           

複制

對比下預測結果:

plt.figure(figsize=(4, 4))

plt.plot(x_data,y_data,'ro',x_test, y_samples[:,:,0], 'bo',alpha=0.3,markersize = 1)

plt.show()           

複制

深度學習生成舞蹈影片02之MDN代碼練習

附上keras實作的MDN:

https://github.com/cpmpercussion/keras-mdn-layer