raspberry pi_Go和Raspberry Pi如何助力钢琴演奏AI

raspberry pi

Dan Tepfer在NPR上的钢琴世界启发了我探索自己的增强钢琴演奏世界。 我可以编写一个可以实时学习的程序,以自己的演奏中的音乐表现来即兴演奏吗?

以下文章是有关制作PIanoAI的逐个过程。 如果您只想尝试PIanoAI, 请访问GitHub以获取说明和下载 。 否则,请留在这里,了解我的许多编程愚蠢。

灵感

在观看Dan Tepfer在NPR上的视频后 ,我抓起了他计算机的静止画面,并得知他使用Processing软件连接到了他的(非常漂亮的)MIDI键盘。

我很容易设法用自己的(而不是花哨的)MIDI键盘来组合类似的东西

正如视频中所解释的那样,Dan的增强型钢琴演奏基本上可以使您以指定的模式镜像或呼应某些音符。 他的许多音乐风格似乎与歌曲有关。 考虑了一下之后,我决定对某种不同的东西感兴趣:我想要一个钢琴伴奏,它可以实时学习以模仿我的风格,并在我自己演奏任何歌曲的空间中即兴创作。

我不是第一个制作钢琴AI的人。 Google制作了AI Duet ,这是一个很棒的程序。 但是我想看看是否可以制作出专门针对自己风格的AI。

人工智能之旅

我的设备没什么特别的。 我从一个放弃学习钢琴演奏的人那里买来的。 几乎任何MIDI键盘和MIDI适配器都可以。

我通常需要至少做两次以使其正确。 我还需要清楚地画出所有内容,以完全了解我在做什么。 那么,我编写程序的过程基本上如下:

  1. 画在纸上。
  2. 用Python编程。
  3. 重来。
  4. 再次将其画在纸上
  5. 在Go中编程。
Notes

前两页(共12页)用于弄清楚我在做什么

每次我在纸上提出想法时,大约需要三张纸才能真正形成想法。

用Python编写钢琴AI

知道自己在做什么之后,便用一组Python脚本实现了所有功能。 这些脚本基于Pygame构建,对MIDI有很好的支持。 这个想法很简单-有两个线程:节拍器和监听器。 收听者仅记录主持人演奏的音符。 节拍器滴答作响并在队列中播放任何音符,或者如果队列中没有音符,则要求AI发送一些新的音符。

我将其设置为可插拔的,因为您可以对AI进行变体,以便可以轻松地为其配备不同的钢琴配件。 有一种简单的回声算法,一种用于在和弦结构中弹奏音符(确定和弦后),另一种用于从马尔可夫链生成钢琴乐曲。 这是我使用该算法的较新版本播放的电影(当我的右手离开键盘时,AI开始播放,直到我再次播放):

我的第一个钢琴演奏AI

我有几件我不喜欢的事情。 首先,这不好。 最好的情况下,钢琴AI伴奏听起来像是一个小孩在努力模仿我自己的演奏(我认为有两个原因,其中基本上不考虑速度数据和过渡时间)。

其次,这些Python脚本在Raspberry Pi上不起作用。 该视频是使用Windows与我一起拍摄的。 我不知道为什么 我在Python 3.4上遇到了麻烦,因此我升级到3.6。 使用Python 3.6时,我仍然遇到奇怪的问题。 pygame.fastevent.post有效,但pygame.fastevent.get无效。 我为此举手,找到了另一种选择。

另一种方法是在Go中编写此代码。 Go明显比Python快 ,这非常有用,因为这是一个低延迟的应用程序。 我的耳朵分辨出20毫秒的差异,因此我想将处理时间降到最短。 我找到了Go MIDI库,因此移植非常可行。

在Go中编写钢琴AI

我决定简化一下。 我不会用很多不同的算法来制作模块,而是专注于我最感兴趣的模块:一个程序,它可以实时学习以在我自己的演奏中即兴发挥 我拿出更多纸开始。

第一天

大多数代码与我以前的Python脚本大致相同。 在Go语言中编写代码时,我发现生成线程比使用Python容易得多。 线程遍布该程序。 有用于监听MIDI的线程,用于演奏音符的线程和用于跟踪音符的线程。 我很想在线程中使用全新的Go 1.9 sync.Map ,但是我意识到我可以利用maps的地图,这超出了sync.Map的复杂性。 尽管如此,我还是制作了一个地图地图,该地图类似于我编写的另一个同步地图存储( schollz / jsonstore )。

我试图使所有内容都达到一流(双关语意),所以我将组件(MIDI,音乐,AI)实现为具有自己功能的对象。 到目前为止,MIDI监听效果很好,并且响应速度很快。 我还实现了播放功能,该功能也可以使用。 这很容易做到。

第二天

我首先将所有代码重构到文件夹中,因为我想为每个对象保留New函数。 物体已经固化; 这里有一个用于学习和生成弹奏的AI,一个用于钢琴音符模型的Music对象,一个用于与MIDI通信的Piano对象以及一个用于将所有内容组合在一起的Player对象。

我花了大量时间在笔和纸上,弄清楚了AI应该如何工作。 我意识到用钢琴音符制作马尔可夫链的方法不止一种。 钢琴音符具有四个基本属性: 音高力度持续时间延迟 (到达下一个音符的时间)。 钢琴音符的基本马尔可夫链将包括四个不同的马尔可夫链,每个属性对应一个。 可以这样说明:

markov chain for piano properties

钢琴特性的基本马尔可夫链。

在此,根据前一音符(P1)的音高来确定下一音符(P2)的下一音高。 速度(V1 / V2),持续时间(D1 / D2)和滞后(L1 / L2)相似。 实际的马尔可夫链仅枚举每个属性值的相对出现频率,并使用随机选择器选择一个属性。 但是,钢琴的属性不一定是独立的。 有时,音高和速度之间或音符的速度和持续时间之间存在关系。 为了解决这个问题,我允许使用不同的耦合。 您可以将属性耦合到任何其他属性的当前值或最后一个值。 目前,我只允许两个耦合,因为这很复杂。 但从理论上讲,您可以将下一个音高的值与上一个音高,速度,持续时间和滞后值相结合。

从理论上弄清一切之后,我便开始实施AI。 AI只是马尔可夫链,因此它确定了音符属性的相对频率表,并具有根据累积概率和随机数来计算它们的功能。 在深夜,它奏效了! 好吧,有点...这是一个愚蠢的视频,我在舔它,然后弹奏AI钢琴:

使用基本的马尔可夫链进行钢琴伴奏的示例。

看来我明天还有更多需要改进的地方。

第三天

我找不到任何改进。 但是也许我昨天尝试过的耦合不好。 我最感兴趣的耦合可以这样可视化:

Markov chain with coupling

具有许多耦合的钢琴特性马尔可夫链的一个示例。

在这种耦合中,前一个音高决定下一个音高。 下一个速度由先前的速度当前音高确定。 当前音高还决定持续时间。 当前持续时间确定当前滞后。 这需要以正确的顺序(音高,持续时间,速度,滞后)进行评估,而这取决于用户,因为我不想对树遍历进行编程。

好吧,我试过了,听起来很糟糕。 我对结果感到非常失望。 考虑到我可能需要尝试不同的机器学习,我决定公开我的仓库。 也许有人会找到它并接管我,因为我不确定我会继续努力。

第四天

考虑了一下之后,我决定尝试一个神经网络(commit b5931ff6 ),至少可以这么说,它表现不佳。 我也尝试了几种变体:成对输入笔记,每个属性单独输入或所有属性作为矢量输入。 这听起来不太好; 时间到了,笔记到处都是。

我还尝试了一个神经网络,在该网络中,我发送了整个键盘的布局(提交20948dfb ),然后将其转换为键盘布局。 听起来很复杂,因为我认为确实如此,而且似乎也不起作用。

我注意到神经网络的最大问题是很难获得随机性。 我尝试将随机列作为随机向量引入,但它会创建太多虚假注释。 一旦开始AI钢琴舔,它似乎陷入了局部最小值,并且在此范围之外没有太多探索。 为了使神经网络起作用,我必须做Google要做的事情,并尝试深入学习什么是“旋律”,什么是“和弦”以及什么是“钢琴”。 啊。

第五天

我放弃。

我没有放弃。 但是,当我在森林中奔跑时,我不禁重新考虑了整个项目。

真的是什么AI? 它应该发挥我的智力水平吗? 我玩游戏时的智力水平是多少? 当我考虑自己的智力时,我意识到: 我不是很聪明!

是的,我是一个简单的钢琴演奏者。 我只是以属于和弦的音阶弹奏音符。 我喜欢时会混入一些小段即兴演奏。 实际上,我考虑得越多,我意识到我的钢琴即兴演奏就好比将我重复使用或重复复制或拼接的小段即兴演奏连在一起。 因此,钢琴AI应该做到这一点。

more notes, smaller page

我记了一些笔记以收集想法,但是这次我使用了一个较小的页面。

我把这个想法写在必要的纸上,然后回家编程。 基本上,此版本的AI是另一种马尔可夫方案,但大于一阶(即,记住的不仅仅是最后的音符)。 马尔可夫转换应该将较大的音节链接起来,即所谓的即兴即兴(即基于我的演奏历史)。 我为此实现了一个新的AI(提交bc96f512 )并进行了尝试。

第六天

有没有搞错! 今天有人将我的钢琴AI应用于产品搜寻 。 哦,男孩,我几乎-但不是完全-完成了,所以我希望今天没有人尝试。

product hunt screen shot

我很高兴能参加Product Hunt,但我希望我能先完成。

有了新的思路,我发现了许多容易解决的问题:

我添加了命令行标志,因此可以开始使用了,它实际上可以工作! 以下是我教学大约30秒然后出现干扰的视频:

我对该项目获得了很多反馈。 这个Hacker News的讨论很有启发性。 以下是一些值得注意的示例:

如果您还有其他想法或问题,请告诉我。 鸣叫@yakczar

本文最初发表在Raspberry Pi AI上 ,经许可转载。

翻译自: https://opensource.com/article/17/10/making-raspberry-pi-powered-ai-play-piano

raspberry pi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值