深度学习可以做 Fizz Buzz 吗?

机器算法验证 机器学习 深度学习
2022-03-29 18:57:01

在阅读了Tensorflow 中的 Fizz Buzz笑话后,我很想知道是否可以通过深度学习正确完成如此简单的任务。关于我们可以或我们不能的原因的任何理论解释?

是模运算,如果我们能做 Fizz Buzz,说不定深度学习也可以用在数论中,比如求素数?

2个回答

作为链接博客文章的作者,我很高兴地说(在正确选择超参数和一点运气的情况下)Fizz Buzz 可以完全由具有一个隐藏层的神经网络学习。

我花了一些时间研究它为什么起作用,原因有点有趣。它取决于输入的二进制表示和以下观察:

  • 如果两个数字相差 15 的倍数,那么它们属于同一个 fizzbuzz“类”(as-is / fizz / buzz / fizzbuzz)

事实证明,有多种方法可以将 10 位二进制数中的两位反转并得到一个相差 15 的倍数的数字。例如,如果您从某个数字 x 开始并打开128 位并关闭 8 位,你得到 x + 120。还有很多其他这样的例子。

如果你有一个位的线性函数,将相同的权重放在这两个位上,它将为 x 和 x + 128 产生相同的输出。

由于有很多这样的位对,事实证明神经网络基本上

  • 学习了一堆等价类(例如,一个包含 x、x + 120 和一些其他数字),并且
  • “记住”每个等价类的正确答案

所以事实证明,当你在数字 101 到 1023 上训练模型时,你有足够的等价类来正确预测 1 到 100。

(这并不正式,当然,这只是我调查网络时学到的高级总结。)

--

至于您关于查找素数的问题,如果这样的方法有效,我会感到惊讶。我的感觉是,这个问题的“相同模 15”结构是神经网络工作的原因,很难想到任何类似的东西,例如寻找素数。

让我以模因的方式回答这个问题。

为什么(总是)深度学习?所有神经网络所做的都是线性回归 (x*w+b),在(中间)响应周围具有一些非线性。

深或derp

让我们谈谈机器学习,更好的是,优化。您所指的明显的一般问题是函数逼近(不是回归本身)。那么,为什么不使用专门为此而开发的方法:编写程序从理论上讲,是的,您可以使用“人工智能”方法来创建程序,其中之一,只要有足够的数据和时间,理论上可以是 FizzBu​​zz。或者一个计算素数的程序(理论上该程序在由人类编写时可能是相同的)。-- 这里没有深度学习 --。

从数据中学习

那么,我们可以从数据中学习吗?我们可以。但首先我们需要了解数据设计一些特性因为只有一个数字特征不够表达......(目前)。

一些代码传入:

library(tidyverse)

theData <- data_frame(a = as.double(1:100),
                      a3 = as.double(a %% 3 == 0),
                      a5 = as.double(a %% 5 == 0),
                      cl = case_when((a3 > 0) & (a5 > 0) ~ 'FizzBuzz',
                                     a3 > 0 ~ 'Fizz',
                                     a5 > 0 ~ 'Buzz',   
                                     TRUE ~ 'Number')) %>%
  mutate(cl = factor(cl))

现在我们有一个数字特征 a(数字)和 a3 和 a5 帮助决定......

在此处输入图像描述

……(╯°□°)╯︵ ┻━┻ 在这里又不是深度学习。但是一个堆叠模型:第一层是 DT,第二层是(使用 Viola-Jones-Cascades 或对Number响应进行简单过滤)一个简单的旧线性回归,解y=a

先说DT:

treeModel <- rpart::rpart(cl ~ ., theData, 
                          control = rpart::rpart.control(minsplit = 5))
rattle::fancyRpartPlot(treeModel, caption = '')

在此处输入图像描述

太疯狂了一个简单的决策树学会了 FizzBu​​zz!但是做到了吗?应用一些测试数据:

testData <- data_frame(a = as.double(200:300),
                      a3 = as.double(a %% 3 == 0),
                      a5 = as.double(a %% 5 == 0),
                      cl = case_when((a3 > 0) & (a5 > 0) ~ 'FizzBuzz',
                                     a3 > 0 ~ 'Fizz',
                                     a5 > 0 ~ 'Buzz',   
                                     TRUE ~ 'Number'))

predictions <- predict(treeModel, testData, type = 'class')
table(testData$cl, predictions) 


        predictions
         Buzz Fizz FizzBuzz Number
Buzz       14    0        0      0
Fizz        0   27        0      0
FizzBuzz    0    0        7      0
Number      0    0        0     53

非常适合数字 200 到 300 的测试集!

好吧,第二层很简单:

lmModel <- lm(arep ~ a - 1, mutate(theData, arep = a))

估计数字的误差是

testData %>%
  mutate(pred = predict(treeModel, ., type = 'class')) %>%
  filter(pred == 'Number') %>%
  mutate(apred = predict(lmModel, .),
         error = a - apred) %>%
  pull(error) %>%
  summary()

     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
5.684e-14 5.684e-14 5.684e-14 5.684e-14 5.684e-14 5.684e-1

......非常接近0。多田!

我们从数据中学习了 FizzBu​​zz!

学习

也许你可以用深度学习做同样的事情。您还可以使用 LSTM 层和卷积进行堆叠模型(你知道,因为模 3 和 5),并且使用大量数据,您可能有机会概括一些模式......是的......不。

所以希望这个答案有助于澄清是的,这是可能的。不,你不需要深度学习来完成这项工作。a而现在,即使是深度学习也无法从单一特征学习 FizzBu​​zz。

至于素数……如果您计算/设计与素数一样多的特征,您也可以从数据中学习它们。¯_(ツ)_/¯