资源 | DanceNet:帮你生成会跳舞的小姐姐

选自GitHub

机器之心整理

参与:思源、张倩

最近有开发者尝试构建能自动生成舞蹈动作的深度网络,他们结合了变分自编码器、LSTM 与混合密度网络,并将这一深度网络命名为 DanceNet。该网络的主要思想即使用 VAE 生成单张舞蹈图片,并根据 LSTM 将这些舞蹈图片组合成一系列完整的动作,最后联合训练就能生成非常逼真的舞蹈动作。机器之心也尝试使用了该项目,并能生成还不错的舞蹈视频,感兴趣的读者也可以使用并完善该项目。

项目地址:https://github.com/jsn5/dancenet

主要模块

DanceNet 中最主要的三个模块是变分自编码器、LSTM 与 MDN。其中变分自编码器(VAE)是最常见的生成模型之一,它能以无监督的方式学习复杂的分布,因此常被用来生成图像数据。VAE 非常优秀的属性是可以使用深度神经网络和随机梯度下降进行训练,并且中间的隐藏编码还表示了图像的某些属性。

如下变分自编码器中的编码器使用三个卷积层和一个全连接层,以生成隐藏编码 z 分布的均值与方差。因为 z 服从于高斯分布,因此确定方差与均值后 z 的分布就完全确定了,随后解码器从 z 分布中采样隐藏编码就能解码为与输出图像相近的输出。

input_img = Input(shape=(120,208,1))
x = Conv2D(filters=128,kernel_size=3, activation='relu', padding='same')(input_img)
x = MaxPooling2D(pool_size=2)(x)
x = Conv2D(filters=64,kernel_size=3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=2)(x)
x = Conv2D(filters=32,kernel_size=3, activation='relu', padding='same')(x)
x = MaxPooling2D(pool_size=2)(x)
shape = K.int_shape(x)
x = Flatten()(x)
x = Dense(128,kernel_initializer='glorot_uniform')(x)

z_mean = Dense(latent_dim)(x)
z_log_var = Dense(latent_dim)(x)
z = Lambda(sampling, output_shape=(latent_dim,), name="z")([z_mean,z_log_var])

encoder = Model(input_img, [z_mean, z_log_var,z], name="encoder")

z_mean 和 z_log_var 为编码器编码的均值与方差,z 为从它们确定的分布中所采样的隐藏编码,编码器最后输出这三个变量。以下展示了 Jaison 所采用解码器的架构,其首通过全连接层对隐藏编码 z 执行仿射变换,再交叉通过 4 个卷积层与 3 个上采样层以将隐藏编码恢复为原始输入图像大小。

latent_inputs = Input(shape=(latent_dim,), name='z_sampling')
x = Dense(shape[1] * shape[2] * shape[3], kernel_initializer='glorot_uniform',activation='relu')(latent_inputs)
x = Reshape((shape[1],shape[2],shape[3]))(x)
x = Dense(128,kernel_initializer='glorot_uniform')(x)
x = Conv2D(filters=32, kernel_size=3, activation='relu', padding='same')(x)
x = UpSampling2D(size=(2,2))(x)
x = Conv2D(filters=64,kernel_size=3, activation='relu', padding='same')(x)
x = UpSampling2D(size=(2,2))(x)
x = Conv2D(filters=128,kernel_size=3, activation='relu', padding='same')(x)
x = UpSampling2D(size=(2,2))(x)
x = Conv2D(filters=1,kernel_size=3, activation='sigmoid', padding='same')(x)

decoder = Model(latent_inputs,x,name='decoder')

在训练 VAE 后,我们从高斯分布中采样一个隐藏编码 z,并将其馈送到解码器,那么模型就能生成新的图像。因此我们可以设想给定不同的隐藏编码 z,解码器最终能生成不同的舞姿图像。

最后,我们还需要长短期记忆网络(LSTM)和混合密度层以将这些舞姿图像连接在一起,并生成真正的舞蹈动作。如下 Jaison 堆叠了三个 LSTM 层,且每一个 LSTM 层后面都采用 Dropout 操作以实现更好的鲁棒性。将循环层的输出接入全连接层与混合密度网络层,最后输出一套舞蹈动作每一个时间步的图像应该是怎样的。

inputs = Input(shape=(128,))
x = Reshape((1,128))(inputs)
x = LSTM(512, return_sequences=True,input_shape=(1,128))(x)
x = Dropout(0.40)(x)
x = LSTM(512, return_sequences=True)(x)
x = Dropout(0.40)(x)
x = LSTM(512)(x)
x = Dropout(0.40)(x)
x = Dense(1000,activation='relu')(x)
outputs = mdn.MDN(outputDim, numComponents)(x)
model = Model(inputs=inputs,outputs=outputs)

以下是实践该项目的环境与过程,机器之心也尝试使用了预训练模型,并生成了效果还不错的视频。此外,根据试验结果,VAE 中的编码器参数数量约 172 万,解码器约为 174 万,但 LSTM+MDN 却有 1219 万参数。最后我们生成了一个 16 秒的舞蹈视频:

视频内容

要求:

  • Python = 3.5.2

工具包:

  • keras==2.2.0
  • sklearn==0.19.1
  • numpy==1.14.3
  • opencv-python==3.4.1

如下展示了用于训练的数据集视频:

视频内容

本地实现已训练模型:

  • 下载预训练权重
  • 提取到 dancenet 目录
  • 运行 dancegen.ipynb
  • 预训练权重下载地址:https://drive.google.com/file/d/1LWtERyPAzYeZjL816gBoLyQdC2MDK961/view?usp=sharing

如何在浏览器上运行:

  • 打开 FloydHub 工作区
  • 训练的权重数据集将自动与环境相连
  • 运行 dancegen.ipynb
  • FloydHu 工作区:bhttps://floydhub.com/run
  • 预训练权重:https://www.floydhub.com/whatrocks/datasets/dancenet-weights

从头开始训练:

  • 在 imgs/ 文件夹下补充标签为 1.jpg, 2.jpg ... 的舞蹈序列图像
  • 运行 model.py
  • 运行 gen_lv.py 以编码图像
  • 运行 video_from_lv.py 以测试解码视频
  • 运行 jupyter notebook 中的 dancegen.ipynb 以训练 dancenet 并生成新视频

参考资料:

  • Cary Huang:https://www.youtube.com/watch?v=Sc7RiNgHHaE&t=9s
  • Francois Chollet:https://blog.keras.io/building-autoencoders-in-keras.html
  • 通过 Python 和 Keras 使用 LSTM 循环神经网络构建时序预测模型:https://machinelearningmastery.com/time-series-prediction-lstm-recurrent-neural-networks-python-keras/
  • 使用深度学习的生成编舞:https://arxiv.org/abs/1605.06921
  • David Ha:http://blog.otoro.net/2015/06/14/mixture-density-networks/
  • Charles Martin:https://github.com/cpmpercussion/keras-mdn-layer

本文为机器之心整理,转载请联系本公众号获得授权。

原文发布于微信公众号 - 机器之心(almosthuman2014)

原文发表时间:2018-08-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

深度学习中训练参数的调节技巧

1、学习率 步长的选择:你走的距离长短,越短当然不会错过,但是耗时间。步长的选择比较麻烦。步长越小,越容易得到局部最优化(到了比较大的山谷,就出不去了),而大了...

1.2K80
来自专栏大数据挖掘DT机器学习

R语言主成分和因子分析

主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分。 探索性因子分析(EFA)是一系列用来发现一组变...

53040
来自专栏大数据挖掘DT机器学习

R语言实现主成分和因子分析

主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分。 探索性因子分析(EFA)是一系列用来发现一组变量...

45540
来自专栏机器学习算法工程师

随机采样方法——蒙特卡罗方法

地址:http://www.cnblogs.com/pinard/p/6625739.html

20340
来自专栏大数据挖掘DT机器学习

NLP真实项目:利用这个模型能够通过商品评论去预测一个商品的销量

前言 由于是日语项目,用到的分词软件等,在中文任务中需要替换为相应的中文分词软件。例如结巴分词 : https://github.com/fxsjy/jieb...

713110
来自专栏ATYUN订阅号

用Keras进行深度学习模式的正则化方法:Dropout

Dropout是神经网络和深度学习模型的简单而有效的正则化技术。 在这篇文章中,你将发现Dropout正则化技术,以及如何使用Keras将其应用于Python中...

45050
来自专栏杨熹的专栏

双向 LSTM

本文结构: 为什么用双向 LSTM 什么是双向 LSTM 例子 ---- 为什么用双向 LSTM? 单向的 RNN,是根据前面的信息推出后面的,但有时候只看前面...

75760
来自专栏机器学习算法与Python学习

机器学习(28)【降维】之sklearn中PCA库讲解与实战

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第一 【Python】:排名第三 【算法】:排名第四 前言 在(机器学习(27)【降维】之...

72660
来自专栏Coding迪斯尼

使用RNN和CNN混合的’鸡尾酒疗法’,提升网络对文本的识别正确率

前几节我们详细研究了GRU和LSTM网络层,这两者特点是能够抓取输入数据在时间上的逻辑联系,因此这两种网络特别容易从文本中抓取规律,因为文本是有一个个单词依据前...

11030
来自专栏人工智能头条

如何选择合适的损失函数,请看......

21810

扫码关注云+社区

领取腾讯云代金券