深度學習第二課 Softmax迴歸

與第一課線性迴歸(linear regression)不同,softmax迴歸針對的是多分類的情況,即labels不再僅有0,1兩個分類。

softmax通過指數運算將最後的分類轉爲0~1間的概率,在終於類別概率中,數值大的爲預測概率。

與線性迴歸損失不同,softmax函數計算損失採用的是交叉熵損失(Cross Entropy),原理和公式推導可參考:https://zhuanlan.zhihu.com/p/27223959

softmax函數簡單實現代碼如下:

from mxnet import autograd,nd
import gluonbook as gb
%matplotlib inline 
import time
import matplotlib.pyplot as plt
import sys

#讀取數據
batch_size = 256
train_iter,test_iter = gb.load_data_fashion_mnist(batch_size)

#參數初始化
num_inputs = 784
num_outputs = 10

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

w.attach_grad()
b.attach_grad()

#正向傳播,實現softmax運算
def softmax(x):
    return nd.exp(x) / nd.exp(x).sum(axis = 1,keepdims = True)

def net(x):
    return softmax(nd.dot(x.reshape((-1,num_inputs)),w) + b)    #對求得的yhat執行softmax運算

def cross_entropy(y_hat,y):               #定義交叉損失熵函數
    return -nd.pick(y_hat,y).log()
def accuracy(yhat,y):
    return (yhat.argmax(axis = 1) == y.astype('float32')).mean().asscalar()   #提取yhat中每行概率最大的類別和真實值y的類別比較後的概率
def evaluate_accuracy(data_iter,net):
    acc = 0
    for X,y in data_iter:
        acc+= accuracy(net(X),y)
        return acc/len(data_iter)
        
num_epochs,lr = 5,0.1
#訓練模型
def train_ch3(net,train_iter,test_iter,loss,num_epochs,batch_size,params = None,lr = None,trainer = None):
    for epoch in range(num_epochs):
        train_l_sum = 0     #定義訓練損失總和
        train_acc_sum = 0   #定義訓練精度總和
        for X ,y in train_iter:
            with autograd.record():
                y_hat = net(X)
                l = loss(y_hat,y)
            l.backward()
            if trainer is None:
                gb.sgd(params,lr,batch_size)
            else:
                trainer.step(batch_size)
            train_l_sum += l.mean().asscalar()
            train_acc_sum += accuracy(y_hat,y)
        test_acc = evaluate_accuracy(test_iter,net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / len(train_iter),
                 train_acc_sum / len(train_iter), test_acc))
train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs,
          batch_size, [w, b], lr)
        

 

簡單小計:

1)keepdims = True:

2)nd.pick():

3) (yhat.argmax(axis = 1) == y.astype('float32')).mean().asscalar():

取yhat中每行概率最大的類別和真實值y的類別比較後的概率(比較後得到的矩陣裏面只有0和1兩類),.mean()相當於求取了和真實值比較多概率。

eg:

Softmax()的Gluon實現:

%matplotlib inline
import gluonbook as gb
from mxnet import gluon, init
from mxnet.gluon import loss as gloss, nn

#讀取數據
batch_size = 256
train_iter, test_iter = gb.load_data_fashion_mnist(batch_size)

#初始化模型
net = nn.Sequential()
net.add(nn.Dense(10))    #定義輸出層目標爲10
net.initialize(init.Normal(sigma=0.01))

#定義Softmax函數和損失
loss = gloss.SoftmaxCrossEntropyLoss()
#定義優化算法
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1})
#訓練模型
num_epochs = 5
gb.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None,
             None, trainer)

小計:

1)nn模塊:

“nn”是 neural networks(神經網絡)的縮寫。顧名思義,該模塊定義了大量神經網絡的層。我們先定義一個模型變量net,它是一個 Sequential 實例。在 Gluon 中,Sequential 實例可以看作是一個串聯各個層的容器。在構造模型時,我們在該容器中依次添加層。當給定輸入數據時,容器中的每一層將依次計算並將輸出作爲下一層的輸入。

作爲一個單層神經網絡,線性迴歸輸出層中的神經元和輸入層中各個輸入完全連接。因此,線性迴歸的輸出層又叫全連接層。在 Gluon 中,全連接層是一個Dense實例。net.add(nn.Dense(10)),表明輸出層個數是10。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章