commit
cc28fb4bb3
File diff suppressed because it is too large
Load Diff
@ -1,124 +0,0 @@
|
|||||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
|
||||||
|
|
||||||
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 "ExpandConvBaseLayer.h"
|
|
||||||
|
|
||||||
#include "paddle/utils/Logging.h"
|
|
||||||
namespace paddle {
|
|
||||||
|
|
||||||
bool ExpandConvBaseLayer::init(const LayerMap &layerMap,
|
|
||||||
const ParameterMap ¶meterMap) {
|
|
||||||
/* Initialize the basic convolutional parent class */
|
|
||||||
ConvBaseLayer::init(layerMap, parameterMap);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (auto &inputConfig : config_.inputs()) {
|
|
||||||
const ConvConfig &conf = inputConfig.conv_conf();
|
|
||||||
/* Consistent caffe mode for multiple input */
|
|
||||||
caffeMode_ = conf.caffe_mode();
|
|
||||||
|
|
||||||
// create a new weight
|
|
||||||
size_t height, width;
|
|
||||||
height = filterPixels_[index] * filterChannels_[index];
|
|
||||||
width = (!isDeconv_) ? numFilters_ : channels_[index];
|
|
||||||
CHECK_EQ(parameters_[index]->getSize(), width * height);
|
|
||||||
Weight *w = new Weight(height, width, parameters_[index]);
|
|
||||||
weights_.emplace_back(w);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
if (biasParameter_.get()) {
|
|
||||||
if (sharedBiases_) {
|
|
||||||
CHECK_EQ((size_t)numFilters_, biasParameter_->getSize());
|
|
||||||
biases_ =
|
|
||||||
std::unique_ptr<Weight>(new Weight(numFilters_, 1, biasParameter_));
|
|
||||||
} else {
|
|
||||||
biases_ =
|
|
||||||
std::unique_ptr<Weight>(new Weight(getSize(), 1, biasParameter_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getOutputSize();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ExpandConvBaseLayer::getOutputSize() {
|
|
||||||
CHECK_NE(inputLayers_.size(), 0UL);
|
|
||||||
size_t layerSize = ConvBaseLayer::calOutputSize();
|
|
||||||
return layerSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpandConvBaseLayer::addSharedBias() {
|
|
||||||
size_t mapW = getOutputSize() / numFilters_;
|
|
||||||
size_t mapH = getOutputValue()->getElementCnt() / mapW;
|
|
||||||
MatrixPtr out =
|
|
||||||
Matrix::create(getOutputValue()->getData(), mapH, mapW, false, useGpu_);
|
|
||||||
|
|
||||||
Matrix::resizeOrCreate(transOutValue_, mapW, mapH, false, useGpu_);
|
|
||||||
|
|
||||||
out->transpose(transOutValue_, false); // false means no memory allocation
|
|
||||||
transOutValue_->reshape(transOutValue_->getElementCnt() / numFilters_,
|
|
||||||
numFilters_);
|
|
||||||
|
|
||||||
MatrixPtr bias = Matrix::create(biases_->getW()->getData(),
|
|
||||||
1,
|
|
||||||
biases_->getW()->getElementCnt(),
|
|
||||||
false,
|
|
||||||
useGpu_);
|
|
||||||
transOutValue_->addBias(*bias, 1.0f);
|
|
||||||
|
|
||||||
transOutValue_->reshape(mapW, mapH);
|
|
||||||
transOutValue_->transpose(out, false); // false means no memory allocation
|
|
||||||
|
|
||||||
out->clear();
|
|
||||||
bias->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpandConvBaseLayer::addUnsharedBias() {
|
|
||||||
MatrixPtr outValue = getOutputValue();
|
|
||||||
MatrixPtr bias = Matrix::create(biases_->getW()->getData(),
|
|
||||||
1,
|
|
||||||
biases_->getW()->getElementCnt(),
|
|
||||||
false,
|
|
||||||
useGpu_);
|
|
||||||
outValue->addBias(*bias, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpandConvBaseLayer::bpropSharedBias(MatrixPtr biases, MatrixPtr v) {
|
|
||||||
size_t mapW = getOutputSize() / numFilters_;
|
|
||||||
size_t mapH = v->getElementCnt() / mapW;
|
|
||||||
MatrixPtr vTmp = Matrix::create(v->getData(), mapH, mapW, false, useGpu_);
|
|
||||||
|
|
||||||
Matrix::resizeOrCreate(transOutValue_, mapW, mapH, false, useGpu_);
|
|
||||||
|
|
||||||
vTmp->transpose(transOutValue_, false); // false means no memory allocation
|
|
||||||
transOutValue_->reshape(transOutValue_->getElementCnt() / numFilters_,
|
|
||||||
numFilters_);
|
|
||||||
biases->collectBias(*transOutValue_, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpandConvBaseLayer::bpropBiases(MatrixPtr v) {
|
|
||||||
MatrixPtr biases = Matrix::create(biases_->getWGrad()->getData(),
|
|
||||||
1,
|
|
||||||
biases_->getWGrad()->getElementCnt(),
|
|
||||||
false,
|
|
||||||
useGpu_);
|
|
||||||
if (sharedBiases_) {
|
|
||||||
bpropSharedBias(biases, v);
|
|
||||||
} else {
|
|
||||||
biases->collectBias(*v, 1.0f);
|
|
||||||
}
|
|
||||||
biases->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace paddle
|
|
@ -1,57 +0,0 @@
|
|||||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "ConvBaseLayer.h"
|
|
||||||
#include "paddle/math/Matrix.h"
|
|
||||||
|
|
||||||
namespace paddle {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A subclass of ConvBaseLayer that is a superclass of both
|
|
||||||
* ExpandConvLayer and ExpandConvTransLayer
|
|
||||||
*/
|
|
||||||
class ExpandConvBaseLayer : public ConvBaseLayer {
|
|
||||||
protected:
|
|
||||||
/// The transpose of output, which is an auxiliary matrix.
|
|
||||||
MatrixPtr transOutValue_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ExpandConvBaseLayer(const LayerConfig& config)
|
|
||||||
: ConvBaseLayer(config) {}
|
|
||||||
|
|
||||||
~ExpandConvBaseLayer() {}
|
|
||||||
|
|
||||||
bool init(const LayerMap& layerMap,
|
|
||||||
const ParameterMap& parameterMap) override;
|
|
||||||
|
|
||||||
size_t getOutputSize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add shared bias.
|
|
||||||
*/
|
|
||||||
void addSharedBias();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add unshared bias.
|
|
||||||
*/
|
|
||||||
void addUnsharedBias();
|
|
||||||
|
|
||||||
void bpropSharedBias(MatrixPtr biases, MatrixPtr v);
|
|
||||||
void bpropBiases(MatrixPtr v);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace paddle
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@
|
|||||||
|
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
||||||
|
|
||||||
|
#include "NEONFunctions.h"
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
namespace neon {
|
||||||
|
|
||||||
|
// b[i] = a[i] > 0.0f ? a[i] : 0.0f
|
||||||
|
void relu(const float* a, float* b, int len) {
|
||||||
|
int offset = len % 16;
|
||||||
|
float32x4_t ma0, ma1, ma2, ma3;
|
||||||
|
float32x4_t mb0, mb1, mb2, mb3;
|
||||||
|
|
||||||
|
float32x4_t zero = vdupq_n_f32(0.f);
|
||||||
|
for (int k = 0; k < len / 16; k++, a += 16, b += 16) {
|
||||||
|
ma0 = vld1q_f32(a);
|
||||||
|
ma1 = vld1q_f32(a + 4);
|
||||||
|
ma2 = vld1q_f32(a + 8);
|
||||||
|
ma3 = vld1q_f32(a + 12);
|
||||||
|
|
||||||
|
mb0 = vmaxq_f32(ma0, zero);
|
||||||
|
mb1 = vmaxq_f32(ma1, zero);
|
||||||
|
mb2 = vmaxq_f32(ma2, zero);
|
||||||
|
mb3 = vmaxq_f32(ma3, zero);
|
||||||
|
|
||||||
|
vst1q_f32(b, mb0);
|
||||||
|
vst1q_f32(b + 4, mb1);
|
||||||
|
vst1q_f32(b + 8, mb2);
|
||||||
|
vst1q_f32(b + 12, mb3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < offset; i++) {
|
||||||
|
b[i] = a[i] > 0.0f ? a[i] : 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace neon
|
||||||
|
} // namespace paddle
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,23 @@
|
|||||||
|
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
namespace neon {
|
||||||
|
|
||||||
|
void relu(const float* a, float* b, int len);
|
||||||
|
|
||||||
|
} // namespace neon
|
||||||
|
} // namespace paddle
|
@ -0,0 +1,197 @@
|
|||||||
|
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||||
|
|
||||||
|
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 "paddle/framework/op_registry.h"
|
||||||
|
#include "paddle/operators/net_op.h"
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
namespace operators {
|
||||||
|
|
||||||
|
class FCOp : public NetOp {
|
||||||
|
public:
|
||||||
|
FCOp(const std::string &type, const framework::VariableNameMap &inputs,
|
||||||
|
const framework::VariableNameMap &outputs,
|
||||||
|
const framework::AttributeMap &attrs)
|
||||||
|
: NetOp(type, inputs, outputs, attrs) {
|
||||||
|
PADDLE_ENFORCE(!Inputs("X").empty(),
|
||||||
|
"Inputs(X) of FCOp should not be null.");
|
||||||
|
PADDLE_ENFORCE(!Inputs("W").empty(),
|
||||||
|
"Inputs(W) of FCOp should not be null.");
|
||||||
|
PADDLE_ENFORCE(!Outputs("MulOut").empty(),
|
||||||
|
"Outputs(MulOut) of FCOp should not be null.");
|
||||||
|
PADDLE_ENFORCE_NE(Output("Out"), framework::kEmptyVarName,
|
||||||
|
"Output(Out) of FCOp should not be null.");
|
||||||
|
|
||||||
|
auto x = Inputs("X");
|
||||||
|
auto w = Inputs("W");
|
||||||
|
auto mul_out = Outputs("MulOut");
|
||||||
|
PADDLE_ENFORCE_EQ(
|
||||||
|
x.size(), w.size(),
|
||||||
|
"The size of inputs X(%d) should be the same as that of weights W(%d).",
|
||||||
|
x.size(), w.size());
|
||||||
|
PADDLE_ENFORCE_EQ(mul_out.size(), x.size(),
|
||||||
|
"The size of intermediate mul_out(%d) should be the same "
|
||||||
|
"as that of inputs X(%d).",
|
||||||
|
mul_out.size(), x.size());
|
||||||
|
|
||||||
|
size_t n = x.size();
|
||||||
|
PADDLE_ENFORCE_GE(n, static_cast<size_t>(1),
|
||||||
|
"The size of inputs X(%d) should be no less than 1.", n);
|
||||||
|
|
||||||
|
auto x_num_col_dims = Attr<std::vector<int>>("xNumColDims");
|
||||||
|
|
||||||
|
// Set all values or set no values (use the default value)
|
||||||
|
if (!x_num_col_dims.empty()) {
|
||||||
|
PADDLE_ENFORCE_EQ(x_num_col_dims.size(), n,
|
||||||
|
"The size of attribute xNumColDims(%d) should be the "
|
||||||
|
"same as that of inputs X(%d).",
|
||||||
|
x_num_col_dims.size(), n);
|
||||||
|
} else {
|
||||||
|
x_num_col_dims.resize(n);
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
x_num_col_dims[i] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mul_out[i] = X[i] * W[i]
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
framework::AttributeMap mul_attr;
|
||||||
|
mul_attr["x_num_col_dims"] = static_cast<int>(x_num_col_dims[i]);
|
||||||
|
mul_attr["y_num_col_dims"] = static_cast<int>(1);
|
||||||
|
AppendOp(
|
||||||
|
framework::OpRegistry::CreateOp("mul", {{"X", {x[i]}}, {"Y", {w[i]}}},
|
||||||
|
{{"Out", {mul_out[i]}}}, mul_attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_out = X[0] * W[0] + ... + X[n-1] * W[n-1]
|
||||||
|
auto sum_out = mul_out[0];
|
||||||
|
if (n > 1) {
|
||||||
|
PADDLE_ENFORCE_NE(Output("SumOut"), framework::kEmptyVarName,
|
||||||
|
"Output(SumOut) of FCOp should not be null when the "
|
||||||
|
"size of Inputs(X) > 1.");
|
||||||
|
|
||||||
|
sum_out = Output("SumOut");
|
||||||
|
AppendOp(framework::OpRegistry::CreateOp("sum", {{"X", {mul_out}}},
|
||||||
|
{{"Out", {sum_out}}}, {}));
|
||||||
|
} else {
|
||||||
|
if (Output("SumOut") != framework::kEmptyVarName) {
|
||||||
|
this->Rename(Output("SumOut"), framework::kEmptyVarName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add_out = sum_out + b
|
||||||
|
auto b = Input("B");
|
||||||
|
auto add_out = sum_out;
|
||||||
|
if (b != framework::kEmptyVarName) {
|
||||||
|
PADDLE_ENFORCE_NE(
|
||||||
|
Output("AddOut"), framework::kEmptyVarName,
|
||||||
|
"Output(AddOut) of FCOp should not be null when Input(B) is set.");
|
||||||
|
|
||||||
|
add_out = Output("AddOut");
|
||||||
|
AppendOp(framework::OpRegistry::CreateOp(
|
||||||
|
"rowwise_add", {{"X", {sum_out}}, {"b", {Input("B")}}},
|
||||||
|
{{"Out", {add_out}}}, {}));
|
||||||
|
} else {
|
||||||
|
if (Output("AddOut") != framework::kEmptyVarName) {
|
||||||
|
this->Rename(Output("AddOut"), framework::kEmptyVarName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto activation = Attr<std::string>("activation");
|
||||||
|
AppendOp(framework::OpRegistry::CreateOp(activation, {{"X", {add_out}}},
|
||||||
|
{{"Y", {Output("Out")}}}, {}));
|
||||||
|
CompleteAddOp(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FCOpMaker : public framework::OpProtoAndCheckerMaker {
|
||||||
|
public:
|
||||||
|
FCOpMaker(framework::OpProto *proto, framework::OpAttrChecker *op_checker)
|
||||||
|
: OpProtoAndCheckerMaker(proto, op_checker) {
|
||||||
|
AddInput("X",
|
||||||
|
"(A vector of Tensors) each input Tensor can be of arbitrary "
|
||||||
|
"dimension, and will be reshaped to a 2-D matrix of size "
|
||||||
|
"(minibatch, number_of_input_features) according to attribute "
|
||||||
|
"xNumColDims.")
|
||||||
|
.AsDuplicable();
|
||||||
|
AddInput("W",
|
||||||
|
"(A vector of Tensors) the weights of FC operator, a "
|
||||||
|
"vector of 2-D matrix of size "
|
||||||
|
"(number_of_input_features, number_of_neurons).")
|
||||||
|
.AsDuplicable();
|
||||||
|
AddInput("B",
|
||||||
|
"(Tensor) the bias of FC operator, a 1-D vector of size "
|
||||||
|
"number_of_neurons.");
|
||||||
|
|
||||||
|
AddOutput("Out",
|
||||||
|
"(Tensor) the activated output matrix of FC operator, a 2-D "
|
||||||
|
"matrix of size (minibatch, number_of_neurons).");
|
||||||
|
AddOutput("MulOut",
|
||||||
|
"(A vector of Tensors) the intermediate outputs of FC operator, "
|
||||||
|
"each Tensor saving the product of X_i * W_i.")
|
||||||
|
.AsIntermediate()
|
||||||
|
.AsDuplicable();
|
||||||
|
AddOutput(
|
||||||
|
"SumOut",
|
||||||
|
"(Tensor) the intermediate output of FC operator, "
|
||||||
|
"saving the sum of the products of X and W, that is sum{X_i * W_i}.")
|
||||||
|
.AsIntermediate();
|
||||||
|
AddOutput("AddOut",
|
||||||
|
"(Tensor) the non-actived output of FC operator, "
|
||||||
|
"saving sum{X_i * W_i} + B.")
|
||||||
|
.AsIntermediate();
|
||||||
|
AddAttr<std::string>(
|
||||||
|
"activation",
|
||||||
|
"(string, default identity) the activation type of FC operator.")
|
||||||
|
.SetDefault("identity")
|
||||||
|
.InEnum({"identity", "sigmoid", "softmax"});
|
||||||
|
AddAttr<std::vector<int>>(
|
||||||
|
"xNumColDims",
|
||||||
|
"(std::vector<int>) The inputs Tensors of FC operator can be of "
|
||||||
|
"more than 2 dimensions. In that case, each input Tensor `X_i` will be "
|
||||||
|
"reshaped to a 2-D matrix. The matrix's first dimension "
|
||||||
|
"(the length of column) will be the product of `X_i`'s last "
|
||||||
|
"`xNumColDims_i` dimensions, that is "
|
||||||
|
"`X_i.dims[0] x ... x X_i.dims[xNumColDims_i - 1]`. "
|
||||||
|
"The matrix's second dimension (the length of row) will be the product "
|
||||||
|
"of `X_i`'s first `rank - xNumColDims_i` dimensions, that is "
|
||||||
|
"`X_i.dims[xNumColDims_i] x ... x X_i.dims[rank - 1]`)")
|
||||||
|
.SetDefault(std::vector<int>{});
|
||||||
|
|
||||||
|
AddComment(R"DOC(
|
||||||
|
Fully Connected Operator, known as Fully Connected Layer or Inner Product Layer
|
||||||
|
in Convolutional Neural Networks. Neurons in a fully connected layer have
|
||||||
|
full connections to all activations in the previous layer.
|
||||||
|
It computes an inner product of a set of
|
||||||
|
learned weights with a matrix multiplication followed by a bias offset
|
||||||
|
(optionally).
|
||||||
|
|
||||||
|
Equation:
|
||||||
|
Out = Act(sum_n{X_i * W_i} + B)
|
||||||
|
|
||||||
|
where X_i is Tensor that will be reshaped to a 2-D matrix of size (M x K),
|
||||||
|
usually M is the minibatch size and K is the number of input features.
|
||||||
|
W_i is a 2-D matrix of size (K x N), where N means the number of neurons
|
||||||
|
in the fully connected layer. B is a 1-D vector of size N.
|
||||||
|
Thus, the output Out is a 2-D matrix of size (M x N).
|
||||||
|
Activation type can be set to `identity` (default), `sigmoid` or `softmax`.
|
||||||
|
)DOC");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace operators
|
||||||
|
} // namespace paddle
|
||||||
|
|
||||||
|
namespace ops = paddle::operators;
|
||||||
|
REGISTER_OP_WITHOUT_GRADIENT(fc, ops::FCOp, ops::FCOpMaker);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue