利用神經網路來實現線性回歸

2021-10-07 14:16:40 字數 3623 閱讀 9728

先導入包

%matplotlib inline

from ipython import display

from matplotlib import pyplot as plt

from mxnet import autograd, nd

import random

features為隨機生成服從(0,1)正態分佈的資料2000個,形狀為1000*2,labels就是目標變數,這裡已經設定好權重w1,w2分別為2,-3.4,還有b為4.2,最後一行是給目標變數加上雜訊,這樣跟真實資料更為接近。

num_inputs = 2

num_examples = 1000

true_w = [2, -3.4]

true_b = 4.2

features = nd.random.normal(scale=1, shape=(num_examples, num_inputs)) #1000*2

labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b #1000*1

labels += nd.random.normal(scale=0.01, shape=labels.shape) #加上雜訊

def use_svg_display():    # 用向量圖顯示  特點 放大後影象不會失真

display.set_matplotlib_formats('svg')

def set_figsize(figsize=(3.5, 2.5)):

use_svg_display()

# 設定圖的尺寸

plt.rcparams['figure.figsize'] = figsize

set_figsize(figsize=(5,5))

plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(),10); # 加分號只顯示圖

plt.scatter(features[:, 0].asnumpy(), labels.asnumpy(),10);

畫了個圖,看看x1和x2與labels的關係:

可以看到x1與labels大體成正相關,x2與labels大體成負相關

# 該函式作用是從樣本中隨機提取大小為batch_size的資料

def data_iter(batch_size, features, labels):

num_examples = len(features)

indices = list(range(num_examples))

random.shuffle(indices) # 樣本的讀取順序是隨機的 indices列表隨機排列

for i in range(0, num_examples, batch_size):

j = nd.array(indices[i: min(i + batch_size, num_examples)])

yield features.take(j), labels.take(j) # take函式根據索引返回對應元素 最後結果為生成器

接著設定函式data_iter為後面小批量隨機梯度下降演算法做準備,該函式的作用是從features樣本中隨機提取若干個資料,例如batch_size 為10時,隨機的將這1000條資料(每條資料有兩個值)分成100份,生成乙個生成器,生成器可以當成列表,能用for迴圈依次提取。

正式開始:

w = nd.random.normal(scale=0.01, shape=(num_inputs, 1))

b = nd.zeros(shape=(1,))

w.attach_grad()#申請相應記憶體來存x的導數。

b.attach_grad()

def linreg(x, w, b): # 本函式已儲存在d2lzh包中方便以後使用

return nd.dot(x, w) + b

def squared_loss(y_hat, y): # 本函式已儲存在d2lzh包中方便以後使用

return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

def sgd(params, lr, batch_size): # 本函式已儲存在d2lzh包中方便以後使用

for param in params:

param[:] = param - lr * param.grad / batch_size

根據(0,0.01)正態分佈隨機生成w,b直接設定為0,attach_grad申請記憶體,linreg函式根據w,b,x的值來計算估計的y,squared_loss函式計算**y值與真實y值的差的平方除以2,sgd函式對w1,w2,b值進行更新,注意sgd函式這裡的for迴圈,裡面更新params引數的方式,其中param的位址是和params一樣的,所以改變param裡面的值的同時params的值也會發生改變,並且直接在param上進行修改,不會新開闢記憶體,是目前最優的方式。

lr = 0.03

num_epochs = 3

net = linreg

loss = squared_loss

for epoch in range(num_epochs): # 訓練模型一共需要num_epochs個迭代週期

# 在每乙個迭代週期中,會使用訓練資料集中所有樣本一次(假設樣本數能夠被批量大小整除)。x

# 和y分別是小批量樣本的特徵和標籤

for x, y in data_iter(batch_size, features, labels):

with autograd.record(): #記錄方便後面backward

l = loss(net(x, w, b), y) # l是有關小批量x和y的損失

l.backward() # 小批量的損失對模型引數求梯度

sgd([w, b], lr, batch_size) # 使用小批量隨機梯度下降迭代模型引數

train_l = loss(net(features, w, b), labels)

print('epoch %d, loss %f' % (epoch + 1, train_l.mean().asnumpy()))

這裡設定學習速度為0.03,迭代次數為3,注意這裡l.backward後,就可以用w.grad和b.grad 的方式得出l分別對w,b求導後所得值,然後根據這些值,用sgd函式進一步進行計算就可以得到更新後的w,b值,for迴圈data_iter得到的生成器,就是隨機小批量的優化演算法,大大提公升了演算法的速度

print(true_w, w)

print(true_b, b)

結果:[2, -3.4]

[[ 1.9999498]

[-3.3991547]]

4.2

[4.1989775]

1 2神經網路實現線性回歸

w tf.variable tf.random uniform 1 1.0,1.0 name w 隨機初始化權重引數 1到1之間 b tf.variable tf.zeros 1 name b 以0為初始化,1 表示維度 y w x data b 目標函式 loss tf.reduce mean t...

神經網路多元線性回歸

jupyter notebook import pandas as pd import numpy as np import tensorflow as tf import matplotlib.pyplot as plt matplotlib inline 資料 讀取資料 data pd.read...

神經網路實現非線性回歸

import tensorflow as tf import numpy as np import matplotlib.pyplot as plt 使用numpy生成200個隨機點 x data np.linspace 0.5,0.5,200 np.newaxis noise np.random....