AlphaGo戰勝了人類最強棋手,但前提是它先學會了人類棋譜,離不開人類指導。
接著谷歌又推出了AlphaGo Zero,只讓AI知道圍棋規則,從零開始學下棋,結果再次登上棋藝頂峰。
AI既然能從零學習圍棋,是否可以從零開始摸索機器學習算法?當然可以,谷歌大腦團隊最新的研究成果已經做到了。
谷歌將這種技術稱之為AutoML-Zero,意為“從零開始的自動機器學習”,已經在GitHub開源,并在Arxiv上提交了論文。
而且這一研究還是來自谷歌大腦的Quoc V.Le大神之手。
AutoML-Zero僅使用基本數學運算為基礎,從一段空程序開始,即可自動發現解決機器學習任務的計算機程序。
AutoML Zero能發現什么
AutoML是一種實現從數據集到機器學習模型的自動化方法,讓你無需高深專業知識,就能自動部署ML模型。
雖說是自動,但現階段的AutoML還要對搜索空間進行很大的限制,這使我們在使用AutoML的時候仍然需要一些專業知識去設計神經網絡的層。
谷歌的目標是讓AutoML可以走得更遠,僅僅使用基本的數學運算作為構建塊,就可以自動發現完整的機器學習算法,進一步降低機器學習的門檻。
盡管AutoML-Zero巨大的搜索空間充滿挑戰性,但進化搜索還是能發現具有梯度下降的線性回歸算法、具有反向傳播的二層神經網絡。
值得注意的是,可以AutoML-Zero的進化過程也是一個不斷“發明”的過程解釋進化的算法,它已經找到了雙線性交互、權重平均、歸一化梯度、數據增強等技術,甚至在某些情況下還發現了類似Dropout的算法。
下面我們先來看看,AutoML在CIFAR-10的二元分類任務上是如何一步步進化的。它首先發現了線性回歸,然后找到了損失函數、梯度下降。
隨著訓練的進行,出現了隨機學習率、隨機權重、激活函數ReLU、梯度歸一化,最后得到了84.06 ± 0.10%正確率的終極算法。
只訓練一個二元分類結果還不太具有說服力,作者又用3種極端情況考察了Auto ML。
首先,當樣本數量很少的時候,在80個樣本上運行100個epoch。AutoML竟然進化出另一種適應性算法,給輸入數據加上了噪聲,并開始使用Dropout來訓練模型。
在快速訓練的情況下,只有800個樣本和10個epoch,結果導致學習率衰退反復出現,這是一個我們在快速訓練訓練機器學習模型中常見的策略。
至于多類別的分類問題,作者使用了CIFAR-10數據集的所有10個類。AutoML進化算法有時會使用權重矩陣的變換平均值作為學習速率。甚至作者也不知道為什么這種機制會更有利于多類任務,雖然這種結果在統計學上是顯著的。
上面的所有測試整個過程中,人類沒有告訴程序任何先驗的機器學習知識。
演示
現在谷歌將AutoML-Zero的程序提交到GitHub,普通電腦只需5分鐘就能體驗一下它的實際效果。
安裝好Bazel后,將代碼下載到本地,運行其中的demo程序:
git clone https://github.com/google-research/google-research.git
cd google-research/automl_zero
./run_demo.sh
這個腳本在10個線性任務上運行進化搜索。每次實驗后,它都會評估在100個新的線性任務中發現的最佳算法。一旦算法的適應度大于0.9999,就選擇該算法作為最終結果,將代碼打印在屏幕上。
在普通電腦上使用CPU在5分鐘內就能發現類似于梯度下降進行線性回歸的程序:
found:
found:
def Setup():
s3 = -0.520936
s2 = s2 * s3
s2 = dot(v1, v1)
v2 = s2 * v1
s2 = s3 * s2
v1 = s0 * v2
s2 = s0 - s3
s2 = -0.390138
v2 = s2 * v0
s1 = dot(v1, v0)
def Predict():
s2 = -0.178737
s1 = dot(v1, v0)
def Learn():
s1 = s1 * s2
s3 = s3 * s2
s2 = s0 * s2
s1 = s1 - s2
v2 = s1 * v0
v1 = v2 + v1
v2 = s3 * v0
v1 = v2 + v1
由人工設計的ML算法是,有興趣的話,你可以比較這兩段程序的差異。
def Setup():
s2 = 0.001 # Init learning rate.
def Predict(): # v0 = features
s1 = dot(v0, v1) # Apply weights
def Learn(): # v0 = features; s0 = label
s3 = s0 - s1 # Compute error.
s4 = s3 * s1 # Apply learning rate.
v2 = v0 * s4 # Compute gradient.
v1 = v1 + v2 # Update weights.