diff --git a/python/paddle/v2/__init__.py b/python/paddle/v2/__init__.py index cc8f33f9800391580d4bacab8a070a04af352a4c..d548d1adaafacdb097dbe476fdc76651c9f46b6b 100644 --- a/python/paddle/v2/__init__.py +++ b/python/paddle/v2/__init__.py @@ -25,12 +25,13 @@ from . import reader import attr import pooling import inferencer +import networks import py_paddle.swig_paddle as api __all__ = [ 'optimizer', 'layer', 'activation', 'parameters', 'init', 'trainer', 'event', 'data_type', 'attr', 'pooling', 'data_feeder', 'dataset', 'reader', - 'topology', 'inferencer', 'infer' + 'topology', 'networks', 'inferencer', 'infer' ] diff --git a/python/paddle/v2/config_base.py b/python/paddle/v2/config_base.py new file mode 100644 index 0000000000000000000000000000000000000000..035f96b0f2e978a413a1ebe0ec115f75ff07befc --- /dev/null +++ b/python/paddle/v2/config_base.py @@ -0,0 +1,86 @@ +# 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. + +import collections + +from paddle.trainer_config_helpers.default_decorators import wrap_name_default +import paddle.trainer_config_helpers as conf_helps + + +class Layer(object): + def __init__(self, name=None, parent_layers=None): + assert isinstance(parent_layers, dict) + self.name = name + self.__parent_layers__ = parent_layers + + def to_proto(self, context): + """ + function to set proto attribute + """ + kwargs = dict() + for layer_name in self.__parent_layers__: + if not isinstance(self.__parent_layers__[layer_name], + collections.Sequence): + v1_layer = self.__parent_layers__[layer_name].to_proto( + context=context) + else: + v1_layer = map(lambda x: x.to_proto(context=context), + self.__parent_layers__[layer_name]) + kwargs[layer_name] = v1_layer + + if self.name is None: + return self.to_proto_impl(**kwargs) + elif self.name not in context: + context[self.name] = self.to_proto_impl(**kwargs) + + return context[self.name] + + def to_proto_impl(self, **kwargs): + raise NotImplementedError() + + +def __convert_to_v2__(method_name, parent_names, is_default_name=True): + if is_default_name: + wrapper = wrap_name_default(name_prefix=method_name) + else: + wrapper = None + + class V2LayerImpl(Layer): + def __init__(self, **kwargs): + parent_layers = dict() + other_kwargs = dict() + for pname in parent_names: + if kwargs.has_key(pname): + parent_layers[pname] = kwargs[pname] + + for key in kwargs.keys(): + if key not in parent_names: + other_kwargs[key] = kwargs[key] + + name = kwargs.get('name', None) + super(V2LayerImpl, self).__init__(name, parent_layers) + self.__other_kwargs__ = other_kwargs + + if wrapper is not None: + __init__ = wrapper(__init__) + + def to_proto_impl(self, **kwargs): + args = dict() + for each in kwargs: + args[each] = kwargs[each] + for each in self.__other_kwargs__: + args[each] = self.__other_kwargs__[each] + return getattr(conf_helps, method_name)(**args) + + return V2LayerImpl diff --git a/python/paddle/v2/layer.py b/python/paddle/v2/layer.py index 19f3c2f998d83c8841535a967c1d6335f13da886..67111f1315fbb0f55c1db0f6fe89fc988c8d83f6 100644 --- a/python/paddle/v2/layer.py +++ b/python/paddle/v2/layer.py @@ -65,10 +65,7 @@ to be in a Python function but could be anywhere. Also, the creation of a protobuf message is hidden in the invocation of paddle.v2.parameters.create, no longer exposed to users. """ - -import collections -import inspect - +from config_base import Layer, __convert_to_v2__ import paddle.trainer_config_helpers as conf_helps from paddle.trainer_config_helpers.config_parser_utils import \ parse_network_config as __parse__ @@ -107,74 +104,6 @@ def parse_network(*outputs): return __parse__(__real_func__) -class Layer(object): - def __init__(self, name=None, parent_layers=None): - assert isinstance(parent_layers, dict) - self.name = name - self.__parent_layers__ = parent_layers - - def to_proto(self, context): - """ - function to set proto attribute - """ - kwargs = dict() - for layer_name in self.__parent_layers__: - if not isinstance(self.__parent_layers__[layer_name], - collections.Sequence): - v1_layer = self.__parent_layers__[layer_name].to_proto( - context=context) - else: - v1_layer = map(lambda x: x.to_proto(context=context), - self.__parent_layers__[layer_name]) - kwargs[layer_name] = v1_layer - - if self.name is None: - return self.to_proto_impl(**kwargs) - elif self.name not in context: - context[self.name] = self.to_proto_impl(**kwargs) - - return context[self.name] - - def to_proto_impl(self, **kwargs): - raise NotImplementedError() - - -def __convert_to_v2__(method_name, parent_names, is_default_name=True): - if is_default_name: - wrapper = wrap_name_default(name_prefix=method_name) - else: - wrapper = None - - class V2LayerImpl(Layer): - def __init__(self, **kwargs): - parent_layers = dict() - other_kwargs = dict() - for pname in parent_names: - if kwargs.has_key(pname): - parent_layers[pname] = kwargs[pname] - - for key in kwargs.keys(): - if key not in parent_names: - other_kwargs[key] = kwargs[key] - - name = kwargs.get('name', None) - super(V2LayerImpl, self).__init__(name, parent_layers) - self.__other_kwargs__ = other_kwargs - - if wrapper is not None: - __init__ = wrapper(__init__) - - def to_proto_impl(self, **kwargs): - args = dict() - for each in kwargs: - args[each] = kwargs[each] - for each in self.__other_kwargs__: - args[each] = self.__other_kwargs__[each] - return getattr(conf_helps, method_name)(**args) - - return V2LayerImpl - - """ Some layer may need some special config, and can not use __convert_to_v2__ to convert. So we also need to implement some special LayerV2. diff --git a/python/paddle/v2/networks.py b/python/paddle/v2/networks.py new file mode 100644 index 0000000000000000000000000000000000000000..74d91593d8551bc1592a78efb704ab3b89f0e0d9 --- /dev/null +++ b/python/paddle/v2/networks.py @@ -0,0 +1,45 @@ +# 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. + +import paddle.trainer_config_helpers.networks as conf_nw +import inspect +from config_base import __convert_to_v2__ + +__all__ = [] + + +def __initialize__(): + for each_subnetwork in conf_nw.__all__: + if each_subnetwork in ['inputs', 'outputs']: + continue + func = getattr(conf_nw, each_subnetwork) + if hasattr(func, 'argspec'): + argspec = func.argspec + else: + argspec = inspect.getargspec(func) + if each_subnetwork == 'simple_attention': + parents = ['encoded_sequence', 'encoded_proj', 'decoder_state'] + else: + parents = filter(lambda x: x.startswith('input'), argspec.args) + assert len(parents) != 0, each_subnetwork + v2_subnet = __convert_to_v2__( + each_subnetwork, + parent_names=parents, + is_default_name='name' in argspec.args) + globals()[each_subnetwork] = v2_subnet + global __all__ + __all__.append(each_subnetwork) + + +__initialize__() diff --git a/python/paddle/v2/tests/test_layer.py b/python/paddle/v2/tests/test_layer.py index b138ddbbe6c0a431393fef165b4eaebf7bfa81e4..0055679a91801a2f9b6432797665ec17caf3beb1 100644 --- a/python/paddle/v2/tests/test_layer.py +++ b/python/paddle/v2/tests/test_layer.py @@ -18,6 +18,7 @@ import paddle.v2.attr as attr import paddle.v2.data_type as data_type import paddle.v2.layer as layer import paddle.v2.pooling as pooling +import paddle.v2.networks as networks pixel = layer.data(name='pixel', type=data_type.dense_vector(128)) label = layer.data(name='label', type=data_type.integer_value(10)) @@ -251,5 +252,13 @@ class ProjOpTest(unittest.TestCase): print layer.parse_network(conv1) +class NetworkTests(unittest.TestCase): + def test_vgg(self): + img = layer.data(name='pixel', type=data_type.dense_vector(784)) + vgg_out = networks.small_vgg( + input_image=img, num_channels=1, num_classes=2) + print layer.parse_network(vgg_out) + + if __name__ == '__main__': unittest.main()