features 是1000*2的矩阵,len()是取其第一维度的大小
也可features.shape[0]
这里的batch_indices作为索引也可以不用变为Tensor
yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行!
yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。
这里的batch_indices必须是tensor类型吗,list类型可以吗
这里还没加,等后面的代码里会有.sum()所以最终是return的向量的所有元素加起来
为什么是一样的效果呀,一个是除在预测值上,一个是除在前面的系数上
这一步相当于把w,b更新了,通过学习率和梯度向理想值靠近了一点,
反正是线性模型,参数wb除以batchsize和整个loss除以batchsize效果一样
因为你X是一个批量乘参数个数的矩阵,得到的y_hat是1乘批量数的矩阵
backward()只会对计算图里面
requires_grad=True的非标量进行梯度计算。x是输入的数据,都是标量,所以不会进行梯度极端
print(f'epoch{epoch + 1},loss{float(train_l.mean()):f}')
TensorDataset:把输入的两类数据进行一 一对应;DataLoader:重新排序,是不是要打乱顺序啊什么的
给元组解包,(features, labels)
一个星号*,表示对list解开入参
*号在python 语言中调用函数时参数前使用表示解包
is_train来区分是不是训练集,如果是训练集需要打乱
单通道,28*28的图片
试验了mnist_train[0到50][1]是int,输出是0-9的范围。
这里的example由img和target组成,提取的是img的形状
这里使用两个[0][0]原因是第一层是一个tuple,里面有一个tensor组成的图片
mnist_train[i]表示第i个例子,mnist_train[i][0]表示第i个例子的图片,mnist_train[i][1]表示第i个例子的label
[0][0]表示第一个样本的图片信息,[0][1]表示该样本对应的标签值
可以把d2l的库换成import matplotlib.pyplot as plt
然后show_images函数里面改为_, axes = plt.subplots(num_rows, num_cols, figsize=figsize)
return上面加一句plt.show()
pycharm不显示图片的自己在代码结尾加一句d2l.plt.show() pycharm不显示图片的自己在代码结尾加一句d2l.plt.show()
这里拿到的图片 转换成tensor的时候 每个值表示对于像素综合阶段得到的一个可以用于计算的值
W的形状必须是(num_inputs, num_outputs),因为这样才能保证W和x的矩阵乘法得到一个长度为num_outputs的向量
每个输出都需要一个偏移
广播机制,矩阵中的各个元素/对应行元素之和
零是一手压扁变行向量,1是两手鼓掌拍扁了变列向量,没有keepdim默认生成行向量
定义模型
python
def net(X):
return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)
对X进行reshape时总元素个数是确定的,指定了一个维度,另一个维度就可以自动计算出来
定义交叉熵损失函数⭐⭐数组操作一次性查询第几个样本 属于第几类的概率
python
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] #第几个样本 属于第几类
第三行是索引,【0,1】是行索引,y是列索引 然后配对 最后取y_hat[0,0] y_hat[1,2]
第三行代码:把这两个样本属于真实标签即0,2的预测概率拿出来
【第几个样本,第几个特征】
有了y,我们知道在第一个样本中,第一类是正确的预测;而
在第二个样本中,第三类是正确的预测。
然后使用y作为y_hat中概率的索引,我们选择第一个样本中第一个
类的概率和第二个样本中第三个类的概率。
python
tensor([0.1000, 0.5000])
实现交叉熵损失函数
现在我们只需一行代码就可以实现交叉熵损失函数。
分到其他类的概率是0 不对,这里不是,-log操作的是两个向量,或许已经把差别累加起来了
python
def cross_entropy(y_hat, y):
return - torch.log(y_hat[range(len(y_hat)), y])
cross_entropy(y_hat, y)
chapter3 分类精度
python
def accuracy(y_hat, y): #@save
"""计算预测正确的数量"""
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())
len(tensor) 是输出 tensor.shape[0]
axis = 1 沿着列方向行进,找出在每一行中的最大概率对应的下标
左边条件判断是否二维,右边判断列数
if后面第一个是判断张量是否大于1维,第二个是判断张量第二个维度是否大于1
python
import torch
# 创建一个形状为(2, 3)的张量
x = torch.Tensor([[1, 2, 3], [4, 5, 6],[1,1,1],[2,2,2]])
print(len(x.shape)) # 2 二维
print(x.shape[0]) # 4 4行
# 遍历张量中的元素
for i in range(x.shape[0]):
for j in range(x.shape[1]):
print(x[i, j])
len(x.shape),维数,一般为二维
x.shape[0]:行数
x.shape[1]: 列数
python
accuracy(y_hat, y) / len(y)
cmp 是一个布尔型张量,True 表示预测正确,而 False 表示预测错误。 当我们将布尔型张量转换为整型时,True 会被转换为 1,而 False 会被转换为 0
都是tensor类型,[False, True]->[0, 1]
python
def evaluate_accuracy(net, data_iter): #@save
"""计算在指定数据集上模型的精度"""
if isinstance(net, torch.nn.Module):
net.eval() # 将模型设置为评估模式
metric = Accumulator(2) # 正确预测数、预测总数
with torch.no_grad():
评估模式 只输入后得出结果用来评估模型真确率 不做反向传播
这里的评估模式 是后面在pytorch用的 现在定义 下一节才用
python
eval()
将Module设置为evaluation mode,相当于 self.train(False)