MXNET:監督學習

來源:互聯網
上載者:User

標籤:col   避免   演算法   puts   因此   fun   amp   引入   backward   

線性迴歸

給定一個資料點集合 X 和對應的目標值 y,線性模型的目標就是找到一條使用向量 w 和位移 b
描述的線,來儘可能地近似每個樣本X[i] 和 y[i]。

數學公式表示為\(\hat{y}=Xw+b\)

目標函數是最小化所有點的平方誤差 \(\sum_{i=1}^{n} (\hat{y_i}-y_i)^2\)

?個神經?絡就是?個由節點(神經元)和有向邊組成的集合。我們? 般把?些節點群組成層,每?層先從下??層的節點擷取輸?,然後輸出給上?的層使?。要計算? 個節點值,我們需要將輸?節點值做加權和(權數值即w),然後再加上?個啟用函數(activation function)。這裡的啟用函數是\(f(x)=x\)

建立資料集: \(y=2*x[0] - 3.4*x[1] + 4.2 +noise\)

# -*- coding: utf-8 -*-from mxnet import ndarray as ndfrom mxnet import autogradnum_inputs = 2num_examples = 1000true_w = [2, -3.4]true_b = 4.2X = nd.random_normal(shape=(num_examples, num_inputs))y = true_w[0] * X[:, 0] + true_w[1] * X[:, 1] + true_by += .01 * nd.random_normal(shape=y.shape)print 'dataset'import matplotlib.pyplot as pltplt.scatter(X[:, 1].asnumpy(),y.asnumpy())plt.show()

當我們開始訓練神經?絡的時候,我們需要不斷讀取資料區塊。這?我們定義?個函數它每次返回 batch_size 個隨機的樣本和對應的?標。

import randombatch_size = 10def data_iter():    # 產??個隨機索引    idx = list(range(num_examples))    random.shuffle(idx)    for i in range(0, num_examples, batch_size):        j = nd.array(idx[i:min(i+batch_size,num_examples)])        yield nd.take(X, j), nd.take(y, j)for data, label in data_iter():     print(data, label)

隨機初始化模型參數,之後訓練時我們需要對這些參數求導來更新它們的值,使損失盡量減小;因此我們需要建立它們的梯度。

w = nd.random_normal(shape=(num_inputs, 1))b = nd.zeros((1,))params = [w, b]for param in params:    param.attach_grad()

定義網路

def net(X):    return nd.dot(X, w) + b

定義損失函數

def square_loss(yhat, y):    # 注意這?我們把 y 變形成 yhat 的形狀來避免矩陣形狀的?動轉換    return (yhat - y.reshape(yhat.shape)) ** 2

定義最佳化方案,我們這?通過隨機梯度下降來求解。每?步,我們將模型參數沿著梯度的反?向走特定距離,這個距離?般叫學習率(learning rate)lr

def SGD(params, lr):    for param in params:        param[:] = param - lr * param.grad

現在我們可以開始訓練了。訓練通常需要迭代資料數次,在這?使? epochs表?迭代總次數; ?次迭代中,我們每次隨機讀取固定數個資料點,計算梯度並更新模型參數。

epochs = 5learning_rate = .001niter = 0moving_loss = 0smoothing_constant = .01# 訓練for e in range(epochs):    total_loss = 0    for data, label in data_iter():        with autograd.record():            output = net(data)            loss = square_loss(output, label)        loss.backward()        SGD(params, learning_rate)        total_loss += nd.sum(loss).asscalar()        # 記錄每讀取?個資料點後,損失的移動平均值的變化;        niter +=1        curr_loss = nd.mean(loss).asscalar()        moving_loss = (1 - smoothing_constant) * moving_loss + (smoothing_constant * curr_loss)        if (niter + 1) % 100 == 0:            print("Epoch %d, batch %d. Average loss: %f" % (                epochs, niter, moving_loss))print(params)# output[[ 1.99952257] [-3.39969802]]<NDArray 2x1 @cpu(0)>, [ 4.19949913]<NDArray 1 @cpu(0)>
線性迴歸-使用Gluon

這裡我們將使用MXNet提供的Gluon介面更方便地實現線性迴歸的訓練。

首先產生資料集

num_inputs = 2num_examples = 1000true_w = [2, -3.4]true_b = 4.2features = nd.random_normal(scale=1, shape=(num_examples, num_inputs))labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_blabels += nd.random_normal(scale=0.01, shape=labels.shape)

讀取資料,使用Gluon提供的data模組來讀取資料。在每一次迭代中,我們將隨機讀取包含10個資料樣本的小批量。

from mxnet.gluon import data as gdatabatch_size = 10dataset = gdata.ArrayDataset(features, labels)data_iter = gdata.DataLoader(dataset, batch_size, shuffle=True)

在前面我們需要定義模型參數,並使用它們一步步描述模型是怎樣計算的。當模型結構變得更複雜時,這些步驟將變得更加繁瑣。其實,Gluon提供了大量預定義的層,這使我們只需關注使用哪些層來構造模型。
首先,匯入nn模組。我們先定義一個模型變數net,它是一個Sequential執行個體。在Gluon中,Sequential執行個體可以看做是一個串聯各個層的容器。在構造模型時,我們在該容器中依次添加層。當給定輸入資料時,容器中的每一層將依次計算並將輸出作為下一層的輸入。
線性迴歸的輸出層又叫全串連層。在Gluon中,全串連層是一個Dense執行個體。我們定義該層輸出個數為1。

from mxnet.gluon import nnnet = nn.Sequential()net.add(nn.Dense(1))

值得一提的是,在Gluon中我們無需指定每一層輸入的形狀,例如線性迴歸的輸入個數。當模型看見資料時,例如後面執行net(X)時,模型將自動推斷出每一層的輸入個數。

初始化模型參數,從MXNet中匯入init模組,並通過init.Normal(sigma=0.01)指定權重參數每個元素將在初始化時隨機採樣於均值為0標準差為0.01的常態分佈。偏差參數全部元素初始化為零。

from mxnet import initnet.initialize(init.Normal(sigma=0.01))

定義損失函數,從gluon引入loss模組

from mxnet.gluon import loss as glossloss = gloss.L2Loss()

定義最佳化演算法,在匯入Gluon後,我們可以建立一個Trainer執行個體,並且將模型參數傳遞給它。

from mxnet.gluon import Trainertrainer = Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.03})

訓練模型,我們通過調用step函數來迭代模型參數。由於變數l是batch_size維的NDArray,執行l.backward()等價於l.sum().backward()。按照小批量隨機梯度下降的定義,我們在step函數中提供batch_size,以確保小批量隨機梯度是該批量中每個樣本梯度的平均。

num_epochs = 3for epoch in range(1, num_epochs + 1):    for X, y in data_iter:        with autograd.record():            l = loss(net(X), y)        l.backward()        trainer.step(batch_size)    print("epoch %d, loss: %f"          % (epoch, loss(net(features), labels).asnumpy().mean()))dense = net[0]print true_w, dense.weight.data()print true_b, dense.bias.data()

可以從net獲得需要的層,並訪問其權重和位移。學到的和真實的參數很接近。

MXNET:監督學習

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.