我們構造乙個簡單的人工訓練資料集,它可以使我們能夠直觀比較學到的引數和真實的模型引數的區別。設訓練資料集樣本數為 1000,輸入個數(特徵數)為 2。給定隨機生成的批量樣本特徵 x∈ℝ1000×2x∈r1000×2,我們使用線性回歸模型真實權重 w=[2,−3.4]⊤w=[2,−3.4]⊤ 和偏差 b=4.2b=4.2,以及乙個隨機噪音項 ϵϵ 來生成標籤
y=xw+b+ϵ,y=xw+b+ϵ,
其中噪音項 ϵϵ 服從均值為 0 和標準差為 0.01 的正態分佈。下面,讓我們生成資料集。
定義模型:
構造乙個資料迭代器-》定義網路模型、定義損失函式、定義優化模型-》訓練模型
在訓練中,我們將多次迭代模型引數。在每次迭代中,我們根據當前讀取的小批量資料樣本(特徵x
和標籤y
),通過呼叫反向函式backward
計算小批量隨機梯度,並呼叫優化演算法sgd
迭代模型引數。由於我們之前設批量大小batch_size
為 10,每個小批量的損失l
的形狀為(10,1)。由於變數l
並不是乙個標量,執行l.backward()
將對l
中元素求和得到新的變數,再求該變數有關模型引數的梯度。
在乙個迭代週期(epoch)中,我們將完整遍歷一遍data_iter
函式,並對訓練資料集中所有樣本都使用一次(假設樣本數能夠被批量大小整除)。這裡的迭代週期個數num_epochs
和學習率lr
都是超引數,分別設 3 和 0.03。在實踐中,大多超引數都需要通過反覆試錯來不斷調節。當迭代週期數設的越大時,雖然模型可能更有效,但是訓練時間可能過長。
%matplotlib inline
from ipython import display
from matplotlib import pyplot as plt
from mxnet import autograd,nd
import random
num_inputs=2#兩個特徵
num_examples=1000
true_w=[2,-3.4]
true_b=4.2
#y[i]=2*x[i][0]-3.4*x[i][1]+4.2+nose
features=nd.random.normal(scale=1,shape=(num_examples,num_inputs))
labels=true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b
labels += nd.random.normal(scale=0.01, shape=labels.shape)#生成方差為0.1的雜訊並且加上y才是最終的y
#x是每一行是乙個長度為 2 的向量,而y的每一行是乙個長度為 1 的向量(標量)
#用於顯示圖,
# 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()
# plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(), 1);
#mxnet的資料格式為ndarray,當需要讀取可**的資料,就要呼叫:.asnumpy()
# 在訓練模型的時候,我們需要遍歷資料集並不斷讀取小批量資料樣本。
# 這裡我們定義乙個函式:它每次返回batch_size(批量大小)個隨機樣本的特徵和標籤
#通過python和yield來構造乙個迭代器
def data_iter(batch_size,features,labels):
batch_size=10
num_examples=len(features)
#產生乙個隨機索引
idx=list(range(num_examples))
random.shuffle(idx)#打亂順序
for i in range(0,num_examples):
j=nd.array(idx[i:min(i+batch_size,num_examples)])
yield features.take(j),labels.take(j) #在numpy中take函式根據索引返回對應的元素
#yield就是 return 返回乙個值,並且記住這個返回的位置,下次迭代就從這個位置後開始
#初始化模型引數
#我們將權重初始化成均值為 0 標準差為 0.01 的正態隨機數,偏差則初始化成 0。
w = nd.random.normal(scale=0.01, shape=(num_inputs, 1))
b = nd.zeros(shape=(1,))
#我們需要對這些引數求梯度來迭代引數的值,因此我們需要建立它們的梯度。
w.attach_grad()
b.attach_grad()
#定義模型def
def linreg(x,w,b):
return nd.dot(x,w)+b
#定義損失函式
def squared_loss(y_hat, y):
return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
#定義優化演算法¶
#以下的sgd函式實現了上一節中介紹的小批量隨機梯度下降演算法。它通過不斷迭代模型引數來優化損失函式。
#這裡自動求梯度模組計算得來的梯度是乙個批量樣本的梯度和。我們將它除以批量大小來得到平均值。
def sgd(params, lr, batch_size):
for param in params:
param[:] = param - lr * param.grad / batch_size
#訓練模型
# 在訓練中,我們將多次迭代模型引數。在每次迭代中,我們根據當前讀取的小批量資料樣本(特徵x和標籤y),
# 通過呼叫反向函式backward計算小批量隨機梯度,並呼叫優化演算法sgd迭代模型引數。
# 由於我們之前設批量大小batch_size為 10,每個小批量的損失l的形狀為(10,1)。
# 由於變數l並不是乙個標量,執行l.backward()將對l中元素求和得到新的變數,再求該變數有關模型引數的梯度。
# 在乙個迭代週期(epoch)中,我們將完整遍歷一遍data_iter函式,並對訓練資料集中所有樣本都使用一次(假設樣本數能夠被批量大小整除)。
# 這裡的迭代週期個數num_epochs和學習率lr都是超引數,分別設 3 和 0.03。
# 在實踐中,大多超引數都需要通過反覆試錯來不斷調節。當迭代週期數設的越大時,雖然模型可能更有效,但是訓練時間可能過長。
lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss
batch_size=10
for epoch in range(num_epochs): # 訓練模型一共需要 num_epochs 個迭代週期。
# 在乙個迭代週期中,使用訓練資料集中所有樣本一次(假設樣本數能夠被批量大小整除)。
# x 和 y 分別是小批量樣本的特徵和標籤。
for x, y in data_iter(batch_size, features, labels):
with autograd.record():
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()))
神經網路的基本步驟: 深度學習 動手學深度學習筆記 12
g是乙個生成的網路,它接收乙個隨機的雜訊z,通過這個雜訊生成,記做g z d是乙個判別網路,判別一張是不是 真實的 它的輸入引數是x,x代表一張,輸出d x 代表x為真實的概率,如果為1,就代表100 是真實的,而輸出為0,就代表不可能是真實的。在訓練過程中,生成網路g的目標就是盡量生成真實的去欺騙...
《動手學深度學習》 深度學習基礎複習
交叉熵只關心對正確類別的 概率,因為只要其值足夠大,就可以確保分類結果正確,而平方損失則過於嚴格,例如y i 1 y i 2 0比y i 1 0,y i 2 0.4的損失要小很多,雖然兩者都有同樣正確的分類 結果。正則化通過為模型損失函式新增懲罰項使學出的模型引數值較小,是應對過擬合的常用手段。權重...
動手學深度學習之深度學習基礎
資料集的形式主要有三種 訓練集測試集 測試資料集不可以用來調參 驗證集 k折交叉驗證 把原始資料分成k組,每次訓練時,使用k 1個子資料集訓練,使用乙個作為驗證,最後通過k次求取訓練誤差和驗證誤差的平均。過擬合 overfitting 模型的訓練誤差遠小於它在測試資料集上的誤差 欠擬合 underf...