softmax多分類學習

2021-10-23 06:14:45 字數 4423 閱讀 2654

'''

softmax回歸從零開始實現

'''import torch

import torchvision

import numpy as np

import sys

import d2lzh_pytorch as d2l

'''獲取資料

'''batch_size = 256

train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

print(train_iter, test_iter)

'''初始化模型引數

引數選擇原因

每個樣本輸入的是長和寬(均為28),所以模型的輸入向量長度就是28*28=784

一共有十個影象類別,所以單層神經網路有10個輸出

因此softmax的權重跟偏差數分別為784*10 和 1*10

'''num_inputs = 784

num_output = 10

w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_output)), dtype=torch.float)

b = torch.zeros(num_output, dtype=torch.float)

w.requires_grad_(requires_grad=true)

b.requires_grad_(requires_grad=true)

'''實現softma運算

tensor 對多維度操作

我們需要實現對其中的一行或者一列進行求和,並在結果中保留行(dim=0)or列(dim=1)這兩個維度(keepdim=true)

求和不影響原來的張量

x = torch.tensor([[1,2,3],[4,5,6]])

print(x.sum(dim=0, keepdim=true))

print(x)

tensor([[5, 7, 9]])

tensor([[1, 2, 3],

[4, 5, 6]])

'''def softmax(x):

x_exp = x.exp()

partition = x_exp.sum(dim=1, keepdim=true)

'''這個函式先對每個元素進行指數運算(exp),

然後對exp矩陣同行元素進行求和,

最後領矩陣每行各元素與該行元素之和相除

得到矩陣每行元素和為1,即每行代表了該樣本在不用類目下的**概率

:param x:

:return: 返回的矩陣是乙個**矩陣,任何乙個元素代表乙個樣本在格式輸出類別的**概率

'''return x_exp / partition

'''定義模型

'''def net(x):

return softmax(torch.mm(x.view((-1, num_inputs)),w)+b)

'''定義損失函式

softmax回歸使用交叉熵損失函式,為了得到標籤的**概率使用gather函式

torch.gather(input, dim, index, out=none)

維度dim按照索引列表index從input中選取指定元素

y_hat = torch.tensor([[0.1, 0.3, 0.6],[0.3, 0.2, 0.5]])

print(y_hat)

y = torch.longtensor([0, 2])

print(y_hat.gather(1, y.view(-1, 1)))

tensor([[0.1000, 0.3000, 0.6000],

[0.3000, 0.2000, 0.5000]])

tensor([[0.1000],

[0.5000]])

gather函式會按照index的torch的形狀進行選取input裡面的元素

dim=1 則按照行進行選擇

即本例子選擇的是第一行的第乙個(索引為0的元素),第二行的第三個(索引為2的元素)

y_hat = torch.tensor([[0.1, 0.3, 0.6],[0.3, 0.2, 0.5]])

y = torch.longtensor([[0, 0, 1],[1, 0, 1]])

print(y_hat.gather(0, y))

tensor([[0.1000, 0.3000, 0.6000],

[0.3000, 0.2000, 0.5000]])

tensor([[0.1000, 0.3000, 0.5000],

[0.3000, 0.3000, 0.5000]])

dim為0的 按列進行選擇

所以得到的結果應該是

第一列的第乙個 第二列的第乙個 第三列的第二個

第一列的第二個 第二列的第乙個 第三列的第二個

# 使用小技巧 y.view(-1, 1) 會將y轉換成總長度除以1得到的行數,1為列的張量

# 舉例說明

# y = torch.arange(15)

# y.view(5,3)

# y.view(-1,3)

# y.view(5,-1)

# 以上三個都是一樣的效果

'''def cross_entropy(y_hat, y):

return - torch.log(y_hat.gather(1,y.view(-1,1)))

'''計算分類準確率 (分類**正確的數量佔總**數量的比)

使用y_hat.argmax(dim=1)函式 返回的是矩陣y_hat每行最大的索引,

且返回結果的形狀跟y_hat形狀一樣

'''def accuracy(y_hat, y):

''':param y_hat: **值

:param y: 真實值

:return:

'''return (y_hat.argmax(dim=1) == y).float().mean().item()

'''0.5

通例子可以看出來

**值中第一行**值為0.6 索引為 2

實際值中正確值為0.1 索引為0

**值中第一行**值為0.5 索引為 2

實際值中正確值為0.5 索引為2

'''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

print(evaluate_accuracy(test_iter, net))

'''訓練模型

使用小批量隨機梯度下降來優化模型的損失函式

'''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()

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(f'epoch , loss , train acc , test acc ')

num_epochs, lr = 5, 0.1

train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [w, b], lr)

多分類學習

多分類學習的基本思路是拆解法,即將多個二分類任務拆為若干個二分類任務求解。具體地就是,先對問題進行拆分,然後為每個拆分的二分類任務訓練乙個分類器 在測試時,對這些分類器的 結果進行整合以獲得最終的多分類結果。關鍵 多分類任務如何拆分。經典的為 一對一 one vs one,ovo 一對多 one v...

softmax的多分類

from 我們常見的邏輯回歸 svm等常用於解決二分類問題,對於多分類問題,比如識別手寫數字,它就需要10個分類,同樣也可以用邏輯回歸或svm,只是需要多個二分類來組成多分類,但這裡討論另外一種方式來解決多分類 softmax。softmax的函式為 p i exp tix kk 1exp tkx ...

softmax的多分類

我們常見的邏輯回歸 svm等常用於解決二分類問題,對於多分類問題,比如識別手寫數字,它就需要10個分類,同樣也可以用邏輯回歸或svm,只是需要多個二分類來組成多分類,但這裡討論另外一種方式來解決多分類 softmax。softmax的函式為 p i dfrac exp theta k tx 可以看到...