Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into mixed_layer

avx_docs
dangqingqing 8 years ago
commit 7a8da332a1

@ -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)

@ -50,11 +50,12 @@ def main():
parameters=parameters,
event_handler=event_handler,
batch_size=32, # batch size should be refactor in Data reader
data_types={ # data_types will be removed, It should be in
data_types=[ # data_types will be removed, It should be in
# network topology
'pixel': images.type,
'label': label.type
})
('pixel', images.type),
('label', label.type)],
reader_dict={'pixel':0, 'label':1}
)
if __name__ == '__main__':

@ -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;
}

@ -23,7 +23,8 @@ __all__ = ['DataProviderConverter']
class IScanner(object):
def __init__(self, input_type, pos):
self.input_type = input_type
assert isinstance(self.input_type, dp2.InputType)
if not isinstance(self.input_type, dp2.InputType):
raise ValueError("input type should be dataprovider2.InputType")
self.pos = pos
def scan(self, dat):
@ -50,7 +51,6 @@ class DenseScanner(IScanner):
def finish_scan(self, argument):
assert isinstance(argument, swig_paddle.Arguments)
assert isinstance(self.input_type, dp2.InputType)
if self.__mat__.dtype != numpy.float32:
self.__mat__ = self.__mat__.astype(numpy.float32)
m = swig_paddle.Matrix.createDenseFromNumpy(self.__mat__, True, False)
@ -63,7 +63,6 @@ class SparseBinaryScanner(IScanner):
self.__rows__ = [0]
self.__cols__ = []
self.__height__ = 0
self.__nnz__ = 0
self.__value__ = []
def scan(self, dat):
@ -76,7 +75,6 @@ class SparseBinaryScanner(IScanner):
def finish_scan(self, argument):
assert isinstance(argument, swig_paddle.Arguments)
assert isinstance(self.input_type, dp2.InputType)
m = swig_paddle.Matrix.createSparse(self.__height__,
self.input_type.dim,
len(self.__cols__),

@ -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

@ -21,3 +21,5 @@
#
# r = paddle.reader.buffered(paddle.reader.creator.text("hello.txt"))
from decorator import *
import creator

@ -0,0 +1,53 @@
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
#
# 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.
__all__ = ['np_array', 'text_file']
def np_array(x):
"""
Creates a reader that yields elements of x, if it is a
numpy vector. Or rows of x, if it is a numpy matrix.
Or any sub-hyperplane indexed by the highest dimension.
:param x: the numpy array to create reader from.
:returns: data reader created from x.
"""
def reader():
if x.ndim < 1:
yield x
for e in x:
yield e
return reader
def text_file(path):
"""
Creates a data reader that outputs text line by line from given text file.
Trailing new line ('\n') of each line will be removed.
:path: path of the text file.
:returns: data reader of text file
"""
def reader():
f = open(path, "r")
for l in f:
yield l.rstrip('\n')
f.close()
return reader

@ -2,3 +2,8 @@ add_test(NAME reader_decorator_test
COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/reader/tests/decorator_test.py
WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)
add_test(NAME reader_creator_test
COMMAND ${PROJ_ROOT}/paddle/.set_python_path.sh -d ${PROJ_ROOT}/python/
${PYTHON_EXECUTABLE} ${PROJ_ROOT}/python/paddle/reader/tests/creator_test.py
WORKING_DIRECTORY ${PROJ_ROOT}/python/paddle)

@ -0,0 +1,38 @@
# Copyright PaddlePaddle contributors. All Rights Reserved
#
# 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.
import unittest
import paddle.reader.creator
import numpy as np
import os
class TestNumpyArray(unittest.TestCase):
def test_numpy_array(self):
l = [[1, 2, 3], [4, 5, 6]]
x = np.array(l, np.int32)
reader = paddle.reader.creator.np_array(x)
for idx, e in enumerate(reader()):
self.assertItemsEqual(e, l[idx])
class TestTextFile(unittest.TestCase):
def test_text_file(self):
path = os.path.join(os.path.dirname(__file__), "test_data_creator.txt")
reader = paddle.reader.creator.text_file(path)
for idx, e in enumerate(reader()):
self.assertEqual(e, str(idx * 2) + " " + str(idx * 2 + 1))
if __name__ == '__main__':
unittest.main()

@ -18,12 +18,13 @@ import parameters
import trainer
import event
import data_type
import data_feeder
import attr
import py_paddle.swig_paddle as api
__all__ = [
'optimizer', 'layer', 'activation', 'parameters', 'init', 'trainer',
'event', 'data_type', 'attr'
'event', 'data_type', 'attr', 'data_feeder'
]

@ -0,0 +1,100 @@
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
#
# 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.
from py_paddle import swig_paddle
from py_paddle import DataProviderConverter
import data_type
__all__ = ['DataFeeder']
class DataFeeder(DataProviderConverter):
"""
DataFeeder converts the data returned by paddle.reader into a data structure
of Arguments which is defined in the API. The paddle.reader usually returns
a list of mini-batch data entries. Each data entry in the list is one sampe.
Each sample is a list or a tuple with one feature or multiple features.
DataFeeder converts this mini-batch data entries into Arguments in order
to feed it to C++ interface.
The example usage:
data_types = [('image', paddle.data_type.dense_vector(784)),
('label', paddle.data_type.integer_value(10))]
reader_dict = {'image':0, 'label':1}
feeder = DataFeeder(data_types=data_types, reader_dict=reader_dict)
minibatch_data = [
( [1.0,2.0,3.0,4.0], 5, [6,7,8] ), # first sample
( [1.0,2.0,3.0,4.0], 5, [6,7,8] ) # second sample
]
# or minibatch_data = [
# [ [1.0,2.0,3.0,4.0], 5, [6,7,8] ], # first sample
# [ [1.0,2.0,3.0,4.0], 5, [6,7,8] ] # second sample
# ]
arg = feeder(minibatch_data)
"""
def __init__(self, data_types, reader_dict):
"""
:param data_types: A list to specify data name and type. Each item is
a tuple of (data_name, data_type). For example:
[('image', paddle.data_type.dense_vector(784)),
('label', paddle.data_type.integer_value(10))]
:type data_types: A list of tuple
:param reader_dict: A dictionary to specify the position of each data
in the input data.
:type reader_dict: dict()
"""
self.input_names = []
input_types = []
self.reader_dict = reader_dict
for each in data_types:
self.input_names.append(each[0])
assert isinstance(each[1], data_type.InputType)
input_types.append(each[1])
DataProviderConverter.__init__(self, input_types)
def convert(self, dat, argument=None):
"""
:param dat: A list of mini-batch data. Each sample is a list or tuple
one feature or multiple features.
for example:
[
([0.2, 0.2], ), # first sample
([0.8, 0.3], ), # second sample
]
or,
[
[[0.2, 0.2], ], # first sample
[[0.8, 0.3], ], # second sample
]
:type dat: List
:param argument: An Arguments object contains this mini-batch data with
one or multiple features. The Arguments definition is
in the API.
:type argument: swig_paddle.Arguments
"""
def reorder_data(data):
retv = []
for each in data:
reorder = []
for name in self.input_names:
reorder.append(each[self.reader_dict[name]])
retv.append(reorder)
return retv
return DataProviderConverter.convert(self, reorder_data(dat), argument)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save