谷歌发布AI涂鸦,用机器学习生成巴赫风格音乐

2019 年 3 月 21 日

谷歌发布AI涂鸦,用机器学习生成巴赫风格音乐

3月21日,为了纪念著名作曲家及管风琴、小提琴、大键琴演奏家约翰•塞巴斯蒂安•巴赫的生日,谷歌推出了纪念版谷歌涂鸦。这不是一个简单的动画或者互动游戏,而是谷歌历史上第一个用到了AI的涂鸦作品。利用机器学习,只要你在乐谱上随意点击添加上几个音符,AI就可以自动为你生成一段“巴赫风”的和弦。除了线上欣赏之外,你还可以把这一小段音乐的MIDI文件下载下来。


巴赫 AI 涂鸦是谷歌内部的 Doodle、Magenta 和 PAIR团队合作的成果。Magenta 团队的使命是帮助人们使用机器学习创作音乐和艺术,PAIR 负责提供工具和经验,让每个人都能享受机器学习带来的好处。


创建 AI 涂鸦的第一步是构建一个机器学习模型。机器学习是通过展示大量示例来教会计算机自行找到答案的过程,而不是给它一堆要遵循的规则(传统计算机编程是这样做的)。Magenta 的 AI 研究员 Anna Huang 开发了 Coconet,这是一种可以用于各种音乐任务的机器学习模型,如调整旋律,在断开的音乐片段之间创建平滑过渡,以及从零开始编曲。


接下来,我们将模型个性化以匹配巴赫的音乐风格。为此,我们用巴赫的 306 首协奏曲训练 Coconet。他的协奏曲总是有四种声音:每种声音都有自己的旋律线,在一起演奏时会产生丰富的和声。这种简洁的结构使旋律线成为机器学习模型的良好训练数据。因此,当你在 Doodle 中模型上创作自己的作品时,它会匹配成巴赫风格的旋律。


Doodle 中除了艺术和机器学习元素之外,我们还需要大量服务器以确保世界各地的人们都可以使用 Doodle。从历史上看,机器学习向来在服务器上运行,这意味着信息需要从一个人的计算机发送到数据中心,然后再将结果发送回计算机。如果巴赫 Doodle 使用相同的方法,会产生大量 traffic。


为了实现这一目标,我们使用了 PAIR 的 TensorFlow.js,它让机器学习可以完全在互联网浏览器中进行。但是,可能有的人的计算机或设备使用 TensorFlow.js 运行 Doodle 会不够快,所以机器学习模型在谷歌的新 TPU 上运行,这是一种快速处理数据中心机器学习任务的方法。Doodle 首次以这种方式使用 TPU。


机器学习模型 Coconet


Magenta 的博客文章中介绍了 Coconet 的详细信息:


3 年前,当 Magenta 成立时,我们就开始研究这个模型。当时我们用机器学习(ML)只能生成旋律。为了让旋律更好听,我们用 Bach 的 306 首协奏曲数据集来训练机器学习模型,生成巴赫风格的音乐。


Coconet 受过训练后可以从片段中复原巴赫的音乐:我们把巴赫音乐的一小段取出来,随机删除一些音符,然后让模型根据上下文猜出丢失的音符。结果,我们得到一个多功能的对位模型,把任意不完整的乐谱作为输入,并得出完整的乐谱。这个设置涵盖了广泛的音乐任务,例如协奏曲旋律、创建平滑过渡、重写和改编,以及从零创作。


传统模型从始至终都是按时间顺序生成音符,但 Coconet 可以从任何地方开始,并以任何顺序创建音符。这种灵活性使其成为理想的支持组合过程的工具。音乐家将其用于工作的一种方法是让 Coconet 反复填写乐谱,取其精华,去其糟粕,最终得到一首好听的曲子。实际上,这就是 Coconet 的内部工作机制:循环生成音符,反复重写并删除自己的工作。从粗略的想法开始,它会反复计算细节,并将音符调整为一个连贯的整体。


下面的动画展示了重写的过程:



我们展示了两个 Coconet 创作的来自巴赫协奏的旋律,这些旋律未包含在训练集中。


我们还构建了一个名为Coucou的扩展接口,可以与 Coconet 进行更一般的交互。它支持一种新的 AI 协作生成,你可以通过擦除不满意的部分并要求模型再次填充来迭代地改进音乐作品。你可以反复单击填充得到不同的音符。试试下面的例子或在页面上随机抽取音符开始,自己动手尝试一下。你还可以使用Magenta.js中现有的 JavaScript 自行创建接口。



它是如何工作的?


Coconet 获得不完整的乐谱并填写缺失的部分。为了训练,我们以第四对位的巴赫协奏曲数据集作为例子,随机擦除一些音符,并要求模型重建被擦除的音符。巴赫的创作与 Coconet 的生成方法之间的区别为我们提供了学习信号,我们用它训练模型。


通过随机擦除笔记,我们希望获得一个可以处理任意不完整输入的模型。



就我们的目的而言,“乐谱”是个三维物体。巴赫的协奏曲为四种声音而写:女高音(S)、中音(A)、男高音(T)和低音(B)。每种声音的音符都用钢琴卷帘表示:二维阵列中时间为横轴,音调为纵轴。假设每个声音在任何给定时间都只唱一个音高。因此,通常对于每个声音,在每个时间点,我们会得到一个独热音调矢量,除了指示音高的单个音符,其他元素全部为零。在存在不确定性的情况下(例如,在模型输出中),该音调向量将包含音高的分类概率分布。


我们将这堆钢琴卷帘视为卷积特征图,时间和间距形成二维卷积空间,每个声音提供一个通道。由于模型训练所用的乐谱不完整,我们为每个语音提供一个额外的通道,带有一个掩码:二进制值,标记每个时间点是否已知该语音的音高。因此,模型中使用的是一个八通道功能图。



该模型是一个相当简单的卷积神经网络,具有批归一化和残余连接。对于使用 Tensorflow.js 实现在浏览器中运行模型的 Doodle,我们能够通过切换到深度可分离的卷积来加速计算。这与常规卷积的不同之处在于,它们将空间轴上的卷积和通道轴的混合分开。它们需要的参数更少,更适合在浏览器中加速。由于卷积扩张,我们得以在减少模型中的层数实现进一步加速的同时,保证性能无损。


模型又生成一堆钢琴卷帘,每种声音有一个钢琴卷帘,但这次包含了在删除音符的音高上的概率分布。该模型使用给出的音符来找出被删除的音符,从而得出在每个时间点由每个音调演唱的音高上的分类分布。


我们训练模型让真正的音高概率分布更大,让模型理解不完整乐谱的音乐含义,如这是什么音调,在某一时间是哪个和弦等。


经过训练后,我们有几种方法从模型产生的概率分布中提取音乐。我们可以根据其分布同时对每个音高进行采样。但是,这并不能解释被采样的音高之间的相互作用。通常,确定其中一个音高会改变其他音高的分布。


考虑到这些相互作用的一种方法是对其中一个音高进行采样,将其添加到不完整的乐谱,并把结果再次“喂”给模型,重新计算剩余音高的分布。重复此过程,直到确定所有音高,在考虑所有交互的情况下完成乐谱。这样的顺序采样让模型能够逐一准确地确定未知的音高。当模型被自己的创作搞晕时,这种“坚定”的假设常常导致过程出错。


因此,我们用另一种方法取而代之:将模型的输出视为草稿,通过重复重写逐步完善。具体来说就是,我们同时对所有音高进行采样,获得完整(但通常是无意义的)乐谱,然后将部分音符擦除后再次输入到模型中,之后重复这一过程。随着时间的推移,我们擦除并重写的音符越来越少,最终得到较为一致的结果。


致谢


本篇博文基于由 Cheng-Zhi Anna Huang、Tim Cooijmans、Adam Roberts,Aaron Courville 和 Douglas Eck 撰写的论文。研究论文中的Tensorflow代码可在Magenta GitHub中获得。


参考链接:


https://magenta.tensorflow.org/coconet


https://www.blog.google/technology/ai/honoring-js-bach-our-first-ai-powered-doodle/



2019 年 3 月 21 日 17:524553
用户头像

发布了 98 篇内容, 共 54.8 次阅读, 收获喜欢 283 次。

关注

评论

发布
暂无评论
发现更多内容

微信推文无缝滚动是这样炼成的

喵喵

微信 前端开发 微信公众号 微信推文 图文混排

好的软件工程原则

pydata

python实现·十大排序算法之计数排序(Counting Sort)

南风以南

Python 排序算法 计数排序

Android原生人脸识别Camera2+FaceDetector 快速实现人脸跟踪

sar

你真的会用Mac中的Finder吗

Winann

macos 效率 App Mac

管理规划篇

姜戈

团队管理 团队组织

在 Go 中使用并发编程 - 第二部分

TuringTuring

golang 并发编程 协程 线程模型

OBS推流学习笔记

Tango

直播 OBS 推流 B站直播

使用 Markdown 制作五线谱

Roc

GitHub markdown 五线谱

ARTS week 1

时之虫

ARTS 打卡计划

2020年下半年计划

Tango

年度计划

源码分析 | Mybatis接口没有实现类为什么可以执行增删改查

小傅哥

Java 源码分析 小傅哥 mybatis 编程思维

假如孔乙己是程序员

顿晓

学习 程序员 孔乙己

软件开发生产率改进之我见(二)

清水

软件工程 软件开发 技术管理

数据与广告系列三:合约广告与与衍生的第三方广告数据监控

黄崇远@数据虫巢

数据挖掘 互联网 广告 移动互联网

栀子花,我们应该像你一样静静绽放

小天同学

个人感想 感悟 日常思考

ARTS week 2

锈蠢刀

Spring Security 两种资源放行策略,千万别用错了!

江南一点雨

Java spring springboot springsecurity

教师节H5案例制作思路分享

喵喵

前端开发 H5游戏

2020全球首创币期权DAPP智能合约强势来袭,闪耀数字经济

极客编

财富的大门给我开了一条缝

YoungZY

读书笔记 读书

提升输入效率第一步——切换双拼

dongh11

效率工具 提升效率 生产力 分享 有趣

点击劫持:无X-Frame-Options头信息(修复)

唯爱

健身一周年:持续锻炼带来无法想象的改变

Breeze

学习 职业 专注 健身

写给产品经理的信(4):你一定要做产品经理么?

夜来妖

生涯规划 产品 程序人生 产品经理 职业规划

使用<input>标签实现六个格子验证码输入框

brave heart

Java vue.js 前端

你为什么“啃不动”你手中的技术书?

图灵社区

Java Python 算法 HTTP R语言

Windows10 如何正确修改本地用户的名称及目录

喵喵

windows Windows 10 电脑故障 Windows技巧

RASP研发踩坑之agent 加载机制(1)

国服第一

Java JVM 类加载 RASP

redis过期策略和内存淘汰机制

wjchenge

宕机原因千千万,被雷劈了最无奈

田晓旭

谷歌发布AI涂鸦,用机器学习生成巴赫风格音乐-InfoQ