detach()
:返回一个新的tensor,并且这个tensor是从当前的计算图中分离出来的。但是返回的tensor和原来的tensor是共享内存空间的。figsize
:Matplotlib库中的一个函数,用于设置图形的尺寸大小。
figsize(width, height)
:其中,width和height分别表示图像的宽度和高度,单位为英寸(inch)。requires_grad =True
:输出张量需要梯度。
%matplotlib inline
import torch
from d2l import torch as d2l
# 生成一个从-8.0到7.9的列表,以0.1为跳跃点
# 需要梯度
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
# 通过relu函数激活
y = torch.relu(x)
d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize=(5, 2.5))
torch.ones_like()
:返回一个与输入张量input形状相同的张量,所有元素都设置为1。retain_graph=True
:第一次计算完梯度后,计算图会被保留下来,再次计算梯度时,就可以重复使用这个计算图,从而避免重复构建计算图,提高计算效率。
y.backward(torch.ones_like(x), retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of relu', figsize=(5, 2.5))
sigmoid在隐藏层中已经较少使用, 它在大部分时候被更简单、更容易训练的ReLU所取代。
y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize=(5, 2.5))
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of sigmoid', figsize=(5, 2.5))
3.当输入为0时,sigmoid函数的导数达到最大值0.25; 而输入在任一方向上越远离0点时,导数越接近0。
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize=(5, 2.5))
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of tanh', figsize=(5, 2.5))
使用Fashion-MNIST图像分类数据集 。
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
torch.zeros()函数
:返回一个形状为为size,类型为torch.dtype,里面的每一个值都是0的tensor。torch.randn
:用来生成随机数字的tensor,这些随机数字满足标准正态(0~1)。
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 定义参数w1,w2,b1,b2
# w1,w2为满足标准正态分布的随机数字,b1,b2为0
W1 = nn.Parameter(torch.randn(
num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(
num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
自己实现ReLU激活函数。
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
使用reshape将每个二维图像转换为一个长度为num_inputs的向量。
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1) # 这里“@”代表矩阵乘法
return (H@W2 + b2)
reduction = none
:表示直接返回n分样本的loss。
loss = nn.CrossEntropyLoss(reduction='none')
直接调用d2l包的train_ch3函数,详细见之前的线性回归。
# 迭代轮数为10,学习率为0.1
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
d2l.predict_ch3(net, test_iter)
# 导入d2l包
import torch
from torch import nn
from d2l import torch as d2l
nn.Sequential()
:一个序列容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。把多个模块封装成一个模块。nn.Flatten()
:将连续的维度范围展平为张量。 经常在nn.Sequential()中出现,一般写在某个神经网络模型之后,用于对神经网络模型的输出进行处理,得到tensor类型的数据。nn.Linear()
:定义一个神经网络的线性层:
torch.nn.Linear(in_features, # 输入的神经元个数
out_features, # 输出神经元个数
bias=True # 是否包含偏置
)
torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
:tensor为一个n维torch.Tensor,mean为正态分布的平均值,std为正态分布的标准差。init_weights
:初始化网络的权重。它还将神经网络的权重设置为非零值,这对神经网络来说是有帮助的,因为神经网络往往会陷入局部最小值,所以给它们许多不同的起始值是个好主意。apply(fn)
:该方法会将fn递归的应用于模块的每一个子模块(.children()的结果)及其自身。
net = nn.Sequential(nn.Flatten(), # 展平为张量
# 定义784输入神经单元,256个输出神经单元的线性层
nn.Linear(784, 256),
# ReLU激活函数
nn.ReLU(),
# 定义256输入神经单元,10个输出神经单元的线性层
nn.Linear(256, 10))
# 初始化网络权重
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01) #初始化权重:标准差为0.01
# 每层都循环一下,最后对整个Sequential也进行操作,递归调用
net.apply(init_weights);
# 批量大小:256,学习率:10,迭代轮数:10
batch_size, lr, num_epochs = 256, 0.1, 10
# 交叉熵损失函数
loss = nn.CrossEntropyLoss(reduction='none')
# 内部优化器
trainer = torch.optim.SGD(net.parameters(), lr=lr)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)