Pytorch模型中的parameter与buffer ---- https://zhuanlan.zhihu.com/p/89442276
Pytorch中Module,Parameter和Buffer的区别 ---- https://www.cnblogs.com/marsggbo/p/12075244.html
Pytorch 中的 Tensor , Variable & Parameter ---- https://www.jianshu.com/p/cb739922ce88
1) 像使用numpy的arrray一样,使用pytorch的tensor
import torch
# numpy array -> tensor
pt_tensor1 = torch.Tensor(numpy_array)
pt_tensor2 = torch.from_numpy(numpy_array)
# tensor -> numpy_array
my_array = pt_tensor1.numpy() # 如果是放在gpu上,要先.cpu()一下
# my_tensor是一个3x4的tensor
# 访问维度
my_tensor.dim() # 2
# 访问大小
my_tensor.size() # (3,4)
my_tensor.shape
# 访问元素个数
my_tensor.numel()
# 访问元素数据类型
my_tensor.type()
# 访问tensor内的某个元素或某些元素
my_tensor[0, 0] # 第0个元素,等价于my_tensor[0][0] my_tensor[1:3, 0:2] # 第2~3行、1~2列的元素,等价于my_tensor[1:3][0:2]
~~疑问:tensor和Variable的.data操作有何作用,和item()有何区别 # item是从0维tensor中拿出具体数值(int,float等) # .data取出的仍然是tensor
# 用到再往这里面加
# 矩阵乘法
torch.matmul(x, y)
Variable
是对Tensor
的封装,操作与tensor
基本一致,不同的是,每一个Variable
被构建的时候,都包含三个属性:
Variable
中所包含的tensor
tensor
的梯度 .grad
.grad_fn
Variable
这个数据结构,是为了引入计算图(自动求导)
,方便构建神经网络。下面用例子说明:# 1. 对标量自动求导
from torch.autograd import Variable
a = torch.randn(10, 5)
b = torch.randn(10, 5)
x = Variable(a, requires_grad=True)
y = Variable(b, requires_grad=True)
z = x + y z.backward()
x.grad # x的梯度 10x1 的全1tensor
z.grad_fn #
# 2. 对向量、矩阵进行求导
n = Variable(torch.zeros(1, 2), requires_grad=True)
m = Variable(torch.FloatTensor([2, 3]), requires_grad=True)
n[0, 0] = m[0, 0] ** 2
n[0, 1] = m[0, 1] ** 3
n.backward(torch.ones_like(n))
m.grad
# [4., 27.]
backward()
,我们可以对某个Variable
(譬如说y)进行一次自动求导,但如果我们再对这个Variable进行一次backward()
操作,会发现程序报错。这是因为PyTorch默认做完一次自动求导后,就把计算图丢弃了。我们可以通过设置retain_graph
来实现多次求导。# 多次自动求导
x = Variable(torch.Tensor([2]), requires_grad=True)
y = x * 2 + x ** 2 + 3
y.backward()
x.grad # 6
y.backward()
# 报错-->RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
z = x * 2 + x ** 2 + 3
z.backward(retain_graph=True) #参数设定,保留计算图
x.grad # 第一次求导的梯度
x.grad.data.zero_() # 梯度归0,否则梯度会叠加(求和)
z.backward() # 第二次求导
x.grad # 第二次求导的梯度
# 注意retain_graph参数的效用只有一次,也就是说在这块代码里,我如果想对z进行第三次求导,同样会报错,因为第二次求导的时候没有声明retain_graph=True
w
:w.data = w.data - lr * w.grad.data # lr 是学习率
Variable
默认是不需要求梯度的,那我还需要手动设置参数 requires_grad=True咯Variable
因为要多次反向传播,那么在backward
的时候还要手动注明参数w.backward(retain_graph=True)
咯nn.Parameter
类型的变量和optimizer机制
来解决了这个问题。Variable
的子类,本质上和后者一样,只不过parameter
默认是求梯度的,同时一个网络net中的parameter变量是可以通过 net.parameters()
来很方便地访问到的,只需将网络中所有需要训练更新的参数定义为Parameter
类型,再佐以optimizer
,就能够完成所有参数的更新了,具体如下:class Net(Module):
def __init__(self, a, b, ...):
super(net, self).__init__()
self... # parameters
self... # layers
def forward(self):
x = ...
x = ... # 数据流
return x
net = Net(a, b, ...)
net.train()
...
optimizer = torch.optim.SGD(net.parameters(), lr=1e-1)
# 然后在每一个batch中,调用optimizer.step()即可完成参数更新了(loss.backward()之后)
https://dreamhomes.top/posts/201906081516/ ---- PyTorch 常用函数解析
PyTorch0.4
中,.data
仍保留,但建议使用 .detach()
, 区别在于 .data
返回和 x
的相同数据 tensor, 但不会加入到x的计算历史里,且require s_grad = False
, 这样有些时候是不安全的, 因为 x.data
不能被 autograd
追踪求微分 。 .detach()
返回相同数据的 tensor ,且 requires_grad=False
,但能通过 in-place
操作报告给 autograd
在进行反向传播的时候.
https://www.cnblogs.com/dogecheng/p/11938009.html ---- PyTorch笔记之 scatter() 函数
https://blog.csdn.net/u014386899/article/details/108420955 ---- pytorch 中Tensor.new()的使用
创建一个新的Tensor
,该Tensor
的type
和device
都和原有Tensor
一致,且无内容
。
pip install tensorboard
下载 tensorboard
库from torch.utils.tensorboard import SummaryWriter
导入 SummaryWriter
类# 1. 创建写入数据的对象
# log_dir 决定生成的文件存放的位置
tb_writer = SummaryWriter(log_dir='./runs')
# 2. 绘制模型图
# model:模型对象
# input_to_model:制造一个可以传入model的tensor
tb_writer.add_graph(model, input_to_model)
# 3. 保存数据
# tag: 数据名称
# scalar_value: 数据的值
# global_step: 当前的阶段数
tb_writer.add_scalar(tag, scalar_value, global_step)
# main_tag: 一级数据名称
# tag_scalar_dict: 传入一个dict对象,key是二级数据名称,value是对应的值(**将绘制在一个图中**)
# global_step: 当前的阶段数
tb_writer.add_scalars(main_tag, tag_scalar_dict, global_step)
# 将数据写入到文件中
tb_writer.flush()
# 关闭tensorboard对象
tb_writer.close()