| /** |
| * Copyright (c) 2016-present, Facebook, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "caffe2/experiments/operators/funhash_op.h" |
| |
| namespace caffe2 { |
| namespace { |
| |
| REGISTER_CPU_OPERATOR(FunHash, FunHashOp<float, CPUContext>); |
| REGISTER_CPU_OPERATOR(FunHashGradient, FunHashGradientOp<float, CPUContext>); |
| |
| OPERATOR_SCHEMA(FunHash) |
| .NumInputs(4, 5) |
| .NumOutputs(1) |
| .SetDoc(R"DOC( |
| This layer compresses a fully-connected layer for sparse inputs |
| via hashing. |
| It takes four required inputs and an optional fifth input. |
| The first three inputs `scalars`, `indices`, and `segment_ids` are |
| the sparse segmented representation of sparse data, which are the |
| same as the last three inputs of the `SparseSortedSegmentWeightedSum` |
| operator. If the argument `num_segments` is specified, it would be used |
| as the first dimension for the output; otherwise it would be derived |
| from the maximum segment ID. |
| |
| The fourth input is a 1D weight vector. Each entry of the fully-connected |
| layer would be randomly mapped from one of the entries in this vector. |
| |
| When the optional fifth input vector is present, each weight of the |
| fully-connected layer would be the linear combination of K entries |
| randomly mapped from the weight vector, provided the input |
| (length-K vector) serves as the coefficients. |
| )DOC") |
| .Input(0, "scalars", "Values of the non-zero entries of the sparse data.") |
| .Input(1, "indices", "Indices to the non-zero valued features.") |
| .Input( |
| 2, |
| "segment_ids", |
| "Segment IDs corresponding to the non-zero entries.") |
| .Input(3, "weight", "Weight vector") |
| .Input( |
| 4, |
| "alpha", |
| "Optional coefficients for linear combination of hashed weights.") |
| .Output( |
| 0, |
| "output", |
| "Output tensor with the first dimension equal to the number " |
| "of segments.") |
| .Arg("num_outputs", "Number of outputs") |
| .Arg("num_segments", "Number of segments"); |
| |
| OPERATOR_SCHEMA(FunHashGradient).NumInputs(5, 6).NumOutputs(1, 2); |
| |
| class GetFunHashGradient : public GradientMakerBase { |
| using GradientMakerBase::GradientMakerBase; |
| vector<OperatorDef> GetGradientDefs() override { |
| if (def_.input_size() == 4) { |
| return SingleGradientDef( |
| "FunHashGradient", |
| "", |
| vector<string>{GO(0), I(0), I(1), I(2), I(3)}, |
| vector<string>{GI(3)}); |
| } |
| // def_.input_size() == 5 |
| return SingleGradientDef( |
| "FunHashGradient", |
| "", |
| vector<string>{GO(0), I(0), I(1), I(2), I(3), I(4)}, |
| vector<string>{GI(3), GI(4)}); |
| } |
| }; |
| |
| REGISTER_GRADIENT(FunHash, GetFunHashGradient); |
| |
| } // namespace |
| } // namespace caffe2 |