{"action":"opened","issue":{"url":"https://api.github.com/repos/fchollet/keras/issues/883","labels_url":"https://api.github.com/repos/fchollet/keras/issues/883/labels{/name}","comments_url":"https://api.github.com/repos/fchollet/keras/issues/883/comments","events_url":"https://api.github.com/repos/fchollet/keras/issues/883/events","html_url":"https://github.com/fchollet/keras/issues/883","id":113057075,"number":883,"title":"Making Keras flexible without too many specific edge cases","user":{"login":"EderSantana","id":3902480,"avatar_url":"https://avatars.githubusercontent.com/u/3902480?v=3","gravatar_id":"","url":"https://api.github.com/users/EderSantana","html_url":"https://github.com/EderSantana","followers_url":"https://api.github.com/users/EderSantana/followers","following_url":"https://api.github.com/users/EderSantana/following{/other_user}","gists_url":"https://api.github.com/users/EderSantana/gists{/gist_id}","starred_url":"https://api.github.com/users/EderSantana/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EderSantana/subscriptions","organizations_url":"https://api.github.com/users/EderSantana/orgs","repos_url":"https://api.github.com/users/EderSantana/repos","events_url":"https://api.github.com/users/EderSantana/events{/privacy}","received_events_url":"https://api.github.com/users/EderSantana/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-10-23T16:43:35Z","updated_at":"2015-10-23T16:43:35Z","closed_at":null,"body":"As we approach the 3000 stars and attract several users more and more edge cases are being added to the main repo. As this is awesome to make the library grow fast and help as much people as possible, it makes me wonder if we can continue to scale at that speed. \r\n\r\nTo make sure Keras can continue to grow fast and helping as much as possible without breaking things, I'd like to propose some functional options, the first two things I thought about was a `LambdaLayer` and `LambdaDataset`. I'm already using `LambdaLayer` in Seya pretty successfully and it looks like this:\r\n```python\r\nclass Lambda(MaskedLayer):\r\n    def __init__(self, func, output_shape, ndim=2):\r\n        super(Lambda, self).__init__()\r\n        self.input = ndim_tensor(ndim)\r\n        self.func = func\r\n        self._output_shape = output_shape\r\n\r\n    def get_output(self, train=False):\r\n        X = self.get_input(train)\r\n        return self.func(X)\r\n\r\n    @property\r\n    def output_shape(self):\r\n        return self._output_shape\r\n```\r\n\r\nAs an example of how powerful this is, we can bootstrap all `Merge` modes with a combination of `merge_mode=\"join\"` and a `LambdaLayer`. For example, say we want to merge things with a kernel projection:\r\n\r\n```python\r\ndef kproj(x):\r\n    # x[0] is layer1\r\n    # x[1] is layer2\r\n    return (T.dot(x[0], x[1].T) + 1)**3\r\n\r\nmodel.add_node(Lambda(kproj, output_shape=(None, out_dim)), inputs=['layer1', 'layer2'], merge_mode='join')\r\n```\r\n\r\nWe did it pretty quickly and nothing new had to be added to the main repo, although now we are merging `layer1` and `layer2` in a huge dimensional space and making Jordan happy.\r\n\r\nThe same flexibility could be added to datasets and I'm sure you guys have ideas of how to do that elsewhere. This is the same philosophy as the one behind our beloved `Callbacks`. Let me know what you think."}}