Shape function for a SeparableConv2D op. This op has three inputs: * input, a 4D tensor with shape = [batch_size, rows, cols, depth_in] * depthwise_filter, a 4D tensor with shape = [filter_rows, filter_cols, depth_in, depth_multiplier] * pointwise_filter, a 4D tensor with shape = [1,
(op)
| 291 | |
| 292 | |
| 293 | def separable_conv2d_shape(op): |
| 294 | """Shape function for a SeparableConv2D op. |
| 295 | |
| 296 | This op has three inputs: |
| 297 | |
| 298 | * input, a 4D tensor with shape = [batch_size, rows, cols, depth_in] |
| 299 | |
| 300 | * depthwise_filter, a 4D tensor with shape = [filter_rows, |
| 301 | filter_cols, depth_in, depth_multiplier] |
| 302 | |
| 303 | * pointwise_filter, a 4D tensor with shape = [1, 1, depth_in * |
| 304 | depth_multiplier, depth_out] |
| 305 | |
| 306 | The output is a 4D tensor with shape = [batch_size, out_rows, |
| 307 | out_cols, depth_out], where out_rows and out_cols depend on the |
| 308 | value of the op's "padding" and "strides" attrs. |
| 309 | |
| 310 | Args: |
| 311 | op: A SeparableConv2D Operation. |
| 312 | |
| 313 | Returns: |
| 314 | A list containing the Shape of the SeparableConv2D output. |
| 315 | |
| 316 | Raises: |
| 317 | ValueError: If the shapes of the input or filter are incompatible. |
| 318 | """ |
| 319 | input_shape = op.inputs[0].get_shape().with_rank(4) |
| 320 | depthwise_filter_shape = op.inputs[1].get_shape().merge_with( |
| 321 | tensor_shape.TensorShape([None, None, input_shape[3], None])) |
| 322 | pointwise_depth_in = depthwise_filter_shape[2] * depthwise_filter_shape[3] |
| 323 | |
| 324 | pointwise_filter_shape = op.inputs[2].get_shape().merge_with( |
| 325 | tensor_shape.TensorShape([1, 1, pointwise_depth_in, None])) |
| 326 | |
| 327 | batch_size = input_shape[0] |
| 328 | in_rows = input_shape[1] |
| 329 | in_cols = input_shape[2] |
| 330 | |
| 331 | filter_rows = depthwise_filter_shape[0] |
| 332 | filter_cols = depthwise_filter_shape[1] |
| 333 | depth_out = pointwise_filter_shape[3] |
| 334 | |
| 335 | stride_b, stride_r, stride_c, stride_d = op.get_attr("strides") |
| 336 | if stride_b != 1 or stride_d != 1: |
| 337 | raise ValueError("Current implementation does not yet support " |
| 338 | "strides in the batch and depth dimensions.") |
| 339 | if stride_r != stride_c: |
| 340 | # TODO(shlens): Add support for this. |
| 341 | raise ValueError("Current implementation only supports equal length " |
| 342 | "strides in the row and column dimensions.") |
| 343 | |
| 344 | # TODO(mrry,shlens): Raise an error if the stride would cause |
| 345 | # information in the input to be ignored. This will require a change |
| 346 | # in the kernel implementation. |
| 347 | stride = stride_r |
| 348 | padding = op.get_attr("padding") |
| 349 | out_rows, out_cols = get2d_conv_output_size(in_rows, in_cols, filter_rows, |
| 350 | filter_cols, stride, stride, |
nothing calls this directly
no test coverage detected