10void bilinear_interpolate_gradient(
25 if (y < -1.0 || y >
height || x < -1.0 || x >
width) {
28 x_low = x_high = y_low = y_high = -1;
43 y_high = y_low =
height - 1;
49 if (x_low >=
width - 1) {
50 x_high = x_low =
width - 1;
58 T hy = 1. - ly, hx = 1. - lx;
67 w1 = hy * hx,
w2 = hy * lx,
w3 = ly * hx,
w4 = ly * lx;
73inline void add(
const T&
val,
T* address) {
78void ROIAlignBackwardFeature(
82 const T& spatial_scale,
86 const int pooled_height,
87 const int pooled_width,
88 const int sampling_ratio,
92 bool continuous_coordinate) {
93 DCHECK(rois_cols == 4 || rois_cols == 5);
97 int pw =
index % pooled_width;
98 int ph = (
index / pooled_width) % pooled_height;
102 const T* offset_bottom_rois = bottom_rois + n * rois_cols;
103 int roi_batch_ind = 0;
104 if (rois_cols == 5) {
105 roi_batch_ind = offset_bottom_rois[0];
106 offset_bottom_rois++;
110 T roi_offset = continuous_coordinate ?
T(0.5) : 0;
111 T roi_start_w = offset_bottom_rois[0] * spatial_scale - roi_offset;
112 T roi_start_h = offset_bottom_rois[1] * spatial_scale - roi_offset;
113 T roi_end_w = offset_bottom_rois[2] * spatial_scale - roi_offset;
114 T roi_end_h = offset_bottom_rois[3] * spatial_scale - roi_offset;
116 T roi_width = roi_end_w - roi_start_w;
117 T roi_height = roi_end_h - roi_start_h;
118 if (continuous_coordinate) {
120 roi_width >= 0 && roi_height >= 0,
121 "ROIs in ROIAlign do not have non-negative size!");
125 roi_height =
std::max(roi_height, (
T)1.);
127 T bin_size_h =
static_cast<T>(roi_height) /
static_cast<T>(pooled_height);
128 T bin_size_w =
static_cast<T>(roi_width) /
static_cast<T>(pooled_width);
130 T* offset_bottom_diff =
133 int top_offset = (n *
channels +
c) * pooled_height * pooled_width;
134 const T* offset_top_diff = top_diff + top_offset;
135 const T top_diff_this_bin = offset_top_diff[ph * pooled_width + pw];
138 int roi_bin_grid_h = (sampling_ratio > 0)
140 :
ceil(roi_height / pooled_height);
142 (sampling_ratio > 0) ? sampling_ratio :
ceil(roi_width / pooled_width);
145 const T count = roi_bin_grid_h * roi_bin_grid_w;
147 for (
int iy = 0; iy < roi_bin_grid_h; iy++) {
148 const T y = roi_start_h + ph * bin_size_h +
149 static_cast<T>(iy + .5f) * bin_size_h /
150 static_cast<T>(roi_bin_grid_h);
151 for (
int ix = 0; ix < roi_bin_grid_w; ix++) {
152 const T x = roi_start_w + pw * bin_size_w +
153 static_cast<T>(ix + .5f) * bin_size_w /
154 static_cast<T>(roi_bin_grid_w);
157 int x_low, x_high, y_low, y_high;
159 bilinear_interpolate_gradient(
174 T g1 = top_diff_this_bin *
w1 / count;
175 T g2 = top_diff_this_bin *
w2 / count;
176 T g3 = top_diff_this_bin *
w3 / count;
177 T g4 = top_diff_this_bin *
w4 / count;
179 if (x_low >= 0 && x_high >= 0 && y_low >= 0 && y_high >= 0) {
181 add(
static_cast<T>(g1), offset_bottom_diff + y_low *
width + x_low);
182 add(
static_cast<T>(g2), offset_bottom_diff + y_low *
width + x_high);
183 add(
static_cast<T>(g3), offset_bottom_diff + y_high *
width + x_low);
184 add(
static_cast<T>(g4), offset_bottom_diff + y_high *
width + x_high);
213 dX->numel(), 0.f,
dX->template mutable_data<float>(), &
context_);
215 if (
dY.numel() > 0) {
216 ROIAlignBackwardFeature<float>(
227 dX->template mutable_data<float>(),
242 .Input(0,
"X",
"See RoIPoolF.")
243 .Input(1,
"RoIs",
"See RoIPoolF.")
244 .Input(2,
"dY",
"Gradient of forward output 0 (Y)")
245 .Output(0,
"dX",
"Gradient of forward input 0 (X)");
251 vector<OperatorDef> GetGradientDefs()
override {
252 return SingleGradientDef(
255 vector<string>{I(0), I(1),
GO(0)},
256 vector<string>{GI(0)});
271 "_caffe2::RoIAlignGradient("
276 " float spatial_scale,"
279 " int sampling_ratio,"
GradientMakerBase(const OperatorDef &def, const vector< GradientWrapper > &g_output)
bool RunOnDevice() override
#define DCHECK(condition)
Tensor add(const Tensor &self, Scalar other, Scalar alpha)
Tensor ceil(const Tensor &self)
C10_EXPORT void Set< float, CPUContext >(const std::int64_t N, const float alpha, float *Y, CPUContext *)
Copyright (c) 2016-present, Facebook, Inc.
REGISTER_CPU_OPERATOR(ATen, ATenOp< CPUContext >)
CAFFE_ENFORCE_EQ(in.size(), 1, "New shape must not be specified by the input blob and the " "argument `shape` at the same time.")
and label is applied to the tensor elementwise If y
SparseLengths8BitsRowwiseOp< CPUContext, 0, 1 >::LENGTHS uint8 tensor obtained with Vector with the same sum of elements as the first dimension of DATA Input(3, "scale_bias", "Matrix of floats, each row r_i of which stores a pair " "s_i, b_i -- scale and bias for i-th row") .Output(0
default where $N$ is batch $C$ is number of $H$ is spatial height
Unscaled log probabilities Optional blob to be used to weight the samples for the loss With spatial weighting is by x
Output tensor quantization scale X
See RoIPoolF Gradient of forward dX
dimensions depend on whether the NCHW or NHWC operators are being used For in the the input has where N is the batch C is the number of channels
REGISTER_GRADIENT(CTC, GetCTCGradient)
SparseLengths8BitsRowwiseOp< CPUContext, 1, 1 >::LENGTHS uint8 tensor obtained with Integer vector containing indices of the first dimension of DATA for the slices that are being aggregated Matrix of each row r_i of which stores a pair b_i scale and bias for i th row Output(0, "output", "output")
where N is the number of elements in the H and W are the height and width
CAFFE_ENFORCE(dims.front() >=0, "Dimension ids must be non-negative.")
c10::BFloat16 max(c10::BFloat16 a, c10::BFloat16 b)
C10_EXPORT_CAFFE2_OP_TO_C10_CPU(RoIAlignGradient, "_caffe2::RoIAlignGradient(" " Tensor features," " Tensor rois," " Tensor grad," " str order," " float spatial_scale," " int pooled_h," " int pooled_w," " int sampling_ratio," " bool aligned" ") -> Tensor", caffe2::RoIAlignGradientCPUOp< float >)