tensorflow/lite/toco/graph_transformations/convert_squeeze_to_reshape.cc
// Replaces a tf.squeeze operator with a reshape.
// Squeeze removes dimensions == 1 (if in the list of squeeze_dims). This
// means that the data layout will never change with this op, just the shape.
// By converting these to reshapes once we have run shape propagation we allow
// standard reshape optimization transforms to do their magic.
Replaces a tf.squeeze operator with a reshape.
Squeeze removes dimensions == 1 (if in the list of squeeze_dims). This
means that the data layout will never change with this op, just the shape.
By converting these to reshapes once we have run shape propagation we allow
standard reshape optimization transforms to do their magic.
Replaces a tf . squeeze operator with a reshape . Squeeze removes dimensions == 1 ( if in the list of squeeze_dims ) . This means that the data layout will never change with this op just the shape . By converting these to reshapes once we have run shape propagation we allow standard reshape optimization transforms to do their magic .
::tensorflow::Status ConvertSqueezeToReshape::Run(Model* model,
                                                  std::size_t op_index,
                                                  bool* modified) {
  *modified = false;
  auto squeeze_it = model->operators.begin() + op_index;
  if (squeeze_it->get()->type != OperatorType::kSqueeze) {
    return ::tensorflow::Status::OK();
  }
  auto squeeze_op = static_cast<SqueezeOperator*>(squeeze_it->get());
  CHECK_EQ(squeeze_op->inputs.size(), 1);
  CHECK_EQ(squeeze_op->outputs.size(), 1);
  const auto& input_array = model->GetArray(squeeze_op->inputs[0]);
  if (!input_array.has_shape()) {
    return ::tensorflow::Status::OK();
  }
  if (input_array.shape().dimensions_count() == 0) {
    return ::tensorflow::Status::OK();
  }
  if (!model->HasArray(squeeze_op->outputs[0]) ||
      !model->GetArray(squeeze_op->outputs[0]).has_shape()) {
    return ::tensorflow::Status::OK();
  }
  const auto& output_shape = model->GetArray(squeeze_op->outputs[0]).shape();
  if (output_shape.dimensions_count() == 0) {
    return ::tensorflow::Status::OK();
  }
  auto* reshape_op = new TensorFlowReshapeOperator;
  reshape_op->inputs = {
      squeeze_op->inputs[0],
      CreateInt32Array(model, squeeze_op->outputs[0] + "_shape",
                       output_shape.dims()),
  };
  reshape_op->outputs = squeeze_op->outputs;
  AddMessageF("Replacing %s with %s", LogName(*squeeze_op),
              LogName(*reshape_op));
  model->operators.emplace(squeeze_it, reshape_op);
  DeleteOpAndArrays(model, squeeze_op);
  *modified = true;
  return ::tensorflow::Status::OK();
}
:: tensorflow :: Status ConvertSqueezeToReshape :: Run ( Model * model , std :: size_t op_index , bool * modified ) { * modified = false ; auto squeeze_it = model -> operators . begin ( ) + op_index ; if ( squeeze_it -> get ( ) -> type != OperatorType :: kSqueeze ) { return :: tensorflow :: Status :: OK ( ) ; } auto squeeze_op = static_cast < SqueezeOperator * > ( squeeze_it -> get ( ) ) ; CHECK_EQ ( squeeze_op -> inputs . size ( ) , 1 ) ; CHECK_EQ ( squeeze_op -> outputs . size ( ) , 1 ) ; const auto & input_array = model -> GetArray ( squeeze_op -> inputs [ 0 ] ) ; if ( ! input_array . has_shape ( ) ) { return :: tensorflow :: Status :: OK ( ) ; } if ( input_array . shape ( ) . dimensions_count ( ) == 0 ) { return :: tensorflow :: Status :: OK ( ) ; } if ( ! model -> HasArray ( squeeze_op -> outputs [ 0 ] ) || ! model -> GetArray ( squeeze_op -> outputs [ 0 ] ) . has_shape ( ) ) { return :: tensorflow :: Status :: OK ( ) ; } const auto & output_shape = model -> GetArray ( squeeze_op -> outputs [ 0 ] ) . shape ( ) ; if ( output_shape . dimensions_count ( ) == 0 ) { return :: tensorflow :: Status :: OK ( ) ; } auto * reshape_op = new TensorFlowReshapeOperator ; reshape_op -> inputs = { squeeze_op -> inputs [ 0 ] , CreateInt32Array ( model , squeeze_op -> outputs [ 0 ] + " " , output_shape . dims ( ) ) , } ; reshape_op -> outputs = squeeze_op -> outputs ; AddMessageF ( " " , LogName ( * squeeze_op ) , LogName ( * reshape_op ) ) ; model -> operators . emplace ( squeeze_it , reshape_op ) ; DeleteOpAndArrays ( model , squeeze_op ) ; * modified = true ; return :: tensorflow :: Status :: OK ( ) ; }
Replaces a tf.squeeze operator with a reshape.
Replaces a tf . squeeze operator with a reshape .
// Yield until input dims have been resolved. // Input array cannot be 0-D. // Yield until shape propagation has set the output shape for us. // We use the output shape that has been calculated by shape propagation. // Empty shapes will not work as empty data arrays. // Replace the operator in the graph.