iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
0
自我挑戰組

深度學習所需入門知識--一位初學者的認知系列 第 25

由 MLP 看機器學習導入策略

  • 分享至 

  • xImage
  •  

延續昨日從無到有以 Mxnet 實作出 MLP,Fields 再拋出以 Gluon 的實作:

from __future__ import print_function
import numpy as np
import mxnet as mx
from mxnet import nd, autograd, gluon

ctx = mx.gpu() if mx.test_utils.list_gpus() else mx.cpu()
data_ctx = ctx
model_ctx = ctx
#這三行目的:只要測試有CUDA GPU就使用它

batch_size = 64
num_inputs = 784
num_outputs = 10
num_examples = 60000
def transform(data, label):
    return data.astype(np.float32)/255, label.astype(np.float32)
train_data = mx.gluon.data.DataLoader(mx.gluon.data.vision.MNIST(train=True,
           transform=transform), batch_size, shuffle=True)
test_data = mx.gluon.data.DataLoader(mx.gluon.data.vision.MNIST(train=False,
           transform=transform), batch_size, shuffle=False)
#在初始值與訓練資料取得,基本上完全一樣

在神經網路模型的設定簡潔許多,與Tensorflow 相較,我們可以考慮在 forward() 下輸出一些訊息,幫助我們診斷我們的模型設計是否正確?

class MLP(gluon.Block):
    def __init__(self, **kwargs):
        super(MLP, self).__init__(**kwargs)
        with self.name_scope():
            self.dense0 = gluon.nn.Dense(64)
            self.dense1 = gluon.nn.Dense(64)
            self.dense2 = gluon.nn.Dense(10)

    def forward(self, x):
        x = nd.relu(self.dense0(x))
        x = nd.relu(self.dense1(x))
        #如果需要進一步查網路在這一層的輸出值來偵錯,可考慮加下一行 
        print("Hidden Representation 2: %s" % x)
        x = self.dense2(x)
        #如果需要進一步查網路輸出值來偵錯,可考慮加下一行 
        print("Network output: %s" % x)
        return x

我們可以開始以MNIST 資料集來訓練MLP,一樣需要初始參數。

net = MLP()
net.collect_params().initialize(mx.init.Normal(sigma=.01), ctx=model_ctx)

data = nd.ones((1,784))
net(data.as_in_context(model_ctx))

到現在為止 MLP 的網路定義多少還是為了展示我們可以很輕易的設計新的模型,多少還是很囉唆。如同 Keras,Gluon 也提供自己的Sequential class 讓開發可以堆疊自己的網路:

num_hidden = 256
net = gluon.nn.Sequential()
with net.name_scope():
    net.add(gluon.nn.Dense(num_hidden, activation="relu"))
    net.add(gluon.nn.Dense(num_hidden, activation="relu"))
    net.add(gluon.nn.Dense(num_outputs))
net.collect_params().initialize(mx.init.Normal(sigma=.1), ctx=model_ctx)

先前自己設計落落長的 MLP Class 其實只要用 net.add(…) 一層一層加上來即可。後面無論是我們自己設計落落長的 MLP Class 還是用 Sequential class 的 net.add(…),都一樣,要有損失函數,要跑 mini-Batch,當然一堆超參數也要設定:

softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': .01})

#這個函數昨天刻意忽略,其目的讓訓練過程每個Iteration的準確度進展能呈現出來
def evaluate_accuracy(data_iterator, net):
    acc = mx.metric.Accuracy()
    for i, (data, label) in enumerate(data_iterator):
        data = data.as_in_context(model_ctx).reshape((-1, 784))
        label = label.as_in_context(model_ctx)
        output = net(data)
        predictions = nd.argmax(output, axis=1)
        acc.update(preds=predictions, labels=label)
    return acc.get()[1]

epochs = 10
smoothing_constant = .01

for e in range(epochs):
    cumulative_loss = 0
    for i, (data, label) in enumerate(train_data):
        data = data.as_in_context(model_ctx).reshape((-1, 784))
        label = label.as_in_context(model_ctx)
        with autograd.record():
            output = net(data)
            loss = softmax_cross_entropy(output, label)
        loss.backward()
        trainer.step(data.shape[0])
        cumulative_loss += nd.sum(loss).asscalar()

    test_accuracy = evaluate_accuracy(test_data, net)
    train_accuracy = evaluate_accuracy(train_data, net)
    print("Epoch %s. Loss: %s, Train_acc %s, Test_acc %s" %
          (e, cumulative_loss/num_examples, train_accuracy, test_accuracy))

最後測試跑了一下程式,準確度還能接受。Gavin 驚訝得很,原先他預期會看到很多 openCV 的函數來抓圖檔的一些影像特徵,結果完全就只靠輸入每個點的0到255灰度即可。Moore幫忙解釋,這些原來要經由專家定義出來的特徵值,似乎就存在於隱藏層裡,在最佳化一次又一次迭代計算過程,得到最佳解後,隱藏層每個單元的值,某些角度就是人類不容易解釋的特徵值。


在『AI探索專案』的第一個 Sprint, Fields 認領 提昇專案成員AI 所需數學知識與對應Python程式,短短兩週,自己了解了機器學習的基礎理論外,還要提昇其他人的知識。所以咬著牙花了幾天跟大家講解囉哩囉唆的一堆數學推導。佳麗耐著性子聽完,等到程式跑完,她表達了意見:

“我覺得全部只有 Goldilocks Rule 是我理解的,我們現在只有最基礎的深度學習模型MLP吧?我看了一下,除了最開始已經知道的學習率,Epoch,Batch Size 等是靠金髮姑娘原則,慢慢抓出『適當』值,剛剛程式裡我也看到 深度要多少層(程式寫的是兩層),每層要多少的單元(寫的是每層都採256單元),我願意猜,這一定又是要靠 Goldilocks Rule。

“再細想,數學別人已經可能幾年前都證明了,甚至許多框架也都開發對應的程式庫提供函數讓我們呼叫,我沒法揣摩出在這裡面我們要加值什麼!”

Gavin 幫忙回答:
”我們這個『AI探索專案』目標之一,不就是要探索我們可以加值什麼!現在沒有答案沒關係,慢慢的我們會找到的。Pete 能說說你的觀察嗎?”

Pete:
”我從 Fields 的講解還有我自己研讀的心得,我認為有三個層次來談:

  1. 要創造出新模型或改良原有模型的人,很需要數學或是演算法的底子。
  2. 能找到合適模型,經由調整超參數來有效訓練模型以滿足需求的人。
  3. 能針對模型的需要,提供或是標示有效的資料集的人。

這三個層次我觀察我們專案剛好都有人才可以進行。另外還有一種人,能判斷需求或問題需要用機器學習來解決,並適度的投入資源。這個大約就是大老闆Servo的活吧?

Molly 加入討論:
“剛剛Pete 所談的第1.項,我擔心以現有成員的經驗來進行,緩不濟急。Fields 短短兩週內有這樣成果是蠻厲害的,但是要作到有效益,研判非要兩三年的摸索。”

Gavin:”以 Product Owner 角度來看,我們專案是『AI探索』,可見成事不必在己,我們如果真能遇到需求是需要發明新的或改良模型,有方向後,也許再去物色合作對象也可以。但是我們要有人可以理解基礎理論,這樣才有辦法與專家對談,所以 Fields 你還是要堅守這個領域。倒是第2.項,我直覺對我們這些人才來說,應用現有模型來訓練,門檻不會高到無法跨過,但是廣度就變成問題了。”

Moore這幾日也有心得:”是的除了先前我們討論過OS, 程式語言,機器學習框架外,不同的問題就會有對應的網路模型來解決,我看到現在有啥 CNN,RNN, Reinforcement Learning, GAN 等等,每一個都有相當的理論基礎還有實作的細節要考慮,我們臂多力分了!”

Cash 聽到 Reinforcement Learning 趕快補充:”我看一些文章,要用Reinforcement Learning 訓練電腦來打怪,除了 GPU 有要求,RAM 居然要100GB 以上呢,這個我要趕快採購,趕緊試試看!”

佳麗瞪了Cash 一下:”我們等大後天的 Sprint Review會議,趁機了解 Servo 與 RJ 真正的需求再聚焦吧!建議現在我們還是維持Sprint 目標,做廣泛的理解機器學習。”

Gavin 最後總結:”沒有扎實的需求或是痛苦的問題要解決,就不會有好的架構設計。所以至今要談聚焦不太現實,如佳麗所言,就繼續廣泛的了解吧。”

Molly 補充:"針對Pete的第3.點,資料集標注,我有認識對岸的人,就是做這一門生意的,明天我跟大家報告狀況。"

Moore:”那後天我要用 Tensorflow 來做MLP,讓大家與Mxnet比比看。”

備註:

專案緣起記錄在 【UP, Scrum 與 AI專案】


上一篇
實作多層感知機
下一篇
資料集標注生意難做?
系列文
深度學習所需入門知識--一位初學者的認知31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言