动手深度学习3月28日

宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述动手深度学习3月28日相关的知识,希望能为你提供帮助。


如果想看jupyter note效果的请点击??github地址??
图像分类数据集使用Fashion-MNIST

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

过框架中的内置函数将 Fashion-MNIST 数据集下载并读取到内存中。
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)

(60000, 10000)

mnist_train[0][0].shape

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

两个可视化数据集的函数
def get_fashion_mnist_labels(labels):
"""返回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):
"""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

几个样本的图像及其相应的标签
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))

array([< matplotlib.axes._subplots.AxesSubplot object at 0x7f57414a4610> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738de2820> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738d8ec40> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738d440d0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738cf24f0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738d1d9d0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738cbee80> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738ccaf10> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738c30670> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738c5ca90> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738c07ee0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738bbd370> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738b6e790> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738b97bb0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738b46f10> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738afe460> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738aaa8b0> ,
< matplotlib.axes._subplots.AxesSubplot object at 0x7f5738ad7cd0> ],
dtype=object)


batch_size = 256

def get_dataloader_workers():
"""使用4个进程来读取的数据"""
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

ftimer.stop():.2f sec

1.19 sec

整合所有组件
现在我们定义了 ??load_data_fashion_mnist?? 函数,用于获取和读取Fashion-MNIST数据集。它返回训练集和验证集的数据迭代器。此外,它还接受一个可选参数,用来将图像大小调整为另一种形状。
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回归的从零开始实现
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)

将展平每个图像,将它们视为长度为784的向量.因为我们的数据集有10个类别,所以网络输出维度为 10。
num_inputs = 784 #28*28
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)

给定一个矩阵??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)

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

softmax 由三个步骤组成:
(1)对每个项求幂(使用???exp???);
(2)对每一行求和(小批量中每个样本是一行),得到每个样本的归一化常数;
(3)将每一行除以其归一化常数,确保结果的和为1。
在查看代码之前,让我们回顾一下这个表达式:

分母或归一化常数,有时也称为配分函数(其对数称为对数-配分函数)。该名称的起源来自 ??统计物理学??中一个模拟粒子群分布的方程。
def softmax(X):
X_exp = torch.exp(X)
partition = X_exp.sum(1, keepdim=True)
return X_exp / partition #这里应用了广播

我们将每个元素变成一个非负数。此外,依据概率的要求,每行总和为1。
X = torch.normal(0,1,(2,5))
X_prob = softmax(X)
X_prob, X_prob.sum(1)

(tensor([[0.2783, 0.1354, 0.0975, 0.4109, 0.0778],
[0.0889, 0.1355, 0.0823, 0.3405, 0.3528]]),
tensor([1.0000, 1.0000]))

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

【动手深度学习3月28日】创建一个数据??y_hat???,其中包含2个样本在3个类别的预测概率,使用??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]

tensor([0.1000, 0.5000])

实现交叉熵损失函数。
def cross_entropy(y_hat, y):
return

    推荐阅读