MCPcopy Index your code
hub / github.com/pytorch/pytorch / GetBackwardPass

Method GetBackwardPass

caffe2/python/core.py:1046–1104  ·  view source on GitHub ↗

Gets the backward pass that computes the derivatives of given blobs. Inputs: ys: a list or a dictionary specifying what blobs we want to compute derivatives of. If the input is a list, we will automatically generate their gradients with all-one values;

(self, ys)

Source from the content-addressed store, hash-verified

1044 return new_input_to_grad, gradient_ops
1045
1046 def GetBackwardPass(self, ys):
1047 """Gets the backward pass that computes the derivatives of given blobs.
1048
1049 Inputs:
1050 ys: a list or a dictionary specifying what blobs we want to compute
1051 derivatives of. If the input is a list, we will automatically
1052 generate their gradients with all-one values; if the input is a
1053 dictionary, for any dictionary entries that are not None, we will
1054 take the corresponding blobs as their gradients; for all those
1055 that are None, we will auto-fill them with 1.
1056 """
1057 if isinstance(ys, list):
1058 ys = dict((y, None) for y in ys)
1059 elif not isinstance(ys, dict):
1060 raise TypeError("ys should either be a list or a dict.")
1061
1062 # Set the gradient frontier with the initialized external
1063 # gradients.
1064 for y in ys.keys():
1065 self.gradient_frontier[y] = self.frontier[y]
1066 self.input_usages[str(y)][self.frontier[str(y)]].append(
1067 len(self.ssa))
1068
1069 all_input_to_grad, all_gradient_ops = self._GetInitGradients(ys)
1070
1071 # (2) Now, after having the virtual play above, we now play the ops
1072 # backwards, creating the gradients along the path. Note that although
1073 # we are playing it backwards, we cannot refer to variables that are
1074 # at a version older than current_versions because it is already been
1075 # overwritten.
1076 for forward_op_idx in reversed(range(len(self.ssa))):
1077 input_to_grad, gradient_ops = self._GenerateGradientsForForwardOp(
1078 forward_op_idx, all_input_to_grad)
1079 all_input_to_grad.update(input_to_grad)
1080 all_gradient_ops += gradient_ops
1081
1082 # If there are multiple use blobs, do gradient accumulation.
1083 additional_sum_ops, grad_map = self.DoGradientAccumulation(
1084 forward_op_idx)
1085 # This line is so that if in an accumulation some of the operators
1086 # have not produced gradients, they still do not overwrite the
1087 # general all_input_to_grad map.
1088 all_input_to_grad.update(grad_map)
1089 all_gradient_ops += additional_sum_ops
1090
1091 # (3) Post-processing.
1092 # After we have done computation for each op, we now have the gradient
1093 # operators ready. For the output map, we will convert everything to
1094 # BlobReferences for easier handling in python.
1095 all_input_to_grad_out = {}
1096 for key, val in all_input_to_grad.items():
1097 if val is not None:
1098 if isinstance(val, (bytes, str)):
1099 grad_out = BlobReference(val)
1100 else:
1101 grad_out = GradientSlice(BlobReference(val[0]),
1102 BlobReference(val[1]))
1103 all_input_to_grad_out[BlobReference(key)] = grad_out

Calls 11

_GetInitGradientsMethod · 0.95
isinstanceFunction · 0.85
reversedFunction · 0.85
BlobReferenceClass · 0.85
rangeFunction · 0.50
keysMethod · 0.45
appendMethod · 0.45
updateMethod · 0.45
itemsMethod · 0.45