??????歡迎來到我的博客,你將找到有關(guān)如何使用技術(shù)解決問題的文章,也會找到某個(gè)技術(shù)的學(xué)習(xí)路線。無論你是何種職業(yè),我都希望我的博客對你有所幫助。最后不要忘記訂閱我的博客以獲取最新文章,也歡迎在文章下方留下你的評論和反饋。我期待著與你分享知識、互相學(xué)習(xí)和建立一個(gè)積極的社區(qū)。謝謝你的光臨,讓我們一起踏上這個(gè)知識之旅!
??引言
當(dāng)處理多分類問題時(shí),PyTorch是一種非常有用的深度學(xué)習(xí)框架。在這篇博客中,我們將討論如何使用PyTorch來解決多分類問題。我們將介紹多分類問題的基本概念,構(gòu)建一個(gè)簡單的多分類神經(jīng)網(wǎng)絡(luò)模型,并演示如何準(zhǔn)備數(shù)據(jù)、訓(xùn)練模型和評估結(jié)果。
??什么是多分類問題?
多分類問題是一種機(jī)器學(xué)習(xí)任務(wù),其中目標(biāo)是將輸入數(shù)據(jù)分為多個(gè)不同的類別或標(biāo)簽。與二分類問題不同,多分類問題涉及到三個(gè)或更多類別的分類任務(wù)。例如,圖像分類問題可以將圖像分為不同的類別,如貓、狗、鳥等。
??處理步驟
-
準(zhǔn)備數(shù)據(jù):
收集和準(zhǔn)備數(shù)據(jù)集,確保每個(gè)樣本都有相應(yīng)的標(biāo)簽,以指明其所屬類別。
劃分?jǐn)?shù)據(jù)集為訓(xùn)練集、驗(yàn)證集和測試集,以便進(jìn)行模型訓(xùn)練、調(diào)優(yōu)和性能評估。 -
數(shù)據(jù)預(yù)處理:
對數(shù)據(jù)進(jìn)行預(yù)處理,例如歸一化、標(biāo)準(zhǔn)化、缺失值處理或數(shù)據(jù)增強(qiáng),以確保模型訓(xùn)練的穩(wěn)定性和性能。 -
選擇模型架構(gòu):
選擇適當(dāng)?shù)纳疃葘W(xué)習(xí)模型架構(gòu),通常包括卷積神經(jīng)網(wǎng)絡(luò)(CNN)、循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)、Transformer等,具體取決于問題的性質(zhì)。 -
定義損失函數(shù):
為多分類問題選擇適當(dāng)?shù)膿p失函數(shù),通常是交叉熵?fù)p失(Cross-Entropy Loss)。 -
選擇優(yōu)化器:
選擇合適的優(yōu)化算法,如隨機(jī)梯度下降(SGD)、Adam、RMSprop等,以訓(xùn)練模型并調(diào)整權(quán)重。 -
訓(xùn)練模型:
使用訓(xùn)練數(shù)據(jù)集來訓(xùn)練模型。在每個(gè)訓(xùn)練迭代中,通過前向傳播和反向傳播來更新模型參數(shù),以減小損失函數(shù)的值。 -
評估模型:
使用驗(yàn)證集來評估模型性能。常見的性能指標(biāo)包括準(zhǔn)確性、精確度、召回率、F1分?jǐn)?shù)等。 -
調(diào)優(yōu)模型:
根據(jù)驗(yàn)證集的性能,對模型進(jìn)行調(diào)優(yōu),可以嘗試不同的超參數(shù)設(shè)置、模型架構(gòu)變化或數(shù)據(jù)增強(qiáng)策略。 -
測試模型:
最終,在獨(dú)立的測試數(shù)據(jù)集上評估模型的性能,以獲得最終性能評估。 -
部署模型:
將訓(xùn)練好的模型部署到實(shí)際應(yīng)用中,用于實(shí)時(shí)或批處理多分類任務(wù)。
??多分類問題
之前我們討論的問題都是二分類居多,對于二分類問題,我們?nèi)羟蟮胮(0),南無p(1)=1-p(0),還是比較容易的,但是本節(jié)我們將引入多分類,那么我們所求得就轉(zhuǎn)化為p(i)(i=1,2,3,4…),同時(shí)我們需要滿足以上概率中每一個(gè)都大于0;且總和為1。
處理多分類問題,這里我們新引入了一個(gè)稱為Softmax Layer
接下來我們一起討論一下Softmax Layer層
首先我們計(jì)算指數(shù)計(jì)算e的zi次冪,原因很簡單e的指數(shù)函數(shù)恒大于0;分母就是e的z1次冪+e的z2次冪+e的z3次冪…求和,這樣所有的概率和就為1了。
下圖形象的展示了Softmax,Exponent這里指指數(shù),和上面我們說的一樣,先求指數(shù),這樣有了分子,再將所有指數(shù)求和,最后一一divide,得到了每一個(gè)概率。
接下來我們一起來看看損失函數(shù)
如果使用numpy進(jìn)行實(shí)現(xiàn),根據(jù)劉二大人的代碼,可以進(jìn)行如下的實(shí)現(xiàn)
import numpy as np
y = np.array([1,0,0])
z = np.array([0.2,0.1,-0.1])
y_pred = np.exp(z)/np.exp(z).sum()
loss = (-y * np.log(y_pred)).sum()
print(loss)
運(yùn)行結(jié)果如下
注意:神經(jīng)網(wǎng)絡(luò)的最后一層不需要激活
在pytorch中
import torch
y = torch.LongTensor([0]) # 長整型
z = torch.Tensor([[0.2, 0.1, -0.1]])
criterion = torch.nn.CrossEntropyLoss()
loss = criterion(z, y)
print(loss)
運(yùn)行結(jié)果如下
下面根據(jù)一個(gè)例子進(jìn)行演示
criterion = torch.nn.CrossEntropyLoss()
Y = torch.LongTensor([2,0,1])
Y_pred1 = torch.Tensor([[0.1, 0.2, 0.9],
[1.1, 0.1, 0.2],
[0.2, 2.1, 0.1]])
Y_pred2 = torch.Tensor([[0.8, 0.2, 0.3],
[0.2, 0.3, 0.5],
[0.2, 0.2, 0.5]])
l1 = criterion(Y_pred1, Y)
l2 = criterion(Y_pred2, Y)
print("Batch Loss1 = ", l1.data, "\nBatch Loss2=", l2.data)
運(yùn)行結(jié)果如下
根據(jù)上面的代碼可以看出第一個(gè)損失比第二個(gè)損失要小。原因很簡單,想對于Y_pred1每一個(gè)預(yù)測的分類與Y是一致的,而Y_pred2則相差了一下,所以損失自然就大了些
??MNIST dataset的實(shí)現(xiàn)
首先第一步還是導(dǎo)包
import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
之后是數(shù)據(jù)的準(zhǔn)備
batch_size = 64
# transform可以將其轉(zhuǎn)化為0-1,形狀的轉(zhuǎn)換從28×28轉(zhuǎn)換為,1×28×28
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307, ), (0.3081, )) # 均值mean和標(biāo)準(zhǔn)差std
])
train_dataset = datasets.MNIST(root='../dataset/mnist/',
train=True,
download=True,
transform=transform)
train_loader = DataLoader(train_dataset,
shuffle=True,
batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/mnist/',
train=False,
download=True,
transform=transform)
test_loader = DataLoader(test_dataset,
shuffle=False,
batch_size=batch_size)
接下來我們構(gòu)建網(wǎng)絡(luò)
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.l1 = torch.nn.Linear(784, 512)
self.l2 = torch.nn.Linear(512, 256)
self.l3 = torch.nn.Linear(256, 128)
self.l4 = torch.nn.Linear(128, 64)
self.l5 = torch.nn.Linear(64, 10)
def forward(self, x):
x = x.view(-1, 784)
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = F.relu(self.l4(x))
return self.l5(x) # 注意最后一層不做激活
model = Net()
之后定義損失和優(yōu)化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
接下來就進(jìn)行訓(xùn)練了
def train(epoch):
running_loss = 0.0
for batch_idx, data in enumerate(train_loader, 0):
inputs, target = data
optimizer.zero_grad()
# forward + backward + update
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
if batch_idx % 300 == 299:
print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
running_loss = 0.0
def test():
correct = 0
total = 0
with torch.no_grad(): # 這里可以防止內(nèi)嵌代碼不會執(zhí)行梯度
for data in test_loader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, dim=1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy on test set: %d %%' % (100 * correct / total))
最后調(diào)用執(zhí)行
if __name__ == '__main__':
for epoch in range(10):
train(epoch)
test()
??NLLLoss 和 CrossEntropyLoss
NLLLoss 和 CrossEntropyLoss(也稱為交叉熵?fù)p失)是深度學(xué)習(xí)中常用的兩種損失函數(shù),用于測量模型的輸出與真實(shí)標(biāo)簽之間的差距,通常用于分類任務(wù)。它們有一些相似之處,但也有一些不同之處。
相同點(diǎn):
用途:兩者都用于分類任務(wù),評估模型的輸出和真實(shí)標(biāo)簽之間的差異,以便進(jìn)行模型的訓(xùn)練和優(yōu)化。
數(shù)學(xué)基礎(chǔ):NLLLoss 和 CrossEntropyLoss 本質(zhì)上都是交叉熵?fù)p失的不同變種,它們都以信息論的概念為基礎(chǔ),衡量兩個(gè)概率分布之間的相似度。
輸入格式:它們通常期望模型的輸出是一個(gè)概率分布,表示各個(gè)類別的預(yù)測概率,以及真實(shí)的標(biāo)簽。
不同點(diǎn):
輸入格式:NLLLoss 通常期望輸入是對數(shù)概率(log probabilities),而 CrossEntropyLoss 通常期望輸入是未經(jīng)對數(shù)化的概率。在實(shí)際應(yīng)用中,CrossEntropyLoss 通常與softmax操作結(jié)合使用,將原始模型輸出轉(zhuǎn)化為概率分布,而NLLLoss可以直接使用對數(shù)概率。
對數(shù)化:NLLLoss 要求將模型輸出的概率經(jīng)過對數(shù)化(取對數(shù))以獲得對數(shù)概率,然后與真實(shí)標(biāo)簽的離散概率分布進(jìn)行比較。CrossEntropyLoss 通常在 softmax 操作之后直接使用未對數(shù)化的概率值與真實(shí)標(biāo)簽比較。
輸出維度:NLLLoss 更通用,可以用于多種情況,包括多類別分類和序列生成等任務(wù),因此需要更多的靈活性。CrossEntropyLoss 通常用于多類別分類任務(wù)。
總之,NLLLoss 和 CrossEntropyLoss 都用于分類任務(wù),但它們在輸入格式和使用上存在一些差異。通常,選擇哪個(gè)損失函數(shù)取決于你的模型輸出的格式以及任務(wù)的性質(zhì)。如果你的模型輸出已經(jīng)是對數(shù)概率形式,通常使用NLLLoss,否則通常使用CrossEntropyLoss。
文章來源:http://www.zghlxwxcb.cn/news/detail-722891.html
挑戰(zhàn)與創(chuàng)造都是很痛苦的,但是很充實(shí)。文章來源地址http://www.zghlxwxcb.cn/news/detail-722891.html
到了這里,關(guān)于使用PyTorch解決多分類問題:構(gòu)建、訓(xùn)練和評估深度學(xué)習(xí)模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!