提交 6f313371 编写于 作者: G gangliao 提交者: GitHub

Merge pull request #1353 from gangliao/concat

LayerOutput for single machine multiple devices
......@@ -126,7 +126,7 @@ class ImageClassifier():
# For oversampling, average predictions across crops.
# If not, the shape of output[name]: (1, class_number),
# the mean is also applicable.
return output[output_layer].mean(0)
return output[output_layer]['value'].mean(0)
def predict(self, image=None, output_layer=None):
assert isinstance(image, basestring)
......
......@@ -156,7 +156,7 @@ class ImageClassifier():
# For oversampling, average predictions across crops.
# If not, the shape of output[name]: (1, class_number),
# the mean is also applicable.
res[name] = output[name].mean(0)
res[name] = output[name]['value'].mean(0)
return res
......
......@@ -38,6 +38,13 @@ Arguments* Arguments::createByPaddleArgumentVector(void* ptr) {
return args;
}
Arguments* Arguments::createByPaddleArgument(const void* ptr) {
auto p = (paddle::Argument*)(ptr);
auto args = new Arguments();
args->m->outputs.push_back(*p);
return args;
}
Matrix* Arguments::getSlotValue(size_t idx) const throw(RangeError) {
auto& a = m->getArg(idx);
return Matrix::createByPaddleMatrixPtr(&a.value);
......
......@@ -144,12 +144,12 @@ Parameter* GradientMachine::getParameter(size_t i) throw(RangeError) {
void GradientMachine::randParameters() { m->machine->randParameters(); }
Matrix* GradientMachine::getLayerOutput(const std::string& layerName) const
Arguments* GradientMachine::getLayerOutput(const std::string& layerName) const
throw(UnsupportError) {
auto nn = std::dynamic_pointer_cast<paddle::NeuralNetwork>(m->machine);
auto nn = m->machine;
if (nn) {
auto mat = nn->getLayerOutput(layerName);
return Matrix::createByPaddleMatrixPtr(&mat);
auto arg = nn->getLayerOutput(layerName);
return Arguments::createByPaddleArgument(&arg);
} else {
throw UnsupportError();
}
......
......@@ -454,6 +454,7 @@ public:
private:
static Arguments* createByPaddleArgumentVector(void* ptr);
static Arguments* createByPaddleArgument(const void* ptr);
void* getInternalArgumentsPtr() const;
private:
......@@ -769,7 +770,7 @@ public:
void randParameters();
Matrix* getLayerOutput(const std::string& layerName) const
Arguments* getLayerOutput(const std::string& layerName) const
throw(UnsupportError);
/**
......@@ -956,7 +957,7 @@ public:
Arguments* getForwardOutput();
Matrix* getLayerOutput(const std::string& layerName);
Arguments* getLayerOutput(const std::string& layerName) const;
};
/// the N-Best results generated from one input sequence.
......
......@@ -131,12 +131,11 @@ void Trainer::testOneDataBatch(size_t batchSize, const Arguments& args) {
void TrainerPrivate::finishTestPeriod() { tester_->finishTestPeriod(); }
void Trainer::finishTestPeriod() { m->finishTestPeriod(); }
Matrix* Trainer::getLayerOutput(const std::string& layerName) {
auto nn = std::dynamic_pointer_cast<paddle::NeuralNetwork>(
this->m->getGradientMachine());
Arguments* Trainer::getLayerOutput(const std::string& layerName) const {
auto nn = this->m->getGradientMachine();
CHECK(nn) << "trainerInternal_.getGradientMachine() is not NeuralNetwork";
auto m = nn->getLayerOutput(layerName);
return Matrix::createByPaddleMatrixPtr(&m);
auto arg = nn->getLayerOutput(layerName);
return Arguments::createByPaddleArgument(&arg);
}
void Trainer::forwardOneBatch(size_t batchSize) {
......
......@@ -134,6 +134,10 @@ public:
backward(callback);
}
virtual Argument getLayerOutput(const std::string& layerName) {
return *((Argument*)nullptr);
}
// see comment in Layer.h for the function with the same name
virtual void resetState() {}
......
......@@ -282,6 +282,18 @@ void MultiGradientMachine::forwardBackward(const std::vector<Argument>& inArgs,
backwardImp(callback);
}
Argument MultiGradientMachine::getLayerOutput(const std::string& layerName) {
std::vector<Argument> args;
args.reserve(threads_.size());
for (auto& thread : threads_) {
args.push_back(thread->getGradientMachine()->getLayerOutput(layerName));
}
outLayerArgs_.concat(args, false /* use_gpu */, outArgStream_, passType_);
return outLayerArgs_;
}
void MultiGradientMachine::backwardImp(const UpdateCallback& callback) {
for (size_t i = 0; i < parameters_.size(); i++) {
if (!parameters_[i]->useGpu() || parameters_[i]->isStatic()) continue;
......
......@@ -189,6 +189,8 @@ public:
PassType passType,
const UpdateCallback& callback);
virtual Argument getLayerOutput(const std::string& layerName);
virtual void onPassEnd();
virtual void finish();
......@@ -314,6 +316,8 @@ protected:
std::vector<Argument> outArgs_;
hl_stream_t outArgStream_;
Argument outLayerArgs_;
/// ParameterType which needs to be merged from each GPU
std::vector<ParameterType> mergeTypes_;
int numDevices_; /* number of gpu devices */
......
......@@ -293,11 +293,10 @@ void NeuralNetwork::backward(const UpdateCallback& callback) {
}
}
MatrixPtr NeuralNetwork::getLayerOutput(const std::string& layerName) {
auto it = layerMap_.find(layerName);
CHECK(it != layerMap_.end()) << "Cannot find layer: " << layerName;
return it->second->getOutputValue();
Argument NeuralNetwork::getLayerOutput(const std::string& layerName) {
return getLayer(layerName)->getOutput();
}
void NeuralNetwork::onPassEnd() {
for (auto& layer : layers_) {
layer->onPassEnd();
......
......@@ -87,7 +87,8 @@ public:
virtual void backward(const UpdateCallback& callback = nullptr);
MatrixPtr getLayerOutput(const std::string& layerName);
virtual Argument getLayerOutput(const std::string& layerName);
const LayerPtr& getLayer(const std::string& layerName) const {
auto it = layerMap_.find(layerName);
CHECK(it != layerMap_.end()) << "Unknown layer " << layerName;
......
......@@ -42,7 +42,7 @@ void CosSimLayer::forward(PassType passType) {
/* malloc memory for the output_ if necessary */
int batchSize = getInputValue(0)->getHeight();
int size = getSize();
CHECK_EQ(forward_.size(), 1) << "Only one forward function needed";
CHECK_EQ(forward_.size(), 1UL) << "Only one forward function needed";
{
REGISTER_TIMER_INFO("CosFwResetTimer", getName().c_str());
......@@ -68,7 +68,7 @@ void CosSimLayer::forward(PassType passType) {
void CosSimLayer::backward(const UpdateCallback& callback) {
/* activation */ {
REGISTER_TIMER_INFO("CosBpAtvTimer", getName().c_str());
CHECK_EQ(backward_.size(), 1) << "Only one backward function needed";
CHECK_EQ(backward_.size(), 1UL) << "Only one backward function needed";
const auto outG = this->getOutputGrad();
const auto outV = this->getOutputValue();
......
......@@ -112,7 +112,7 @@ bool CosSimVecMatLayer::init(const LayerMap& layerMap,
void CosSimVecMatLayer::forward(PassType passType) {
Layer::forward(passType);
CHECK_EQ(forward_.size(), 1) << "Only one forward function needed";
CHECK_EQ(forward_.size(), 1UL) << "Only one forward function needed";
MatrixPtr inV0 = getInputValue(0);
MatrixPtr inV1 = getInputValue(1);
......@@ -145,7 +145,7 @@ void CosSimVecMatLayer::forward(PassType passType) {
}
void CosSimVecMatLayer::backward(const UpdateCallback& callback) {
CHECK_EQ(backward_.size(), 1) << "Only one forward function needed";
CHECK_EQ(backward_.size(), 1UL) << "Only one forward function needed";
MatrixPtr inV0 = getInputValue(0);
MatrixPtr inV1 = getInputValue(1);
......
......@@ -17,10 +17,10 @@ limitations under the License. */
TEST(RowBuffer, testAutoGrow) {
paddle::RowBuffer buf(128);
ASSERT_EQ(128, buf.getWidth());
ASSERT_EQ(128UL, buf.getWidth());
ASSERT_TRUE(buf.isAutoGrowth());
buf.resize(2);
ASSERT_EQ(2, buf.getRowCount());
ASSERT_EQ(2UL, buf.getRowCount());
for (size_t i = 0; i < buf.getWidth() * 2; ++i) {
buf.data()[i] = i;
}
......@@ -35,7 +35,7 @@ TEST(RowBuffer, testAutoGrow) {
data[i] = i;
}
ASSERT_EQ(3, buf.getRowCount());
ASSERT_EQ(3UL, buf.getRowCount());
for (size_t i = 0; i < buf.getRowCount() - 1; ++i) {
for (size_t j = 0; j < buf.getWidth(); ++j) {
ASSERT_NEAR(i * buf.getWidth() + j, buf.get(i)[j], 1e-5);
......@@ -51,7 +51,7 @@ TEST(RowBuffer, testWithMemBuf) {
std::make_shared<paddle::CpuMemoryHandle>(128 * 2 * sizeof(real));
paddle::RowBuffer buf(mem, 128);
ASSERT_TRUE(!buf.isAutoGrowth());
ASSERT_EQ(2, buf.getRowCount());
ASSERT_EQ(2UL, buf.getRowCount());
for (size_t i = 0; i < buf.getWidth() * 2; ++i) {
buf.data()[i] = i;
}
......
......@@ -208,7 +208,7 @@ def __monkeypatch_gradient_machine__():
output = dict()
for name in layerNames:
output[name] = __matrix_to_numpy__(self.getLayerOutput(name))
output[name] = __arguments_to_numpy__(0, self.getLayerOutput(name))
return output
swig_paddle.GradientMachine.getLayerOutputs = getLayerOutputs
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册