<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 3.6 softmax回歸的從零開始實現 這一節我們來動手實現softmax回歸。首先導入本節實現所需的包或模塊。 ``` python import torch import torchvision import numpy as np import sys sys.path.append("..") # 為了導入上層目錄的d2lzh_pytorch import d2lzh_pytorch as d2l ``` ## 3.6.1 獲取和讀取數據 我們將使用Fashion-MNIST數據集,并設置批量大小為256。 ``` python batch_size = 256 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) ``` ## 3.6.2 初始化模型參數 跟線性回歸中的例子一樣,我們將使用向量表示每個樣本。已知每個樣本輸入是高和寬均為28像素的圖像。模型的輸入向量的長度是 `$ 28 \times 28 = 784 $`:該向量的每個元素對應圖像中每個像素。由于圖像有10個類別,單層神經網絡輸出層的輸出個數為10,因此softmax回歸的權重和偏差參數分別為`$ 784 \times 10 $`和`$ 1 \times 10 $`的矩陣。 ``` python num_inputs = 784 num_outputs = 10 W = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtype=torch.float) b = torch.zeros(num_outputs, dtype=torch.float) ``` 同之前一樣,我們需要模型參數梯度。 ``` python W.requires_grad_(requires_grad=True) b.requires_grad_(requires_grad=True) ``` ## 3.6.3 實現softmax運算 在介紹如何定義softmax回歸之前,我們先描述一下對如何對多維`Tensor`按維度操作。在下面的例子中,給定一個`Tensor`矩陣`X`。我們可以只對其中同一列(`dim=0`)或同一行(`dim=1`)的元素求和,并在結果中保留行和列這兩個維度(`keepdim=True`)。 ``` python X = torch.tensor([[1, 2, 3], [4, 5, 6]]) print(X.sum(dim=0, keepdim=True)) print(X.sum(dim=1, keepdim=True)) ``` 輸出: ``` tensor([[5, 7, 9]]) tensor([[ 6], [15]]) ``` 下面我們就可以定義前面小節里介紹的softmax運算了。在下面的函數中,矩陣`X`的行數是樣本數,列數是輸出個數。為了表達樣本預測各個輸出的概率,softmax運算會先通過`exp`函數對每個元素做指數運算,再對`exp`矩陣同行元素求和,最后令矩陣每行各元素與該行元素之和相除。這樣一來,最終得到的矩陣每行元素和為1且非負。因此,該矩陣每行都是合法的概率分布。softmax運算的輸出矩陣中的任意一行元素代表了一個樣本在各個輸出類別上的預測概率。 ``` python def softmax(X): X_exp = X.exp() partition = X_exp.sum(dim=1, keepdim=True) return X_exp / partition # 這里應用了廣播機制 ``` 可以看到,對于隨機輸入,我們將每個元素變成了非負數,且每一行和為1。 ``` python X = torch.rand((2, 5)) X_prob = softmax(X) print(X_prob, X_prob.sum(dim=1)) ``` 輸出: ``` tensor([[0.2206, 0.1520, 0.1446, 0.2690, 0.2138], [0.1540, 0.2290, 0.1387, 0.2019, 0.2765]]) tensor([1., 1.]) ``` ## 3.6.4 定義模型 有了softmax運算,我們可以定義上節描述的softmax回歸模型了。這里通過`view`函數將每張原始圖像改成長度為`num_inputs`的向量。 ``` python def net(X): return softmax(torch.mm(X.view((-1, num_inputs)), W) + b) ``` ## 3.6.5 定義損失函數 上一節中,我們介紹了softmax回歸使用的交叉熵損失函數。為了得到標簽的預測概率,我們可以使用`gather`函數。在下面的例子中,變量`y_hat`是2個樣本在3個類別的預測概率,變量`y`是這2個樣本的標簽類別。通過使用`gather`函數,我們得到了2個樣本的標簽的預測概率。與3.4節(softmax回歸)數學表述中標簽類別離散值從1開始逐一遞增不同,在代碼中,標簽類別的離散值是從0開始逐一遞增的。 ``` python y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]]) y = torch.LongTensor([0, 2]) y_hat.gather(1, y.view(-1, 1)) ``` 輸出: ``` tensor([[0.1000], [0.5000]]) ``` 下面實現了3.4節(softmax回歸)中介紹的交叉熵損失函數。 ``` python def cross_entropy(y_hat, y): return - torch.log(y_hat.gather(1, y.view(-1, 1))) ``` ## 3.6.6 計算分類準確率 給定一個類別的預測概率分布`y_hat`,我們把預測概率最大的類別作為輸出類別。如果它與真實類別`y`一致,說明這次預測是正確的。分類準確率即正確預測數量與總預測數量之比。 為了演示準確率的計算,下面定義準確率`accuracy`函數。其中`y_hat.argmax(dim=1)`返回矩陣`y_hat`每行中最大元素的索引,且返回結果與變量`y`形狀相同。相等條件判斷式`(y_hat.argmax(dim=1) == y)`是一個類型為`ByteTensor`的`Tensor`,我們用`float()`將其轉換為值為0(相等為假)或1(相等為真)的浮點型`Tensor`。 ``` python def accuracy(y_hat, y): return (y_hat.argmax(dim=1) == y).float().mean().item() ``` 讓我們繼續使用在演示`gather`函數時定義的變量`y_hat`和`y`,并將它們分別作為預測概率分布和標簽。可以看到,第一個樣本預測類別為2(該行最大元素0.6在本行的索引為2),與真實標簽0不一致;第二個樣本預測類別為2(該行最大元素0.5在本行的索引為2),與真實標簽2一致。因此,這兩個樣本上的分類準確率為0.5。 ``` python print(accuracy(y_hat, y)) ``` 輸出: ``` 0.5 ``` 類似地,我們可以評價模型`net`在數據集`data_iter`上的準確率。 ``` python # 本函數已保存在d2lzh_pytorch包中方便以后使用。該函數將被逐步改進:它的完整實現將在“圖像增廣”一節中描述 def evaluate_accuracy(data_iter, net): acc_sum, n = 0.0, 0 for X, y in data_iter: acc_sum += (net(X).argmax(dim=1) == y).float().sum().item() n += y.shape[0] return acc_sum / n ``` 因為我們隨機初始化了模型`net`,所以這個隨機模型的準確率應該接近于類別個數10的倒數即0.1。 ``` python print(evaluate_accuracy(test_iter, net)) ``` 輸出: ``` 0.0681 ``` ## 3.6.7 訓練模型 訓練softmax回歸的實現跟[“線性回歸的從零開始實現”](linear-regression-scratch.md)一節介紹的線性回歸中的實現非常相似。我們同樣使用小批量隨機梯度下降來優化模型的損失函數。在訓練模型時,迭代周期數`num_epochs`和學習率`lr`都是可以調的超參數。改變它們的值可能會得到分類更準確的模型。 ``` python num_epochs, lr = 5, 0.1 # 本函數已保存在d2lzh包中方便以后使用 def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, optimizer=None): for epoch in range(num_epochs): train_l_sum, train_acc_sum, n = 0.0, 0.0, 0 for X, y in train_iter: y_hat = net(X) l = loss(y_hat, y).sum() # 梯度清零 if optimizer is not None: optimizer.zero_grad() elif params is not None and params[0].grad is not None: for param in params: param.grad.data.zero_() l.backward() if optimizer is None: d2l.sgd(params, lr, batch_size) else: optimizer.step() # “softmax回歸的簡潔實現”一節將用到 train_l_sum += l.item() train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item() n += y.shape[0] test_acc = evaluate_accuracy(test_iter, net) print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc)) train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr) ``` 輸出: ``` epoch 1, loss 0.7878, train acc 0.749, test acc 0.794 epoch 2, loss 0.5702, train acc 0.814, test acc 0.813 epoch 3, loss 0.5252, train acc 0.827, test acc 0.819 epoch 4, loss 0.5010, train acc 0.833, test acc 0.824 epoch 5, loss 0.4858, train acc 0.836, test acc 0.815 ``` ## 3.6.8 預測 訓練完成后,現在就可以演示如何對圖像進行分類了。給定一系列圖像(第三行圖像輸出),我們比較一下它們的真實標簽(第一行文本輸出)和模型預測結果(第二行文本輸出)。 ``` python X, y = iter(test_iter).next() true_labels = d2l.get_fashion_mnist_labels(y.numpy()) pred_labels = d2l.get_fashion_mnist_labels(net(X).argmax(dim=1).numpy()) titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)] d2l.show_fashion_mnist(X[0:9], titles[0:9]) ``` ![](https://img.kancloud.cn/d2/95/d295111c6eab16e5c075241bab6e2038_1820x268.png) ## 小結 * 可以使用softmax回歸做多類別分類。與訓練線性回歸相比,你會發現訓練softmax回歸的步驟和它非常相似:獲取并讀取數據、定義模型和損失函數并使用優化算法訓練模型。事實上,絕大多數深度學習模型的訓練都有著類似的步驟。 ----------- > 注:本節除了代碼之外與原書基本相同,[原書傳送門](https://zh.d2l.ai/chapter_deep-learning-basics/softmax-regression-scratch.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看