python中backward函数_pytorchbackward函数
import torch
a=torch.linspace(-100,100,10,requires_grad=True)
s=torch.sigmoid(a)
lu(a)
c.backward()
# 出错信息: grad can be implicitly created only for scalar outputs (只有当输出为标量时,梯度才能被隐式的创建)
对于输出时标量的情况:
import torch
a=torch.linspace(-100,100,10,requires_grad=True)
lu(a).sum()
c.backward() # 根据链式法则⾃动计算叶⼦结点的梯度,requires_grad=true 的变量
c # tensor([ 0.0000, ... , 100.0000], grad_fn=)
# SumBackward0 是求和运算的反向传播算法
<_functions # ((, 0),) # grad_fn 中有next_functions 连接
# pytorch 创建动态计算图
显式创建梯度:
import torch
a=torch.linspace(-100,100,10,requires_grad=True)
s=torch.sigmoid(a)
lu(a)
c.backward(torch.autogra
d.s(10),requires_grad=True))
backward :
// loss.backward() 和 torch.autograd.backward(loss) 相同
torch.autograd.backward(
tensors, #⽤于计算梯度的tensor
grad_tensors=None, #显式定义梯度
retain_graph=None, # 在backward之后,pytorch会把计算图销毁,要重复调⽤backward 就需要设置为True
create_graph=False)
# 当⼀个标量调⽤backward 的时候,grad_tensors=torch.Tensor([1])
当variable的requires_grad=True时,将存储相应的 gradient functions; (当进⾏模型预测,不需要梯度信息时,使⽤ _grad() context-manager disable 梯度计算,requires_grad=False )
所有的operations都是定义在Autograd.Function 类中,这个类主要有两个⽅法:forward 和backward ,backward 函数实现梯度的反向传播。 每次对tensor的操作会创建⼀个新的function object ⽤来计算和记录发⽣了什么。 记录的历史是存成 function的DAG,通过edges 来确定数据依赖 (output 依赖input 数据)。当backward 函数被调⽤时,将按照拓扑序遍历这个DAG 图调⽤function 的backward 函数,并且把梯度传给下⼀个function。
def backward (incoming_gradients):
ad = incoming_gradients
for inp in self.inputs:
ad_fn is not None:
new_incoming_gradients = //
incoming_gradient * ad_fn(self.Tensor, inp)
else:
pass
通过继承torch.autograd.Function⾃⼰定义Function 函数:
static forward(ctx, *args) # ctx context ⽤来存储反向传播需要的信息
static backward(ctx, *args)
class MMFunction(torch.autograd.Function):
@staticmethod
def forward(ctx,input,weight):
ctx.save_for_backward(input,weight) # ctx contex ⽤来存储⽤于反向计算的信息;
(weight.t())
return output
@staticmethod
def backward(ctx,grad_output):
input,weight=ctx.saved_variables
ds_input_grad[0]:
grad_input = (weight)
ds_input_grad[1]:
grad_weight = (input)
return grad_input, grad_weight
MMF=MMFunction.apply
# 直接调⽤MMFunction
input=torch.randn([3,2], requires_grad=True)
weight=torch.randn([3,2],requires_grad=True)
f=MMF(input,weight)
f #tensor([[-1.0838, -1.2282, 0.3823],
[-1.7367, -1.6129, -0.6131],
[ 1.5180, 1.7324, -0.5771]], grad_fn=) # grad_fn 为⾃定义的Function的backward⽅法
# 将MMFunction包在nn.Module
class Module):
def __init__(self, W, H):
super(MMul, self).__init__()
self.s(W, H)) # parameter 是⼀种特殊的Variable, 默认需要梯度,automatically registered as module's parameter
def forward(self, input):
return MMF(input,self.weight)
input=torch.randn([3,2], requires_grad=True)
m=MMul(3,2)
m(input) # tensor([[ 1.1420, 1.1420, 1.1420],
[-1.3408, -1.3408, -1.3408],
[ 1.8580, 1.8580, 1.8580]], grad_fn=)
PyObject *THPFunction_apply(PyObject *cls, PyObject *inputs)
{
...
THPObjectPtr backward_cls(PyObject_GetAttrString(cls, "_backward_cls"));
if (!backward_cls) return nullptr;
THPObjectPtr ctx_obj(PyObject_CallFunctionObjArgs(backward_cls, nullptr));
if (!ctx_obj) return nullptr;
THPFunction* ctx = (THPFunction*)();
auto cdata = std::shared_ptr(new PyNode(std::move(ctx_obj)), deleteNode);
ctx->cdata = cdata; // ad_fn()
// Prepare inputs and allocate context (grad fn)
auto info_pair = unpack_input(inputs);
UnpackedInput& unpacked_input = info_pair.first;
InputFlags& input_info = info_pair.second;
// Record input nodes if tracing
auto* node = _trace_pre_record(cls, inputs, unpacked_input.input_vars);
// Initialize backward function (and ctx)
bool is_executable = input_info.is_executable;
cdata->set_next_edges(std::move(_edges));
ctx->needs_input_grad = ds_lease();
ctx->is_variable_input = std::move(input_info.is_variable_input);
.....
// Call forward 调⽤forward 函数
THPObjectPtr tensor_outputs;
{
AutoGradMode grad_mode(false);
THPObjectPtr forward_fn(PyObject_GetAttrString(cls, "forward"));
if (!forward_fn) return nullptr;
tensor_outputs = PyObject_CallObject(forward_fn, ctx_input_tuple);
if (!tensor_outputs) return nullptr;
}
return process_outputs(cls, cdata, ctx, unpacked_input, inputs, std::move(tensor_outputs),
is_executable, node);
}
// CppNode is the Node in the autograd graph that represents the user defined
// backward function for Function. Calls to CppNode::apply are forward to
// T::backward().
template
struct CppNode : public Node {
variable_list apply(variable_list&& inputs) override;
AutogradContext ctx_;
std::vector is_variable_input_;
std::vector input_info_;
std::vector output_info_;
void release_variables() override;
void set_ctx_grad_fn(const std::shared_ptr &node);
void save_variables_to_ctx();
};
struct PyNode : public Node {
PyNode(THPObjectPtr obj) : lease()) {}
linspace函数python/tutorials/beginner/examples_autograd/two_layer_net_custom_function.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。