最近,看了一些《一起学深度学习的视频》,主要学习了基础部分(其实还没有涉及神经网络和深度学习哈哈),了解了一些torch的基本语法,并仿照其中敲了一些代码。
# # 1数据操作入门 创建数组/数组塑性
# import torch
# x=torch.arange(12)
# print('创建的张量为',x) ##创建一个张量 包含12个元素
# X=x.shape
# print('创建张量的形状',X)
# t=x.numel()
# print("元素的个数",t)
#
# x1=x.reshape(3,4)
# print('\n塑形张量为:',x1)
# X1=x1.shape
# print('塑性张量的形状',X1)
# t1=x1.numel()
# print("元素的个数",t1)
# # 2零数组和1数组
# import torch
# X=torch.zeros((2,3,4))
# print(X)
# X1=torch.ones((2,3,4))
# print(X1)
# X2=torch.randn(3,4) ##其中的每个元素都从均值为0、标准差为1的标准⾼斯分布(正态分布)中随机采样
# print(X2)
# X3=torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]]) ##赋值 输入特定的列表
# print(X3)
# # 3运算符号--按元素计算
# import torch
# x=torch.tensor([1.0,2,4,8])
# y=torch.tensor([2,2,2,2])
# print(x+y)
# print(x-y)
# print(x*y)
# print(x/y)
# print(x**y)
# print(torch.exp(x)) ##幂运算
# # 4张量连结 按照轴0和轴1
# import torch
# X=torch.arange(12,dtype=torch.float32).reshape((3,4))
# print(X)
# Y=torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
# print(Y)
# Z=torch.cat((X,Y),dim=0) ##按照轴0进行连结
# Z1=torch.cat((X,Y),dim=1) ##按照轴1进行连结
# print(Z)
# print(Z1)
# # 5 逻辑判断--也是按照元素判断 求和
# import torch
# X=torch.arange(12,dtype=torch.float32).reshape((3,4))
# Y=torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
# print(X==Y)
# X0=X.sum()
# print(X0)
# # 6广播机制--自助匹配形状 矩阵a复制列 矩阵b复制行
# import torch
# a = torch.arange(3).reshape((3, 1))
# b = torch.arange(2).reshape((1, 2))
# print(a)
# print(b)
# c=a+b
# print(c)
# # 7 切片打印和修改
# import torch
# X=torch.arange(12,dtype=torch.float32).reshape((3,4))
# print(X[-1]) ##行
# print(X[1:3]) ##行
# X[1,2]=22
# X[:,1]=0 ##所有行的1号列
# print(X)
# # 8节省内存--原地操作 ##直接赋值会占用新的空间 ##通过切片或者+=均可以减少内存
# import torch
# X=torch.arange(12,dtype=torch.float32).reshape((3,4))
# Y=torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
#
# before = id(Y)
# Y = Y + X
# print(id(Y) == before)
#
# Z = torch.zeros_like(Y)
# print(Z)
# print('id(Z):', id(Z))
# Z[:] = X + Y
# print('id(Z):', id(Z))
# print(Z)
#
# before = id(Y)
# X += Y
# print(id(Y) == before)
# # 10 转化为numpy张量 numpy数组和torch张量之间的转化 张量为1的张量转化为标量
# import torch
# X=torch.arange(12,dtype=torch.float32).reshape((3,4))
# A=X.numpy()
# B=torch.tensor(A)
# print(A,'\n',type(A))
# print(B,'\n',type(B))
#
# a=torch.tensor([3.5])
# print(a,a.item(),float(a),int(a))
# 11 数据预处理csv文件
# import os
# os.makedirs(os.path.join('..', 'data'), exist_ok=True)
# data_file = os.path.join('..', 'data', 'house_tiny.csv')
# with open(data_file, 'w') as f:
# f.write('NumRooms,Alley,Price\n') # 列名
# f.write('NA,Pave,127500\n') # 每⾏表⽰⼀个数据样本
# f.write('2,NA,106000\n')
# f.write('4,NA,178100\n')
# f.write('NA,NA,140000\n')
#
# import pandas as pd
# data = pd.read_csv(data_file)
# print(data)
# # 12处理缺失值 插值法(替代和弥补缺失值)和删除法
# # 12-1空缺为数值
# import os
# import pandas as pd
# data_file = os.path.join('..', 'data', 'house_tiny.csv')
# data = pd.read_csv(data_file)
# # print(data)
# inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
# inputs = inputs.fillna(inputs.mean())
# # print(inputs)
# # 12-2丢失为离散值或类别值
# inputs = pd.get_dummies(inputs, dummy_na=True)
# # print(inputs)
# # 12-3 转化为张量格式
# import torch
# X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
# print(X)
# print(y)
# 13线性代数 向量是标量的推广,矩阵是向量的推广
# 13.1标量 由只有一个元素的张量表示
# import torch
# x = torch.tensor(3.0)
# y = torch.tensor(2.0)
# a= x + y
# b=x * y
# c=x / y
# d=x**y
# print(a,b,c,d)
# 13.2 向量 单行
# import torch
# x=torch.arange(4)
# print(x)
# a=x[3]
# print(a) #索引
# b=len(x)
# print(b) #长度
# c=x.shape
# print(c) #形状
# 13.3 矩阵 多行 转置
# import torch
# A = torch.arange(20).reshape(5, 4) #塑性
# print(A)
# x=A[1,3] #索引
# print(x)
# B=A.T #转置
# print(B)
# import torch #对称矩阵
# B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]]) #对称矩阵
# print(B)
# B==B.T
# print(B==B.T)
# import torch #三维
# X = torch.arange(24).reshape(2, 3, 4)
# print(X)
# 14张量算法的基本性质
# import torch #矩阵之间 哈达玛积
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# B = A.clone() # 通过分配新内存,将A的⼀个副本分配给B
# print(A)
# # print(A+B) #加法
# print(A*B) #hadamard积
# import torch #矩阵和标量
# a = 2
# X = torch.arange(24).reshape(2, 3, 4)
# print(a + X)
# print((a * X).shape)
# 15.1降维求和 向量
# import torch
# X = torch.arange(4, dtype=torch.float32)
# print(X)
# print(X.sum())
# 15.2降维求和 矩阵
# import torch
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# print(A.shape)
# print(A.sum())
# B = torch.arange(20*2, dtype=torch.float32).reshape(2, 5, 4)
# print(B)
# print(B.shape)
# print(B.sum()) #直接求和
# B_sum_axis0=B.sum(axis=0) #按照0维
# print(B_sum_axis0)
# print(B_sum_axis0.shape)
# B_sum_axis1=B.sum(axis=1) #按照1维
# print(B_sum_axis1)
# print(B_sum_axis1.shape)
# B_sum_axis01=B.sum(axis=[0,1]) #按照0维和1维同时
# print(B_sum_axis01)
# print(B_sum_axis01.shape)
# 16均值
# import torch
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# a=A.mean()
# b=A.sum()/A.numel()
# print(a)
# print(b)
# 17非降维求和
# import torch
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# print(A)
# sum_A1 = A.sum(axis=1, keepdims=True) #某一维上的求和
# print(sum_A1)
# a=A/sum_A1 #通过广播机制将A除以sum_A1
# print(a)
# b=A.cumsum(axis=0) #累加求和
# print(b)
# 18点积
# import torch
# x= torch.arange(4, dtype=torch.float32)
# y = torch.ones(4, dtype = torch.float32)
# print(x, y, torch.dot(x, y)) #按照元素乘积
# 19矩阵 向量积 mv matrix-vector
# import torch
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# x= torch.arange(4, dtype=torch.float32)
# print(A)
# print(x)
# print(A.shape, x.shape, torch.mv(A, x)) #A乘以x的转置等于结果的转置
# 20矩阵矩阵积 mm matrix-matrix
# import torch
# A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# B = torch.ones(4, 3)
# C = torch.mm(A, B)
# print(A)
# print(B)
# print(C)
# 21范数 向量或者矩阵的长度
# import torch
# u = torch.tensor([3.0, -4.0])
# t=torch.norm(u) #平方和开根号L2
# print(t)
# y=torch.abs(u).sum() #绝对值求和L1
# print(y)
# z=torch.norm(torch.ones((4, 9)))
# print(z) #矩阵元素的平方和开根号
# 22自动微分
# import torch
# x = torch.arange(4.0)
# print(x)
# x.requires_grad_(True) #计算y关于x的梯度之前,我们需要⼀个地⽅来存储梯度 # 等价于x=torch.arange(4.0,requires_grad=True)
# x.grad
# y = 2 * torch.dot(x, x)
# print('y=',y)
# y.backward() #我们通过调⽤反向传播函数来⾃动计算y关于x每个分量的梯度,并打印这些梯度
# t=x.grad
# print('梯度=',t)
# # print(t == 4 * x) #判断一下
#
# x.grad.zero_() # 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
# y = x.sum()
# y.backward()
# z=x.grad
# print(z)
# 23 ⾮标量变量的反向传播
# 对⾮标量调⽤backward需要传⼊⼀个gradient参数,该参数指定微分函数关于self的梯度。
# 在我们的例⼦中,我们只想求偏导数的和,所以传递⼀个1的梯度是合适的
# import torch
# x = torch.arange(4.0)
# x.requires_grad_(True) #计算y关于x的梯度之前,我们需要⼀个地⽅来存储梯度 # 等价于x=torch.arange(4.0,requires_grad=True)
# # x.grad.zero_() #同于清空存储
# y = x * x
# print(y)
# y.sum().backward() # 等价于y.backward(torch.ones(len(x)))
# q=x.grad
# print(q)
# 24分离计算 变量分离求取偏导
# import torch
# x = torch.arange(4.0)
# x.requires_grad_(True)
# # x.grad.zero_()
# y = x * x
# u = y.detach()
# print('u=',u)
# z = u * x
# print("z=",z)
#
# z.sum().backward()
# print(z)
# # x.grad == u
#
# x.grad.zero_()
# y.sum().backward()
# print(y)
# 25 Python控制流的梯度计算
# import torch
#
# def f(a):
# b = a * 2
# while b.norm() < 1000:
# b = b * 2
# if b.sum() > 0:
# c = b
# else:
# c = 100 * b
# return c
#
# a = torch.randn(size=(), requires_grad=True)
# a.backward()
# # print(a)
# d = f(a)
# d.backward()
# print(a)
# print(d)
# print(a.grad == d / a)
# 26 线性神经网络
# import random
# import torch
# from d2l import torch as d2l
#
# #生成数据集
# def synthetic_data(w, b, num_examples): #@save
# """⽣成y=Xw+b+噪声"""
# X = torch.normal(0, 1, (num_examples, len(w))) #正态分布数组 【均值 标准差 形状】自变量数组
# y = torch.matmul(X, w) + b #线性 张量相乘 再加上偏差
# y += torch.normal(0, 0.01, y.shape) # 添加噪声 噪声为正态型
# return X, y.reshape((-1, 1)) #(-1,1)转换成一列 ;(1,-1)转换成一行
#
# true_w = torch.tensor([2, -3.4])
# true_b = 4.2
# features, labels = synthetic_data(true_w, true_b, 1000) #调用函数
#
# print('features:', features[0],'\nlabel:', labels[0]) #打印第一个结果
#
# # d2l.set_figsize()
# # d2l.plt.scatter(features[:, (1)].detach().numpy(), labels.detach().numpy(), 1) #第一列
# # # d2l.plt.show() #显示图片显示曲线
#
# #读取数据集
# def data_iter(batch_size, features, labels):
# num_examples = len(features) #确定生成的数据集的总数量
# indices = list(range(num_examples)) #生成索引列表 [0 1 2 ...]
# # 这些样本是随机读取的,没有特定的顺序
# random.shuffle(indices) #打乱索引列表
# for i in range(0, num_examples, batch_size): #取被打乱的索引表的前n个 n为取样数据量
# batch_indices = torch.tensor(
# indices[i: min(i + batch_size, num_examples)]) #从i开始
# yield features[batch_indices], labels[batch_indices]
#
# batch_size = 10 #取样数据量
# for X, y in data_iter(batch_size, features, labels):
# print(X, '\n', y)
# break
#
# #初始化模型参数
# w = torch.normal(0, 0.01, size=(2,1), requires_grad=True) #正态分布随机生成
# b = torch.zeros(1, requires_grad=True) #生成0集
#
# #定义模型
# def linreg(X, w, b): #@save
# """线性回归模型"""
# return torch.matmul(X, w) + b # 线性方程表达式
#
# #定义损失函数
# def squared_loss(y_hat, y): #@save #预测值和真实值
# """均⽅损失"""
# return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
#
# #定义优化算法
# def sgd(params, lr, batch_size): #@save
# """⼩批量随机梯度下降"""
# with torch.no_grad(): #使用with 确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等。
# for param in params:
# param -= lr * param.grad / batch_size
# param.grad.zero_() #清空梯度
#
# #训练
# lr = 0.03 #学习率
# num_epochs = 3 #扫描三遍
# net = linreg #线性 上述已定义
# loss = squared_loss #损失函数 上述已定义
#
# for epoch in range(num_epochs):
# for X, y in data_iter(batch_size, features, labels): #特征和标签
# l = loss(net(X, w, b), y) # X和y的⼩批量损失 #预测的y和真实的y做损失
# # 因为l形状是(batch_size,1),⽽不是⼀个标量。l中的所有元素被加到⼀起,
# # 并以此计算关于[w,b]的梯度
# l.sum().backward()
# sgd([w, b], lr, batch_size) # 使⽤参数的梯度更新参数
# with torch.no_grad():
# train_l = loss(net(features, w, b), labels)
# print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
#
# print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
# print(f'b的估计误差: {true_b - b}')
# 27 线性回归的简洁实现
# import numpy as np
# import torch
# from torch.utils import data #引入了处理数据的模块
# from d2l import torch as d2l
#
# #生成数据集
# true_w = torch.tensor([2, -3.4])
# true_b = 4.2
# features, labels = d2l.synthetic_data(true_w, true_b, 1000) #人工数据合成函数
#
# #读取数据集
# def load_array(data_arrays, batch_size, is_train=True): #@save
# """构造⼀个PyTorch数据迭代器"""
# dataset = data.TensorDataset(*data_arrays)
# return data.DataLoader(dataset, batch_size, shuffle=is_train)
#
# batch_size = 10
# data_iter = load_array((features, labels), batch_size)
# next(iter(data_iter)) #得到一个X一个Y
# # print(next(iter(data_iter)))
#
# #定义模型 使用框架的预定义好的层
# from torch import nn #nn是神经⽹络的缩写
# net = nn.Sequential(nn.Linear(2, 1)) #线性层 全连接层
#
# #初始化模型参数
# net[0].weight.data.normal_(0, 0.01) #使用正态分布替换掉data的值
# net[0].bias.data.fill_(0) #设置偏差为0
# # print(net[0])
#
# #定义损失函数 均方误差 也称平方范数
# loss = nn.MSELoss()
#
# #定义优化算法 实例化SGD
# trainer = torch.optim.SGD(net.parameters(), lr=0.03)
#
# #训练
# num_epochs = 3
# for epoch in range(num_epochs):
# for X, y in data_iter:
# l = loss(net(X) ,y)
# trainer.zero_grad() #清零
# l.backward()
# trainer.step() #更新
# l = loss(net(features), labels)
# print(f'epoch {epoch + 1}, loss {l:f}')
# w = net[0].weight.data
# print('w的估计误差:', true_w - w.reshape(true_w.shape))
# b = net[0].bias.data
# print('b的估计误差:', true_b - b)
# # 28正态分布与平方损失
# import math
# import numpy as np
# from d2l import torch as d2l
#
# def normal(x, mu, sigma):
# p = 1 / math.sqrt(2 * math.pi * sigma**2)
# return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)
# # 再次使⽤numpy进⾏可视化
# x = np.arange(-7, 7, 0.01)
# # 均值和标准差对
# params = [(0, 1), (0, 2), (3, 1)]
# d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params],
# xlabel='x',
# ylabel='p(x)',
# figsize=(4.5, 2.5),
# legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])
# d2l.plt.show()
# # 29 图像分类数据集
# import matplotlib.pyplot as plt
# import torch
# import torchvision
# from torch.utils import data
# from torchvision import transforms
# from d2l import torch as d2l
# d2l.use_svg_display()
#
# # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# # 并除以255使得所有像素的数值均在0到1之间
# 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)
#
# print(len(mnist_train), len(mnist_test))
#
# def get_fashion_mnist_labels(labels): #@save
# """返回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): #@save
# """绘制图像列表"""
# 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
#
# 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))
# # plt.show()
#
# #读取小批量
# batch_size = 256
# def get_dataloader_workers(): #@save
# """使⽤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
# print(f'{timer.stop():.2f} sec')
#
# 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()))
#
# train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
# for X, y in train_iter:
# print(X.shape, X.dtype, y.shape, y.dtype)
# break
#
# torch.Size([32, 1, 64, 64])
# torch.float32
# torch.Size([32])
# torch.int64
# 30 softmax回归的从零开始实现
# import torch
# from IPython import display
# from d2l import torch as d2l
#
# batch_size = 64
# train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
#
# #初始化模型参数
# 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)
#
# #定义softmax参数
# X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
# print(X.sum(0, keepdim=True), X.sum(1, keepdim=True))
#
# def softmax(X):
# X_exp = torch.exp(X)
# partition = X_exp.sum(1, keepdim=True)
# return X_exp / partition # 这⾥应⽤了⼴播机制
#
# X = torch.normal(0, 1, (2, 5))
# X_prob = softmax(X)
# print(X_prob, X_prob.sum(1))
#
# #定义模型
# def net(X):
# return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)
#
# #定义损失函数
# y = torch.tensor([0, 2])
# y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
# print(y_hat[[0, 1], y])
#
# def cross_entropy(y_hat, y):
# return - torch.log(y_hat[range(len(y_hat)), y])
#
# TT=cross_entropy(y_hat, y)
# print(TT)
#
# #分类精度
# 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())
#
# print(accuracy(y_hat, y) / len(y))
#
# 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]
#
# def evaluate_accuracy(net, data_iter): #@save
# """计算在指定数据集上模型的精度"""
# if isinstance(net, torch.nn.Module):
# net.eval() # 将模型设置为评估模式
# metric = Accumulator(2) # 正确预测数、预测总数
# with torch.no_grad():
# for X, y in data_iter:
# metric.add(accuracy(net(X), y), y.numel())
# return metric[0] / metric[1]
#
#
#
# # print(evaluate_accuracy(net, test_iter))
#
# #训练
# def train_epoch_ch3(net, train_iter, loss, updater): #@save
# """训练模型⼀个迭代周期(定义⻅第3章)"""
# # 将模型设置为训练模式
# if isinstance(net, torch.nn.Module):
# net.train()
# # 训练损失总和、训练准确度总和、样本数
# metric = Accumulator(3)
# for X, y in train_iter:
# # 计算梯度并更新参数
# y_hat = net(X)
# l = loss(y_hat, y)
# if isinstance(updater, torch.optim.Optimizer):
# # 使⽤PyTorch内置的优化器和损失函数
# updater.zero_grad()
# l.mean().backward()
# updater.step()
# else:
# # 使⽤定制的优化器和损失函数
# l.sum().backward()
# updater(X.shape[0])
# metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())
# # 返回训练损失和训练精度
# return metric[0] / metric[2], metric[1] / metric[2]
#
# class Animator: #@save
# """在动画中绘制数据"""
# def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,
# ylim=None, xscale='linear', yscale='linear',
# fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,
# figsize=(3.5, 2.5)):
# # 增量地绘制多条线
# if legend is None:
# legend = []
# d2l.use_svg_display()
# self.fig, self.axes = d2l.plt.subplots(nrows, ncols, figsize=figsize)
# if nrows * ncols == 1:
# self.axes = [self.axes, ]
# # 使⽤lambda函数捕获参数
# self.config_axes = lambda: d2l.set_axes(
# self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
# self.X, self.Y, self.fmts = None, None, fmts
#
# def add(self, x, y):
#
# # 向图表中添加多个数据点
# if not hasattr(y, "__len__"):
# y = [y]
# n = len(y)
# if not hasattr(x, "__len__"):
# x = [x] * n
# if not self.X:
# self.X = [[] for _ in range(n)]
# if not self.Y:
# self.Y = [[] for _ in range(n)]
# for i, (a, b) in enumerate(zip(x, y)):
# if a is not None and b is not None:
# self.X[i].append(a)
# self.Y[i].append(b)
# self.axes[0].cla()
# for x, y, fmt in zip(self.X, self.Y, self.fmts):
# self.axes[0].plot(x, y, fmt)
# self.config_axes()
# display.display(self.fig)
# display.clear_output(wait=True)
#
# def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): #@save
# """训练模型(定义⻅第3章)"""
# animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],
# legend=['train loss', 'train acc', 'test acc'])
# for epoch in range(num_epochs):
# train_metrics = train_epoch_ch3(net, train_iter, loss, updater)
# test_acc = evaluate_accuracy(net, test_iter)
# animator.add(epoch + 1, train_metrics + (test_acc,))
# train_loss, train_acc = train_metrics
# assert train_loss < 0.5, train_loss
# assert train_acc <= 1 and train_acc > 0.7, train_acc
# assert test_acc <= 1 and test_acc > 0.7, test_acc
#
# lr = 0.1
# def updater(batch_size):
# return d2l.sgd([W, b], lr, batch_size)
#
# num_epochs = 10
# train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)
#
# def predict_ch3(net, test_iter, n=6): #@save
# """预测标签(定义⻅第3章)"""
# for X, y in test_iter:
# break
# trues = d2l.get_fashion_mnist_labels(y)
# preds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1))
# titles = [true +'\n' + pred for true, pred in zip(trues, preds)]
# d2l.show_images(
# X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])
# predict_ch3(net, test_iter)
# d2l.plt.show()
#31简洁实现
# import torch
# from torch import nn
# from d2l import torch as d2l
# batch_size = 16
# train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
#
# # PyTorch不会隐式地调整输⼊的形状。因此,
# # 我们在线性层前定义了展平层(flatten),来调整⽹络输⼊的形状
# net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
# def init_weights(m):
# if type(m) == nn.Linear:
# nn.init.normal_(m.weight, std=0.01)
# net.apply(init_weights)
#
# loss = nn.CrossEntropyLoss(reduction='none')
#
# trainer = torch.optim.SGD(net.parameters(), lr=0.1)
# #
# num_epochs = 10
# d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
#
# def predict_ch3(net, test_iter, n=6): #@save
# """预测标签(定义⻅第3章)"""
# for X, y in test_iter:
# break
# trues = d2l.get_fashion_mnist_labels(y)
# preds = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1))
# titles = [true +'\n' + pred for true, pred in zip(trues, preds)]
# d2l.show_images(
# X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])
# predict_ch3(net, test_iter)
# d2l.plt.show()