Softmax 回歸 + 損失函數 + 圖片分類數據集

Softmax 回歸

在這里插入圖片描述
softmax 回歸是機器學習另外一個非常經典且重要的模型,是一個分類問題。

下面先解釋一下分類和回歸的區別:
在這里插入圖片描述
在這里插入圖片描述
簡單來說,分類問題從回歸的單輸出變成了多輸出,輸出的個數等于類別的個數。
在這里插入圖片描述
實際上,對于分類來說,我們不關心它們之間實際的值,我們關心的是:模型是否對正確類別的置信度特別的大
在這里插入圖片描述
雖然上述沒有要求 O i O_i Oi? 是一個什么樣的值,但是如果我們將值放在合適的區間,也會讓后續的處理變得更加的簡單,比如下面我們希望模型的輸出是一個概率:在這里插入圖片描述
在這里插入圖片描述
上述要是你使用了 o n e ? h o t one-hot one?hot 編碼的話,只有當 i = y i=y i=y時, y i = 1 y_i = 1 yi?=1,否則就是0。
在這里插入圖片描述

損失函數

損失函數是用來衡量預測值與真實值之間的區別,是機器學習里面一個非常重要的概念。
在這里插入圖片描述

1. L2 Loss(均方損失)

在這里插入圖片描述
藍色的線表示 y = 0 y=0 y=0 時變換我的 預測值 y ′ y' y 所生成的函數,可以看出來是一個二次函數。綠色是一個似然函數,似然函數取得最大值表明取該參數模型最合理。橙色的表示的是損失函數的梯度,由于是一次函數,穿過原點。

由上述可以發現,當預測值與真實值距離比較遠的時候,梯度比較的大,則對參數的更新是比較的多的,當越靠近原點的時候,梯度的絕對值就會越小,對參數的更新就會越來越小。但這可能并不是一件好事,因為在離原點越遠的地方,我可能并不希望需要那么大的梯度來更新我的參數。因此也可以考慮下面的 L1 Loss

L1 Loss

在這里插入圖片描述
當然也是可以提出新的損失函數來結合上述兩種損失函數的好處。
在這里插入圖片描述
在這里插入圖片描述
上述損失函數定義的好處就是:當預測值與真實值差別比較大的時候,我可以以均勻的力度
往回拉。當兩者越來越接近時,我可以使得拉的力度越來越小,從而不會出現數值上的問題。

圖片分類數據集

下面使用 Fashion-MNIST 數據集,展示對數據集的一般操作:

首先導入所需的庫:

%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2ld2l.use_svg_display() 
# 使用svg來顯示圖片

接著我們可以通過框架中的內置函數將Fashion-MNIST數據集下載并讀取到內存中

# 通過ToTensor實例將圖像數據從PIL類型變換成32位浮點數格式,
# 并除以255使得所有像素的數值均在0~1之間
trans = transforms.ToTensor() # 預處理,將圖片轉換成tensor
mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)
# transform=trans希望得到的是一個tensor而不是一張圖片
mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)

Fashion-MNIST由10個類別的圖像組成,每個類別由訓練數據集(train dataset)中的6000張圖像和測試數據集(test dataset)中的1000張圖像組成。因此,訓練集和測試集分別包含60000和10000張圖像。測試數據集不會用于訓練,只用于評估模型性能。
在這里插入圖片描述
每個輸入圖像的高度和寬度均為28像素。
數據集由灰度圖像組成,其通道數為1。
為了簡潔起見,將高度 h h h像素、寬度 w w w像素圖像的形狀記為 h × w h \times w h×w或( h h h, w w w)。
在這里插入圖片描述
接著定義兩個可視化數據集的函數

Fashion-MNIST中包含的10個類別,分別為t-shirt(T恤)、trouser(褲子)、pullover(套衫)、dress(連衣裙)、coat(外套)、sandal(涼鞋)、shirt(襯衫)、sneaker(運動鞋)、bag(包)和ankle boot(短靴)。

以下函數用于在數字標簽索引及其文本名稱之間進行轉換。

def get_fashion_mnist_labels(labels):  #@save"""返回Fashion-MNIST數據集的文本標簽"""text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save"""繪制圖像列表"""figsize = (num_cols * scale, num_rows * scale)_, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)axes = axes.flatten()for i, (ax, img) in enumerate(zip(axes, imgs)):if torch.is_tensor(img):# 圖片張量ax.imshow(img.numpy())else:# PIL圖片ax.imshow(img)ax.axes.get_xaxis().set_visible(False)ax.axes.get_yaxis().set_visible(False)if titles:ax.set_title(titles[i])return axes

以下展示訓練數據集中前幾個樣本的圖像及其相應的標簽。
在這里插入圖片描述
為了使我們在讀取訓練集和測試集時更容易,我們使用內置的數據迭代器,而不是從零開始創建。
在每次迭代中,數據加載器每次都會讀取一小批量數據,大小為batch_size

通過內置數據迭代器,我們可以隨機打亂了所有樣本,從而無偏見地讀取小批量。

batch_size = 256def get_dataloader_workers():  #@save"""使用4個進程來讀取數據"""return 4train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers())timer = d2l.Timer() # 用來測試速度
for X, y in train_iter:continue
f'{timer.stop():.2f} sec'

在這里插入圖片描述
在模型訓練之前,一般都是需要測試數據讀取的速度,數據讀取的速度需要比模型的訓練速度更快才好。

基于上述內容,現在我們定義load_data_fashion_mnist函數,用于獲取和讀取Fashion-MNIST數據集。這個函數返回訓練集驗證集的數據迭代器。此外,這個函數還接受一個可選參數resize,用來將圖像大小調整為另一種形狀。

def load_data_fashion_mnist(batch_size, resize=None):  #@save"""下載Fashion-MNIST數據集,然后將其加載到內存中"""trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False,num_workers=get_dataloader_workers()))

在這里插入圖片描述

Softmax 回歸從0開始實現

import torch
from IPython import display
from d2l import torch as d2lbatch_size = 256 # 每次隨機讀取256張圖片
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) # 前面實現過

由于圖像是12828的,但是對于softmax來說,輸入的需要是一個向量。(但是這種操作會損失很多空間信息,卷積部分解決。)因此我們將展平每個圖像,把它們看作長度為784的向量。數據集有十個類別,因此網絡輸出維度就是10。

num_inputs = 784 # 將空間拉長,28*28拉成784的一個向量
num_outputs = 10W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
# 行數為輸入的個數,列數等于輸出的個數
b = torch.zeros(num_outputs, requires_grad=True)
# 對每一個輸出,都需要有一個偏移

下面定義 softmax 操作:
在這里插入圖片描述實現softmax由三個步驟組成:

  1. 對每個項求冪(使用exp);
  2. 對每一行求和(小批量中每個樣本是一行),得到每個樣本的規范化常數;
  3. 將每一行除以其規范化常數,確保結果的和為1。

表達式如下:
s o f t m a x ( X ) i j = exp ? ( X i j ) ∑ k exp ? ( X i k ) . \mathrm{softmax}(\mathbf{X})_{ij} = \frac{\exp(\mathbf{X}_{ij})}{\sum_k \exp(\mathbf{X}_{ik})}. softmax(X)ij?=k?exp(Xik?)exp(Xij?)?.分母或規范化常數,有時也稱為配分函數(其對數稱為對數-配分函數)。該名稱來自統計物理學中一個模擬粒子群分布的方程。

def softmax(X):X_exp = torch.exp(X) # 對X中的每個元素作指數運算partition = X_exp.sum(1, keepdim=True) # 按照每一行進行求和return X_exp / partition  # 這里應用了廣播機制

在這里插入圖片描述
定義softmax操作后,可以實現softmax回歸模型
下面的代碼定義了輸入如何通過網絡映射到輸出。
注意,將數據傳遞到模型之前,我們使用reshape函數將每張原始圖像展平為向量。

def net(X):return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)

首先回顧一下交叉熵:
交叉熵采用真實標簽的預測概率的負對數似然。這里我們不使用Python的for循環迭代預測(這往往是低效的),而是通過一個運算符選擇所有元素。

下面,**創建一個數據樣本y_hat,其中包含2個樣本在3個類別的預測概率,以及它們對應的標簽y。**有了y,我們知道在第一個樣本中,第一類是正確的預測;而在第二個樣本中,第三類是正確的預測。然后(使用y作為y_hat中概率的索引),我們選擇第一個樣本中第一個類的概率和第二個樣本中第三個類的概率。

y = torch.tensor([0, 2]) # 表示兩個樣本的真實標簽分別為0、2
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y_hat[[0, 1], y] 
# 對第0個樣本,拿出y[0]對應的那個元素,對第一個樣本,拿出y[1]對應的那個元素
# [0, 1] 是一個索引列表,表示要選取 y_hat 中的第一行和第二行。

在這里插入圖片描述
基于上述,我們下面來實現交叉熵損失函數:

# 了解交叉熵公式和代碼上述原理,一行代碼即可完成。
def cross_entropy(y_hat, y):return - torch.log(y_hat[range(len(y_hat)), y])cross_entropy(y_hat, y)

在這里插入圖片描述
由于上述是分類問題,因此需要將預測類別與真實 y y y 元素進行比較:

def accuracy(y_hat, y):  #@save"""計算預測正確的數量"""# 要是 y_hat 是一個二維矩陣且列數也大于1 if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: y_hat = y_hat.argmax(axis=1) # 按每一行來存最大值的下標cmp = y_hat.type(y.dtype) == y  # 將 y_hat 轉換為 y 的數據類型,然后作比較return float(cmp.type(y.dtype).sum()) # 返回預測正確的樣本數

我們將繼續使用之前定義的變量y_haty分別作為預測的概率分布和標簽。可以看到,第一個樣本的預測類別是2(該行的最大元素為0.6,索引為2),這與實際標簽0不一致。第二個樣本的預測類別是2(該行的最大元素為0.5,索引為2),這與實際標簽2一致。因此,這兩個樣本的分類精度率為0.5。
在這里插入圖片描述
同樣,對于任意數據迭代器data_iter可訪問的數據集,可以評估在任意模型net的精度

def evaluate_accuracy(net, data_iter):  #@save"""計算在指定數據集上模型的精度"""if isinstance(net, torch.nn.Module):net.eval()  # 將模型設置為評估模式metric = Accumulator(2)  # 正確預測數、預測總數with torch.no_grad():for X, y in data_iter:metric.add(accuracy(net(X), y), y.numel())return metric[0] / metric[1]

這里定義一個實用程序類Accumulator,用于對多個變量進行累加。在上面的evaluate_accuracy函數中,我們在(Accumulator實例中創建了2個變量,分別用于存儲正確預測的數量和預測的總數量)。當我們遍歷數據集時,兩者都將隨著時間的推移而累加。

class Accumulator:  #@save"""在n個變量上累加"""def __init__(self, n):self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]

在這里插入圖片描述
下面就可以進行 softmax 的回歸訓練了:

def train_epoch_ch3(net, train_iter, loss, updater):  #@save"""訓練模型一個迭代周期(定義見第3章)"""# 將模型設置為訓練模式if isinstance(net, torch.nn.Module):net.train()# 訓練損失總和、訓練準確度總和、樣本數metric = Accumulator(3)for X, y in train_iter:# 計算梯度并更新參數y_hat = net(X)l = loss(y_hat, y)if isinstance(updater, torch.optim.Optimizer):# 使用PyTorch內置的優化器和損失函數updater.zero_grad()l.mean().backward()updater.step()else:# 使用定制的優化器和損失函數l.sum().backward()updater(X.shape[0])metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())# 返回訓練損失和訓練精度return metric[0] / metric[2], metric[1] / metric[2]

在展示訓練函數的實現之前,我們[定義一個在動畫中繪制數據的實用程序類]Animator

class Animator:  #@save"""在動畫中繪制數據"""def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,ylim=None, xscale='linear', yscale='linear',fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,figsize=(3.5, 2.5)):# 增量地繪制多條線if legend is None:legend = []d2l.use_svg_display()self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)if nrows * ncols == 1:self.axes = [self.axes, ]# 使用lambda函數捕獲參數self.config_axes = lambda: d2l.set_axes(self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)self.X, self.Y, self.fmts = None, None, fmtsdef add(self, x, y):# 向圖表中添加多個數據點if not hasattr(y, "__len__"):y = [y]n = len(y)if not hasattr(x, "__len__"):x = [x] * nif not self.X:self.X = [[] for _ in range(n)]if not self.Y:self.Y = [[] for _ in range(n)]for i, (a, b) in enumerate(zip(x, y)):if a is not None and b is not None:self.X[i].append(a)self.Y[i].append(b)self.axes[0].cla()for x, y, fmt in zip(self.X, self.Y, self.fmts):self.axes[0].plot(x, y, fmt)self.config_axes()display.display(self.fig)display.clear_output(wait=True)

下面開始訓練:

def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):  #@save"""訓練模型(定義見第3章)"""animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],legend=['train loss', 'train acc', 'test acc'])for epoch in range(num_epochs):train_metrics = train_epoch_ch3(net, train_iter, loss, updater)test_acc = evaluate_accuracy(net, test_iter)animator.add(epoch + 1, train_metrics + (test_acc,))train_loss, train_acc = train_metricsassert train_loss < 0.5, train_lossassert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_acc

[小批量隨機梯度下降來優化模型的損失函數],設置學習率為0.1

lr = 0.1def updater(batch_size):return d2l.sgd([W, b], lr, batch_size)

在這里插入圖片描述
對圖像進行預測:

def predict_ch3(net, test_iter, n=6):  #@save"""預測標簽"""for X, y in test_iter:breaktrues = d2l.get_fashion_mnist_labels(y)preds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1))titles = [true +'\n' + pred for true, pred in zip(trues, preds)]d2l.show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])predict_ch3(net, test_iter)

在這里插入圖片描述

Softmax 回歸的簡潔實現

通過深度學習框架的高級API也能更方便地實現softmax回歸模型:

import torch
from torch import nn
from d2l import torch as d2lbatch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

Softmax 回歸的輸出層是一個全連接層

# PyTorch不會隱式地調整輸入的形狀。因此,
# 我們在線性層前定義了展平層(flatten),來調整網絡輸入的形狀
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights);

在交叉熵損失函數中傳遞未規范化的預測,并同時計算softmax及其對數

loss = nn.CrossEntropyLoss(reduction='none')# 不進行任何減少操作,返回每個樣本的損失值。

使用學習率為0.1的小批量隨機梯度下降作為優化算法

trainer = torch.optim.SGD(net.parameters(), lr=0.1)

訓練,重用之前編寫的函數:
在這里插入圖片描述

QA思考

Q1:softlabel訓練策略。

上述被稱為軟標簽,旨在通過使用非硬性(即不是0或1的絕對分類結果)的目標標簽來提高模型的泛化能力和魯棒性。
傳統的分類任務中,目標標簽通常是one-hot編碼的形式,即對于每個樣本,正確的類別標記為1,其他類別標記為0。但是實際上對于邊界值是很難達到的,比如對于softmax函數而言:
softmax ( z i ) = e z i ∑ j = 1 n e z j \text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{n} e^{z_j}} softmax(zi?)=j=1n?ezj?ezi??
要想使其輸出為 1 ,則需要某一個 z i z_i zi? ,趨近于無窮才行。

而softlabel則允許這些標簽值位于(0, 1)之間,并且所有類別的概率之和通常為1。這意味著即使是錯誤的類別也可能被賦予一定的概率,從而向模型傳達“某種程度上的正確”。比如我可以認為0.9 就是正確,0.1 就是不正確。

Q2 : softmax 回歸和 logistic 回歸的聯系。
可以認為logistic是softmax的特例,也就是logistic是一個兩分類的問題,只需要輸出一個類別的概率 P P P 即可,剩下的直接 1 ? P 1-P 1?P 即可。但是在實際的分類問題中,兩分類的問題很少。

Q3 : 在 Accuracy函數中為啥不把除以 len(y) 做完呢?
在 Accuracy 函數中,不能直接除以 len(y),因為最后一個 batch 的樣本數量可能會少于設定的 batch size。為了確保準確率計算的正確性,應該根據當前 batch 實際包含的樣本數量進行歸一化,而不是固定地使用完整的 batch size。

補充:
考慮到李沐老師的視線中使用到了d2l,且是在jupyter上面進行實現的,但是我現在不想用d2l,以及需要再Pycharm上面編寫,于是我根據上述代碼編寫了下面的代碼,結果也能很好的復現李沐老師代碼的結果。

import torch
import torchvision
from torchvision import transforms
from torch.utils import data
import matplotlib.pyplot as pltclass Animator:def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,ylim=None, xscale='linear', yscale='linear',fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5)):if legend is None:legend = []self.xlabel = xlabelself.ylabel = ylabelself.legend = legendself.xlim = xlimself.ylim = ylimself.xscale = xscaleself.yscale = yscaleself.fmts = fmtsself.figsize = figsizeself.X, self.Y = [], []def add(self, x, y):if not hasattr(y, "__len__"):y = [y]n = len(y)if not hasattr(x, "__len__"):x = [x] * nif not self.X:self.X = [[] for _ in range(n)]if not self.Y:self.Y = [[] for _ in range(n)]for i, (a, b) in enumerate(zip(x, y)):if a is not None and b is not None:self.X[i].append(a)self.Y[i].append(b)def show(self):plt.figure(figsize=self.figsize)for x_data, y_data, fmt in zip(self.X, self.Y, self.fmts):plt.plot(x_data, y_data, fmt)plt.xlabel(self.xlabel)plt.ylabel(self.ylabel)if self.legend:plt.legend(self.legend)if self.xlim:plt.xlim(self.xlim)if self.ylim:plt.ylim(self.ylim)plt.xscale(self.xscale)plt.yscale(self.yscale)plt.grid()plt.show()def get_dataloader_workers():return 0  # 禁用多進程加載def load_data_fashion_mnist(batch_size, resize=None):trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST("./data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST("./data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True, num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False, num_workers=get_dataloader_workers()))# softmax 實現
def softmax(X):X_exp = torch.exp(X)partition = X_exp.sum(1, keepdim=True)return X_exp / partition# 回歸模型
def net(X):return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)# 交叉熵損失函數
def cross_entropy(y_hat, y):return -torch.log(y_hat[range(len(y_hat)), y])# 預測正確的數量
def accuracy(y_hat, y):if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = y_hat.argmax(axis=1)cmp = y_hat.type(y.dtype) == yreturn float(cmp.type(y.dtype).sum())class Accumulator:def __init__(self, n):self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def reset(self):self.data = [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]def evaluate_accuracy(net, data_iter):if isinstance(net, torch.nn.Module):net.eval()metric = Accumulator(2)with torch.no_grad():for X, y in data_iter:metric.add(accuracy(net(X), y), y.numel())return metric[0] / metric[1]def train_epoch_ch3(net, train_iter, loss, updater):if isinstance(net, torch.nn.Module):net.train()metric = Accumulator(3)for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y)if isinstance(updater, torch.optim.Optimizer):updater.zero_grad()l.mean().backward()updater.step()else:l.sum().backward()updater(X.shape[0])metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())return metric[0] / metric[2], metric[1] / metric[2]def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],legend=['train loss', 'train acc', 'test acc'])for epoch in range(num_epochs):train_metrics = train_epoch_ch3(net, train_iter, loss, updater)test_acc = evaluate_accuracy(net, test_iter)animator.add(epoch + 1, train_metrics + (test_acc,))train_loss, train_acc = train_metricsassert train_loss < 0.5, train_lossassert train_acc <= 1 and train_acc > 0.7, train_accassert test_acc <= 1 and test_acc > 0.7, test_accanimator.show()  # 展示最終結果圖def sgd(params, lr, batch_size):with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()def updater(batch_size):return sgd([W, b], lr, batch_size)def get_fashion_mnist_labels(labels):text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):figsize = (num_cols * scale, num_rows * scale)_, axes = plt.subplots(num_rows, num_cols, figsize=figsize)axes = axes.flatten()for i, (ax, img) in enumerate(zip(axes, imgs)):if torch.is_tensor(img):ax.imshow(img.numpy(), cmap='gray')else:ax.imshow(img, cmap='gray')ax.axes.get_xaxis().set_visible(False)ax.axes.get_yaxis().set_visible(False)if titles:ax.set_title(titles[i])plt.show()def predict_ch3(net, test_iter, n=6):for X, y in test_iter:breaktrues = get_fashion_mnist_labels(y)preds = get_fashion_mnist_labels(net(X).argmax(axis=1))titles = [true + '\n' + pred for true, pred in zip(trues, preds)]show_images(X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])if __name__ == "__main__":# 定義超參數batch_size = 256num_epochs = 10lr = 0.1# 加載數據train_iter, test_iter = load_data_fashion_mnist(batch_size)# 初始化模型參數num_inputs = 784num_outputs = 10W = torch.normal(0, 0.1, size=(num_inputs, num_outputs), requires_grad=True)b = torch.zeros(num_outputs, requires_grad=True)# 訓練模型train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)# 測試模型并顯示預測結果predict_ch3(net, test_iter)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73516.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73516.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73516.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL-存儲過程

介紹 基本語法 創建 調用 查看 刪除 變量 系統變量 查看 設置 用戶定義變量 賦值 使用 局部變量 聲明 賦值 流程控制 參數 條件結構 IF case 循環結構 while repeat loop 游標 條件處理程序 介紹 舉個簡單的例子&#xff0c;我們先select某數據&…

使用 Go 和 Gin 實現高可用負載均衡代理服務器

前言 在現代分布式系統中,負載均衡是保障服務高可用性和性能的核心技術。本文將基于 Go 語言和 Gin 框架實現一個支持動態路由、健康檢查、會話保持等特性的企業級負載均衡代理服務器,并提供完整的壓力測試方案和優化建議。 通過本方案實現的負載均衡代理具備以下優勢: 單…

在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 MineCraft 服務器,并實現遠程聯機,詳細教程

Linux 部署 MineCraft 服務器 詳細教程&#xff08;丐版&#xff0c;無需云服務器&#xff09; 一、虛擬機 Ubuntu 部署二、下載 Minecraft 服務端三、安裝 JRE 21四、安裝 MCS manager 面板五、搭建服務器六、本地測試連接七、下載櫻花&#xff0c;實現內網穿透&#xff0c;邀…

批量取消 PDF 文檔中的所有超鏈接

在 PDF 文檔中我們可以插入各種各樣的文本也可以給文本設置字體&#xff0c;顏色等多種樣式&#xff0c;同時還可以給文字或者圖片添加上超鏈接&#xff0c;當我們點擊超鏈接之后&#xff0c;就會跳轉到對應的網頁。有時候這會對我們的閱讀或者使用形成一定的干擾&#xff0c;今…

Ubuntu xinference部署本地模型bge-large-zh-v1.5、bge-reranker-v2-m3

bge-large-zh-v1.5 下載模型到指定路徑&#xff1a; modelscope download --model BAAI/bge-large-zh-v1.5 --local_dir ./bge-large-zh-v1.5自定義 embedding 模型&#xff0c;custom-bge-large-zh-v1.5.json&#xff1a; {"model_name": "custom-bge-large…

Vue的實例

Every Vue application starts with a single Vue component instance as the application root. Any other Vue component created in the same application needs to be nested inside this root component. 每個 Vue 應用都以一個 Vue 組件實例作為應用的根開始。在同一個應…

Linux學習筆記(應用篇三)

基于I.MX6ULL-MINI開發板 LED學習GPIO應用編程輸入設備 開發板中所有的設備&#xff08;對象&#xff09;都會在/sys/devices 體現出來&#xff0c;是 sysfs 文件系統中最重要的目錄結構 /sys下的子目錄說明/sys/devices這是系統中所有設備存放的目錄&#xff0c;也就是系統中…

【圖論】網絡流算法入門

&#xff08;決定狠狠加訓圖論了&#xff0c;從一直想學但沒啟動的網絡流算法開始。&#xff09; 網絡流問題 ? 問題定義&#xff1a;在帶權有向圖 G ( V , E ) G(V, E) G(V,E) 中&#xff0c;每條邊 e ( u , v ) e(u, v) e(u,v) 有容量 c ( u , v ) c(u, v) c(u,v)&am…

遞歸、搜索與回溯第四講:floodfill算法

遞歸、搜索與回溯第四講&#xff1a;floodfill算法 1.Floodfill算法介紹2.圖像渲染3.島嶼數量4.島嶼的最大面積5.被圍繞的區域6.太平洋大西洋水流問題7.掃雷游戲8.衣櫥整理 1.Floodfill算法介紹 2.圖像渲染 3.島嶼數量 4.島嶼的最大面積 5.被圍繞的區域 6.太平洋大西洋水流問題…

【深度學習與實戰】2.3、線性回歸模型與梯度下降法先導案例--最小二乘法(向量形式求解)

為了求解損失函數 對 的導數&#xff0c;并利用最小二乘法向量形式求解 的值? 這是?線性回歸?的平方誤差損失函數&#xff0c;目標是最小化預測值 與真實值 之間的差距。 ?損失函數?&#xff1a; 考慮多個樣本的情況&#xff0c;損失函數為所有樣本的平方誤差之和&a…

氣象可視化衛星云圖的方式:方法與架構詳解

氣象衛星云圖是氣象預報和氣候研究的重要數據來源。通過可視化技術,我們可以將衛星云圖數據轉化為直觀的圖像或動畫,幫助用戶更好地理解氣象變化。本文將詳細介紹衛星云圖可視化的方法、架構和代碼實現。 一、衛星云圖可視化方法 1. 數據獲取與預處理 衛星云圖數據通常來源…

瀏覽器渲染原理與優化詳解

一、瀏覽器渲染基礎原理 瀏覽器渲染流程主要包括以下步驟&#xff08;也稱為"關鍵渲染路徑"&#xff09;&#xff1a; 構建DOM樹&#xff1a;將HTML解析為DOM&#xff08;文檔對象模型&#xff09;樹構建CSSOM樹&#xff1a;將CSS解析為CSSOM&#xff08;CSS對象模…

基于Spring Boot的成績管理系統后臺實現

下面是一個完整的成績管理系統后臺實現&#xff0c;使用Spring Boot框架&#xff0c;包含學生管理、課程管理和成績管理功能。 1. 項目結構 src/main/java/com/example/grademanagement/ ├── config/ # 配置類 ├── controller/ # 控制器 ├── dto/ …

實現極限網關(INFINI Gateway)配置動態加載

還在停機更新 Gateway 配置&#xff0c;OUT 了。 今天和大家分享一個 Gateway 的功能&#xff1a;動態加載配置&#xff08;也稱熱更新或熱加載&#xff09;。 這個功能可以在 Gateway 不停機的情況下更新配置并使之生效。 配置樣例如下&#xff1a; path.data: data path.…

Mean Shift 圖像分割與 Canny 邊緣檢測教程

1. Mean Shift 簡介 Mean Shift 是一種聚類算法&#xff0c;通過尋找圖像中顏色相似的區域來實現分割。它非常適合用于場景分割或物體檢測等任務。本教程將它與 Canny 邊緣檢測結合&#xff0c;突出分割區域的邊界。 2. 圖像分割流程 我們將按照以下步驟完成圖像分割和邊緣檢…

Day15 -實例 端口掃描工具 WAF識別工具的使用

一、端口掃描工具 1、zenmap 我這里user是漢字名&#xff0c;沒有解析成功。等后續換一個英文賬戶試一試。 魔改kali的nmap nmap -p8000-9000 8.140.159.19 2、masscan cmd啟動&#xff0c;拖入exe文件。然后先寫ip&#xff0c;會報錯給提示 尋路犬系統 我們去找一下他的…

如何解決高并發場景下的性能瓶頸?實踐分享

解決高并發性能瓶頸的核心方法包括優化系統架構、合理使用緩存技術、數據庫優化及擴展策略、負載均衡設計。 其中&#xff0c;優化系統架構是根本解決性能問題的關鍵所在。良好的系統架構能夠有效支撐業務高效穩定運行&#xff0c;避免性能瓶頸帶來的損失。企業可通過微服務架構…

自動駕駛背后的數學:ReLU,Sigmoid, Leaky ReLU, PReLU,Swish等激活函數解析

隨著自動駕駛技術的飛速發展&#xff0c;深度學習在其中扮演著至關重要的角色。而激活函數作為神經網絡中的關鍵組件&#xff0c;直接影響著模型的性能和效果。前面幾篇博客 自動駕駛背后的數學&#xff1a;特征提取中的線性變換與非線性激活 , 「自動駕駛背后的數學&#xff1…

性能測試、負載測試、壓力測試的全面解析

在軟件測試領域&#xff0c;性能測試、負載測試和壓力測試是評估系統穩定性和可靠性的關鍵手段。?它們各自關注不同的測試目標和應用場景&#xff0c;理解這些差異對于制定有效的測試策略至關重要。 本文對性能測試、負載測試和壓力測試進行深入分析&#xff0c;探討其定義、…

責任鏈模式-java

1、spring依賴注入模式 @Configuration public class ChainConfig {@Beanpublic ChainSpringFactory chainSpringFactory(List<IHandler<DemoOne,Boolean>> handlerList){return new ChainSpringFactory(handlerList);}} public class DemoOne { }public abstract…