一.項(xiàng)目背景
本項(xiàng)目在之前項(xiàng)目分類模型基礎(chǔ)上神經(jīng)網(wǎng)絡(luò)應(yīng)用(一)進(jìn)一步拓展神經(jīng)網(wǎng)絡(luò)應(yīng)用,相比之前本項(xiàng)目增加了新的知識(shí)點(diǎn),比如正則化,softmax函數(shù)和交叉熵?fù)p失函數(shù)等。
二.前期準(zhǔn)備
1.正則化
1)解釋:在機(jī)器學(xué)習(xí)中為了防止模型過(guò)擬合(簡(jiǎn)單說(shuō)就是在訓(xùn)練集上樣本表現(xiàn)的
很好,在測(cè)試集上表現(xiàn)的很差),經(jīng)常需要進(jìn)行正則化,所謂正則化簡(jiǎn)單來(lái)說(shuō)就是讓模
型系數(shù)變得相對(duì)小一點(diǎn),防止數(shù)據(jù)稍微變化引起模型圖形曲線較大波動(dòng),總之一句話,
讓模型曲線表現(xiàn)更加平穩(wěn)。
2)分類:正則化總體分類為L(zhǎng)1正則化和L2正則化。兩者區(qū)別在于范數(shù)級(jí)別不同,
L2正則化是||w||2,L1正則化是||w||1范數(shù),并且L2正則傾向于系數(shù)W盡量均衡(非
零分量個(gè)數(shù)盡量多),L1正則化使W分類盡量稀疏(非零分量個(gè)數(shù)盡量少),我們以線
性回歸為例,簡(jiǎn)單說(shuō)明一下。
【注】正則項(xiàng)不包括截距項(xiàng)。
2.Softmax函數(shù)
1)Softmax經(jīng)常被應(yīng)用在多分類任務(wù)的神經(jīng)網(wǎng)絡(luò)中的輸出層,簡(jiǎn)單理解可以認(rèn)為
Softmax輸出的是幾個(gè)類別選擇的概率。比如我有一個(gè)二分類任務(wù),Softmax函數(shù)可以
根據(jù)它們相對(duì)的大小,輸出二個(gè)類別選取的概率,并且概率和為1。表達(dá)式如下,Si代
表的是第i個(gè)神經(jīng)元的輸出。
softmax函數(shù)
3.交叉熵?fù)p失函數(shù)
在神經(jīng)網(wǎng)絡(luò)反向傳播中需要損失函數(shù),損失函數(shù)其實(shí)表示的是真實(shí)值與網(wǎng)絡(luò)的估計(jì)
值的誤差,有了這個(gè)誤差我們才能知道怎樣去修改網(wǎng)絡(luò)中的權(quán)重。損失函數(shù)可以有很多
形式,這里用的是交叉熵函數(shù),主要是由于這個(gè)求導(dǎo)結(jié)果比較簡(jiǎn)單,易于計(jì)算,并且交
叉熵解決某些損失函數(shù)學(xué)習(xí)緩慢的問(wèn)題,函數(shù)表達(dá)式如下
它的導(dǎo)數(shù)推到過(guò)程我們就不再說(shuō)明,網(wǎng)上有很多資料大家可以參考,針對(duì)本項(xiàng)目分類
模型,我們最終結(jié)果為如下,也就是我們的預(yù)測(cè)概率值減去目標(biāo)值。
三.實(shí)現(xiàn)過(guò)程
1.生成數(shù)據(jù)
#生成數(shù)據(jù)
def generate_data():
#設(shè)定種子數(shù),保定生成數(shù)據(jù)相同
np.random.seed(0)
#生成數(shù)據(jù)集和標(biāo)簽,noise表示產(chǎn)生噪音
X, y = datasets.make_moons(200, noise=0.20)
#返回?cái)?shù)據(jù)集
return X, y
2.構(gòu)建模型
#計(jì)算損失函數(shù)
def calculate_loss(model, X, y):
#訓(xùn)練樣本個(gè)數(shù)
num_examples = len(X) # training set size
#加載模型參數(shù)
W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
#前向傳播
z1 = X.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
exp_scores = np.exp(z2)
#softmax函數(shù)歸一化
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
#定義交叉熵?fù)p失函數(shù)
corect_logprobs = -np.log(probs[range(num_examples), y])
#計(jì)算總的損失函數(shù)
data_loss = np.sum(corect_logprobs)
#L2正則化,防止過(guò)擬合
data_loss += Config.reg_lambda / 2 * (np.sum(np.square(W1)) + np.sum(np.square(W2)))
#除以樣本總數(shù)
return 1. / num_examples * data_loss
#構(gòu)建模型
def build_model(X, y, nn_hdim, num_passes=20000, print_loss=False):
#樣本個(gè)數(shù)
num_examples = len(X)
#記錄隨機(jī)中子數(shù)
np.random.seed(0)
#初始化神經(jīng)網(wǎng)絡(luò)參數(shù)
W1 = np.random.randn(Config.nn_input_dim, nn_hdim) / np.sqrt(Config.nn_input_dim)
b1 = np.zeros((1, nn_hdim))
W2 = np.random.randn(nn_hdim, Config.nn_output_dim) / np.sqrt(nn_hdim)
b2 = np.zeros((1, Config.nn_output_dim))
#存儲(chǔ)模型參數(shù)
model = {}
#遍歷每一輪
for i in range(0, num_passes):
#前向傳播
z1 = X.dot(W1) + b1
#函數(shù)表達(dá)式(e(z)-e(-z))/(e(z)+e(-z))
#隱藏層輸出
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
#輸出層輸出
exp_scores = np.exp(z2)
#計(jì)算概率
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
#反向傳播
delta3 = probs
#計(jì)算損失函數(shù)導(dǎo)數(shù)
delta3[range(num_examples), y] -= 1
#計(jì)算w2梯度
dW2 = (a1.T).dot(delta3)
#計(jì)算b2梯度
db2 = np.sum(delta3, axis=0, keepdims=True)
#計(jì)算輸入層到隱藏層總誤差
delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
#計(jì)算w1梯度
dW1 = np.dot(X.T, delta2)
#計(jì)算b1梯度
db1 = np.sum(delta2, axis=0)
#正則化系數(shù)w(只對(duì)w進(jìn)行正則化,b不改變)
dW2 += Config.reg_lambda * W2
dW1 += Config.reg_lambda * W1
#更新參數(shù)
W1 += -Config.epsilon * dW1
b1 += -Config.epsilon * db1
W2 += -Config.epsilon * dW2
b2 += -Config.epsilon * db2
#存儲(chǔ)模型參數(shù)
model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
#輸出損失函數(shù)
if print_loss and i % 1000 == 0:
print("Loss after iteration %i: %f" % (i, calculate_loss(model, X, y)))
#返回模型參數(shù)
return model
3.預(yù)測(cè)樣本
#預(yù)測(cè)樣本
def predict(model, x):
#加載模型參數(shù)
W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
#前向傳播
z1 = x.dot(W1) + b1
a1 = np.tanh(z1)
z2 = a1.dot(W2) + b2
#計(jì)算總體輸出
exp_scores = np.exp(z2)
#softmax函數(shù)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
#返回預(yù)測(cè)概率最大值對(duì)應(yīng)標(biāo)簽
return np.argmax(probs, axis=1)
4.繪制圖形可視化
#繪制邊界線
def plot_decision_boundary(pred_func, X, y):
#分別設(shè)置間隔
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
#步長(zhǎng)
h = 0.01
#生成網(wǎng)格數(shù)據(jù)
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
#預(yù)測(cè)整個(gè)網(wǎng)格z值
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
#繪制分割線
plt.contourf(xx,
yy,
Z,
cmap=plt.cm.Spectral)
#繪制散點(diǎn)圖
plt.scatter(X[:, 0],
X[:, 1],
c=y,
cmap=plt.cm.Spectral)
#顯示圖形
plt.show()
#可視化函數(shù)
def visualize(X, y, model):
#繪制圖形
plot_decision_boundary(lambda x:predict(model,x), X, y)
#設(shè)置標(biāo)題
plt.title("Neural Network")
#主函數(shù)
def main():
#生成數(shù)據(jù)
X, y = generate_data()
#構(gòu)建模型
model = build_model(X, y, 3, print_loss=True)
#可視化
visualize(X, y, model)
#預(yù)測(cè)準(zhǔn)確樣本數(shù)
accuracy=0
#設(shè)定種子數(shù),保定生成數(shù)據(jù)相同
np.random.seed(1)
#生成數(shù)據(jù)集和標(biāo)簽,noise表示產(chǎn)生噪音
X_test, y = datasets.make_moons(200, noise=0.20)
#驗(yàn)證測(cè)試集
for i in range(len(X_test)):
#預(yù)測(cè)測(cè)試集
if y[i]==predict(model,X_test[i]):
#預(yù)測(cè)準(zhǔn)確數(shù)目
accuracy+=1
#輸出準(zhǔn)確率
print("Accuracy:",float(accuracy)/len(X_test))
結(jié)論:準(zhǔn)確率為96%(這里測(cè)試集數(shù)據(jù)我們添加了噪音),如果在產(chǎn)生測(cè)試集數(shù)據(jù)時(shí)取掉
noise參數(shù)(也就是說(shuō)取掉噪音數(shù)據(jù)),準(zhǔn)確率會(huì)更高。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4771瀏覽量
100715 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62573 -
Softmax
+關(guān)注
關(guān)注
0文章
9瀏覽量
2506
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論