最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

09 Softmax 回歸 + 損失函數(shù) + 圖片分類數(shù)據(jù)集【動手學(xué)深度學(xué)習(xí)v2

2021-11-18 18:18 作者:如果我是泡橘子  | 我要投稿

----未完待續(xù)----



softmax回歸


  • softmax回歸是機器學(xué)習(xí)中非常重要而且經(jīng)典的模型,他的名字雖然叫回歸,但實際上是一個分類問題



分類與回歸

  • 回歸是估計一個連續(xù)值
  • 分類是預(yù)測一個連續(xù)的類別
  • 分類問題舉例






從回歸到多類分類


  • 分類問題從單輸出變成了多輸出,輸出的個數(shù)等于類別的個數(shù)



從回歸到多類分類


  • 類別是一個數(shù),也可能是一個字符串
  • 一位有效編碼:剛好有一個位置有效的編碼方式(有效的那一位為 1 ,其它位上全部置 0 )
  • 不關(guān)心置信度的值是多少,只關(guān)心正確類別的置信度的值要遠(yuǎn)遠(yuǎn)高于其他非正確類置信度,使得正確的類別能夠與其他類別拉開距離
  • 雖然關(guān)心的是一個相對值,但是需要把這些值放在一個合適的區(qū)間
  • 希望是輸出能夠盡量是一個概率
  • y^:一個長為 n 的向量,每個元素都非負(fù),而且這些元素加起來的和為 1
  • exp(o):e 的 o 次方,e 是一個指數(shù)常數(shù)。指數(shù)的好處是:不管是什么值都能將它變成非負(fù)
  • 通過 softmax 將輸出 o 變成了概率



softmax 和交叉熵?fù)p失


  • 一般來說使用真實概率與預(yù)測概率的區(qū)別來作為損失
  • 假設(shè) p 和 q 是兩個離散概率
  • 上圖中第二式的化簡:根據(jù)前面的一位有效編碼,yi中只有一位有效元素為1,其他都為0
  • 對分類問題來講,不關(guān)心對于非正確類的預(yù)測值,只關(guān)心對于正確類的預(yù)測值及其置信度的大小



總結(jié)


  • softmax 回歸是一個多分類分類模型
  • 使用 softmax 操作子得到每個類的預(yù)測置信度(使得每個類的置信度是一個概率,非負(fù)且和為1)
  • 使用交叉熵來衡量預(yù)測和標(biāo)號的區(qū)別(作為損失函數(shù))





損失函數(shù)


  • 損失函數(shù)用來衡量預(yù)測值和真實值之間的區(qū)別



常用的損失函數(shù)


1、L2 Loss(均方損失)

  • 藍(lán)色曲線表示 y = 0 的時候變化預(yù)測值 y‘ 的函數(shù),這是一個二次函數(shù)
  • 綠色曲線是它的似然函數(shù),即exp( - l ),它的似然函數(shù)是一個高斯分布
  • 橙色曲線表示損失函數(shù)的梯度,它是一條過原點的直線
  • 在梯度下降的時候是根據(jù)負(fù)梯度方向來更新梯度,所以它的導(dǎo)數(shù)決定如何更新參數(shù)
  • 當(dāng) y 和 y‘ 離得比較遠(yuǎn)(橫軸到零點的距離越遠(yuǎn)),梯度越大,對參數(shù)的更新越多,更新的幅度越大,反之亦然



2、L2 Loss(絕對值損失函數(shù))

  • 藍(lán)色曲線表示 y = 0 的時候變化預(yù)測值 y‘ 的函數(shù)
  • 綠色曲線是它的似然函數(shù),即exp( - l )
  • 橙色曲線表示損失函數(shù)的梯度,當(dāng) 距離 > 1 的時候他的值為1,當(dāng) 距離 < 1 的時候他的值為-1
  • 絕對值函數(shù)在0點處不可導(dǎo)
  • 在梯度下降的時候是根據(jù)負(fù)梯度方向來更新梯度,它的梯度永遠(yuǎn)是常數(shù),所以就算 y 和 y‘ 離得比較遠(yuǎn),參數(shù)更新的幅度也不會太大,會帶來穩(wěn)定性上的好處
  • 它的缺點是在 0 點處不可導(dǎo),另外在 0 點處有一個 -1 到 1 的劇烈變化,不平滑性導(dǎo)致預(yù)測值和真實值靠的比較近的時候,也就是優(yōu)化到了末期的時候這個地方可能就變得不那么穩(wěn)定



Huber's Robust Loss(Huber魯棒損失)

  • 當(dāng)真實值和預(yù)測值相差較大時,他是一個絕對誤差,而當(dāng)他們相差較小時是一個均方誤差
  • 減去 1 / 2 的作用是使得分段函數(shù)的曲線能夠連起來
  • 藍(lán)色曲線表示 y = 0 的時候變化預(yù)測值 y‘ 的函數(shù),在 -1 到 1 之間是一個比較平滑的二次函數(shù),在這個區(qū)間外是一條直線
  • 綠色曲線是它的似然函數(shù),即exp( - l ),和高斯分布有點類似,但是不想絕對值誤差那樣在 0 點處有一個很尖的地方
  • 橙色曲線表示損失函數(shù)的梯度,當(dāng) 距離 > 1 的時候他的值為 -1 或者 1,是一個常數(shù),當(dāng)距離 < 1 的時候是一個漸變的過程,這樣的好處是當(dāng)預(yù)測值和真實值差得比較遠(yuǎn)的時候,參數(shù)值的更新比較均勻,而當(dāng)預(yù)測值和真實值相差比較近的時候,即在參數(shù)更新的末期,梯度會越來越小,保證優(yōu)化過程是比較平滑的,不會出現(xiàn)數(shù)值上的劇烈變化





圖片分類數(shù)據(jù)集


MNIST數(shù)據(jù)集(對手寫數(shù)字的識別)是圖像分類中廣泛使用的數(shù)據(jù)集之一,但是作為基準(zhǔn)數(shù)據(jù)集過于簡單,因此使用類似但是更復(fù)雜的Fashion-MNIST數(shù)據(jù)集


1、導(dǎo)包


%matplotlib inline

import torch

import torchvision

from torch.utils import data

from torchvision import transforms

from d2l import torch as d2l


d2l.use_svg_display()

  • torchvision:pytorch對于機器學(xué)習(xí)實現(xiàn)的一個庫
  • from torch.utils import data:方便讀取數(shù)據(jù)的一些小批量的函數(shù)
  • transforms:對數(shù)據(jù)進行操作的模塊
  • from d2l import torch as d2l:將一些函數(shù)實現(xiàn)好之后存在 d2l 中
  • d2l.use_svg_display():使用 svg 來顯示圖片,清晰度會更高一些



2、通過框架中的內(nèi)置函數(shù)將Fashion-MNIST數(shù)據(jù)集下載并讀取到內(nèi)存中


trans = transforms.ToTensor()

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)


len(mnist_train),len(mnist_test)

  • trans = transforms.ToTensor():將圖片轉(zhuǎn)換成pytorch中的tensor,通過ToTensor實例將圖像數(shù)據(jù)從PIL類型變換成32位浮點數(shù)格式,并除以255使得所有像素的數(shù)值均在 0 到 1 之間
  • train=True:代表下載的是訓(xùn)練集數(shù)據(jù)集
  • download=True:可以將數(shù)據(jù)集加載好然后放在指定的目錄下就可以不用download了
  • train=False:代表下載的是測試集數(shù)據(jù)集
  • 報錯:<urlopen error [WinError 10060] 由于連接方在一段時間后沒有正確答復(fù)或連接的主機沒有反應(yīng),連接嘗試失敗。>,科學(xué)上網(wǎng)之后可以解決這個問題

輸出:

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz

Using downloaded and verified file: ../data\FashionMNIST\raw\train-images-idx3-ubyte.gz

Extracting ../data\FashionMNIST\raw\train-images-idx3-ubyte.gz to ../data\FashionMNIST\raw


Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz

Using downloaded and verified file: ../data\FashionMNIST\raw\train-labels-idx1-ubyte.gz

Extracting ../data\FashionMNIST\raw\train-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw


Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to ../data\FashionMNIST\raw\t10k-images-idx3-ubyte.gz

100.0%

Extracting ../data\FashionMNIST\raw\t10k-images-idx3-ubyte.gz to ../data\FashionMNIST\raw


Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw\t10k-labels-idx1-ubyte.gz

119.3%

Extracting ../data\FashionMNIST\raw\t10k-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw



(60000, 10000)


mnist_train[0][0].shape

輸出:

torch.Size([1, 28, 28])

  • torch.Size([1, 28, 28]):因為它是一個黑白圖片,所以channel數(shù)是 1



3、定義兩個可視化數(shù)據(jù)集的函數(shù)


def get_fashion_mnist_labels(labels): ?#@save

? ? """返回Fashion-MNIST數(shù)據(jù)集的文本標(biāo)簽。"""

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

? ? """Plot a list of images."""

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



4、幾個樣本的圖像及其相應(yīng)的標(biāo)簽


X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))

show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));

  • next:拿到第一個小批量

輸出:

  • X.reshape(18, 28, 28):18張28 * 28的圖片
  • 2, 9:2 行 9 列
  • titles=get_fashion_mnist_labels(y):圖片的名稱顯示其對應(yīng)的標(biāo)號



5、讀取一小批量數(shù)據(jù),大小為batch_size


batch_size = 256


def get_dataloader_workers(): ?#@save

? ? """使用4個進程來讀取數(shù)據(jù)。"""

? ? return 4


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

  • 定義一個函數(shù) get_dataloader_workers() 每次返回 4 ,使用 4 個進程數(shù)來進行讀取,可以根據(jù) cpu 的大小來尋阿澤一個小一點的數(shù)或者大一點的數(shù)
  • shuffle=True:指定是否打亂順序
  • num_workers=get_dataloader_workers():分配多少個進程,這里給定的是 4
  • timer = d2l.Timer():timer 用來測試速度

輸出:

'4.00 sec'

  • 讀取一次數(shù)據(jù)的時間是 4 秒
  • 經(jīng)常會遇到一個性能問題:模型訓(xùn)練速度比較快,但是數(shù)據(jù)讀不過來,訓(xùn)練之前可以看一下數(shù)據(jù)讀取的速度,一般要比模型的訓(xùn)練速度要快,這是一個常見瓶頸



6、整合 load_data_fashion_mnist() 函數(shù)


def load_data_fashion_mnist(batch_size, resize=None): ?#@save

? ? """下載Fashion-MNIST數(shù)據(jù)集,然后將其加載到內(nèi)存中。"""

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

  • resize:是否將圖片變得更大,后續(xù)可能需要更大的圖片





softmax回歸的從零開始實現(xiàn)


1、導(dǎo)包


import torch

from IPython import display

from d2l import torch as d2l



batch_size = 256

train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

  • batch_size = 256:每次隨機讀取256張圖片
  • d2l.load_data_fashion_mnist(batch_size):調(diào)用存儲在 d2l 中的讀取數(shù)據(jù)集的函數(shù)(上面已經(jīng)實現(xiàn)了)
  • train_iter, test_iter:返回訓(xùn)練集和測試集的迭代器



2、展平每個圖像,將他們視為長度為 784 的向量,因為數(shù)據(jù)集有 10 個類別,所以網(wǎng)絡(luò)的輸出維度是 10


num_inputs = 784

num_outputs = 10


W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)

b = torch.zeros(num_outputs, requires_grad=True)

  • 每張圖片都是 28 *28,通道數(shù)為 1.是一個三維的輸入,但是對于 softmax 回歸來講,它的輸入需要是一個向量,所以需要將圖片拉長成為一個向量
  • 這個“拉長”的操作會損失很多的空間信息,這里留給卷積神經(jīng)網(wǎng)絡(luò)來提取特征信息
  • W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True):定義權(quán)重 W,將他初始為一個高斯隨機分布的值,均值為 0,方差為 0.01.它的形狀是行數(shù)等于輸入的個數(shù),列數(shù)等于輸出的個數(shù),因為要計算梯度,所以requires_grad=True
  • b = torch.zeros(num_outputs, requires_grad=True):定義偏移量 b:它的長度等于輸出的個數(shù),因為要計算梯度,所以requires_grad=True



3、回顧:給定一個矩陣 X ,對所有元素求和


X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])

X.sum(0, keepdim=True), X.sum(1, keepdim=True)

  • 0:將 shape 中的第 0 個元素變成 1,這就變成了一個行向量
  • 1:將 shape 中的第 1 個元素變成 1,這就變成了一個列向量

輸出:

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

tensor([[ 6.],[15.]]))



4、實現(xiàn) softmax

def softmax(X):

? ? X_exp = torch.exp(X)

? ? partition = X_exp.sum(1, keepdim=True)

? ? return X_exp / partition ?# 這里應(yīng)用了廣播機制

  • torch.exp(X):將 X 的每一個元素做指數(shù)運算
  • X_exp.sum(1, keepdim=True):按照 shape 中的第一個元素求和,即按照每一行來進行求和



5、將每一個元素變成一個非負(fù)數(shù)。根據(jù)概率原理,每行的總和為 1


X = torch.normal(0, 1, (2, 5))

X_prob = softmax(X)

X_prob, X_prob.sum(1)

  • X = torch.normal(0, 1, (2, 5)):創(chuàng)建一個均值為 0,方差為 1 的2行5列的矩陣 X

輸出:

(tensor([[0.3740, 0.1609, 0.1182, 0.0572, 0.2897],

[0.2156, 0.2721, 0.1700, 0.3240, 0.0184]]),

tensor([1., 1.]))



6、實現(xiàn) softmax 回歸模型


def net(X):

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



7、實現(xiàn)交叉熵?fù)p失


補充:創(chuàng)建一個數(shù)據(jù) y_hat,其中包含 2 個樣本在 3 個類別的預(yù)測概率,使用 y 作為 y_hat 的索引


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

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

y_hat[[0, 1], y]

  • y_hat[[0, 1], y]給定一個預(yù)測值,然后拿出給定標(biāo)號的真實類別的預(yù)測值是多少。對應(yīng)[0][0],[1][2]

輸出:

tensor([0.1000, 0.5000])



8、實現(xiàn)交叉熵?fù)p失函數(shù)


def cross_entropy(y_hat, y):

? ? return - torch.log(y_hat[range(len(y_hat)), y])


cross_entropy(y_hat, y)

輸出:

tensor([2.3026, 0.6931])



9、將預(yù)測類別和真實 y 元素進行比較


def accuracy(y_hat, y): ?#@save

? ? """計算預(yù)測正確的數(shù)量。"""

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

? ? return float(cmp.type(y.dtype).sum())


accuracy(y_hat, y) / len(y)

輸出:

0.5



10、評估在任意模型 net 的準(zhǔn)確率


def evaluate_accuracy(net, data_iter): ?#@save

? ? """計算在指定數(shù)據(jù)集上模型的精度。"""

? ? if isinstance(net, torch.nn.Module):

? ? ? ? net.eval() ?# 將模型設(shè)置為評估模式

? ? metric = Accumulator(2) ?# 正確預(yù)測數(shù)、預(yù)測總數(shù)

? ? for X, y in data_iter:

? ? ? ? metric.add(accuracy(net(X), y), y.numel())

? ? return metric[0] / metric[1]



11、Accumulator實例中創(chuàng)建了 2 個變量,用于分別儲存正確預(yù)測的數(shù)量和預(yù)測的總數(shù)量


class Accumulator: ?#@save

? ? """在`n`個變量上累加。"""

? ? def __init__(self, n):

? ? ? ? self.data = [0.0] * n


? ? def 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]


evaluate_accuracy(net, test_iter)

輸出:

0.1274



12、softmax回歸的訓(xùn)練





















































09 Softmax 回歸 + 損失函數(shù) + 圖片分類數(shù)據(jù)集【動手學(xué)深度學(xué)習(xí)v2的評論 (共 條)

分享到微博請遵守國家法律
海南省| 健康| 襄汾县| 柳江县| 江安县| 潮州市| 信宜市| 株洲市| 县级市| 布尔津县| 甘德县| 万山特区| 汶川县| 舒城县| 湘潭县| 北安市| 罗源县| 青州市| 神农架林区| 上饶县| 上犹县| 东平县| 黎城县| 峨眉山市| 永嘉县| 常山县| 宁化县| 江源县| 昭通市| 六安市| 朝阳县| 松溪县| 大同市| 电白县| 广州市| 上蔡县| 清水县| 正镶白旗| 阳朔县| 星子县| 任丘市|