Exemplo n.º 1
0
def data_generator(x, y, batch_size):
    x = to_list(x)
    y = to_list(y)
    max_batch_index = len(x[0]) // batch_size
    i = 0
    while 1:
        x_batch = [array[i * batch_size:(i + 1) * batch_size] for array in x]
        x_batch = unpack_singleton(x_batch)

        y_batch = [array[i * batch_size:(i + 1) * batch_size] for array in y]
        y_batch = unpack_singleton(y_batch)
        yield x_batch, y_batch
        i += 1
        i = i % max_batch_index
Exemplo n.º 2
0
def data_generator(x, y, batch_size):
    x = to_list(x)
    y = to_list(y)
    max_batch_index = len(x[0]) // batch_size
    i = 0
    while 1:
        x_batch = [array[i * batch_size: (i + 1) * batch_size] for array in x]
        x_batch = unpack_singleton(x_batch)

        y_batch = [array[i * batch_size: (i + 1) * batch_size] for array in y]
        y_batch = unpack_singleton(y_batch)
        yield x_batch, y_batch
        i += 1
        i = i % max_batch_index
Exemplo n.º 3
0
 def avg_loss(losses, batch_sizes):
     averages = []
     for i in range(len(losses[0])):
         if i not in stateful_metric_indices:
             averages.append(
                 np.average([out[i] for out in losses],
                            weights=batch_sizes))
         else:
             averages.append(np.float64(losses[-1][i]))
     return unpack_singleton(averages)
Exemplo n.º 4
0
def _collect_input_shape(input_tensors):
    """Collects the output shape(s) of a list of Keras tensors.

    # Arguments
        input_tensors: list of input tensors (or single input tensor).

    # Returns
        List of shape tuples (or single tuple), one tuple per input.
    """
    input_tensors = to_list(input_tensors)
    shapes = []
    for x in input_tensors:
        try:
            shapes.append(K.int_shape(x))
        except TypeError:
            shapes.append(None)
    return unpack_singleton(shapes)
Exemplo n.º 5
0
    def test_on_batch_custom(self,
                             x,
                             y,
                             sample_weight=None,
                             class_weight=None):
        """
            only diff to `test_on_batch`:
                extra `class_weight`
        """
        x, y, sample_weights = self._standardize_user_data(
            x, y, sample_weight=sample_weight, class_weight=class_weight)

        if self._uses_dynamic_learning_phase():
            ins = x + y + sample_weights + [0.]
        else:
            ins = x + y + sample_weights
        self._make_test_function()
        outputs = self.test_function(ins)
        return unpack_singleton(outputs)
Exemplo n.º 6
0
def _collect_previous_mask(input_tensors):
    """Retrieves the output mask(s) of the previous node.

    # Arguments
        input_tensors: A tensor or list of tensors.

    # Returns
        A mask tensor or list of mask tensors.
    """
    input_tensors = to_list(input_tensors)
    masks = []
    for x in input_tensors:
        if hasattr(x, '_keras_history'):
            inbound_layer, node_index, tensor_index = x._keras_history
            node = inbound_layer._inbound_nodes[node_index]
            mask = node.output_masks[tensor_index]
            masks.append(mask)
        else:
            masks.append(None)
    return unpack_singleton(masks)    
Exemplo n.º 7
0
    def call(self, inputs):
        if isinstance(inputs, GraphWrapper):
            nodes = inputs.nodes
            adjacency = inputs.adjacency
        else:
            raise ValueError()

        new_nodes = Dropout(rate=self.nodes_rate,
                            noise_shape=self.nodes_noise_shape,
                            seed=self.nodes_seed)(nodes)

        new_adj = to_list(adjacency)
        if self.use_adjacency_dropout:
            new_adj = [
                Dropout(rate=self.adjacency_rate,
                        noise_shape=self.adjacency_noise_shape,
                        seed=self.nodes_seed)(a) for a in new_adj
            ]
            new_adj = unpack_singleton(new_adj)
        else:
            new_adj = adjacency

        return self.make_output_graph(adjacency=new_adj, nodes=new_nodes)
Exemplo n.º 8
0
def predict_loop(model, f, ins, batch_size=32, verbose=0, steps=None):
    """Abstract method to loop over some data in batches.

    # Arguments
        model: Keras model instance.
        f: Keras function returning a list of tensors.
        ins: list of tensors to be fed to `f`.
        batch_size: integer batch size.
        verbose: verbosity mode.
        steps: Total number of steps (batches of samples)
            before declaring `predict_loop` finished.
            Ignored with the default value of `None`.

    # Returns
        Array of predictions (if the model has a single output)
        or list of arrays of predictions
        (if the model has multiple outputs).
    """
    num_samples = check_num_samples(ins,
                                    batch_size=batch_size,
                                    steps=steps,
                                    steps_name='steps')
    if verbose == 1:
        if steps is not None:
            progbar = Progbar(target=steps)
        else:
            progbar = Progbar(target=num_samples)

    indices_for_conversion_to_dense = []
    is_sparse = False
    for i in range(len(model._feed_inputs)):
        if issparse(ins[i]) and not K.is_sparse(model._feed_inputs[i]):
            indices_for_conversion_to_dense.append(i)
        elif issparse(ins[i]) and K.is_sparse(model._feed_inputs[i]):
            is_sparse = True
    if steps is not None:
        # Step-based predictions.
        # Since we do not know how many samples
        # we will see, we cannot pre-allocate
        # the returned Numpy arrays.
        # Instead, we store one array per batch seen
        # and concatenate them upon returning.
        unconcatenated_outs = []
        for step in range(steps):
            batch_outs = f(ins)
            batch_outs = to_list(batch_outs)
            if step == 0:
                for batch_out in batch_outs:
                    unconcatenated_outs.append([])
            for i, batch_out in enumerate(batch_outs):
                unconcatenated_outs[i].append(batch_out)
            if verbose == 1:
                progbar.update(step + 1)
        if is_sparse:
            if len(unconcatenated_outs) == 1:
                return vstack(unconcatenated_outs[0], 'csr')
            return [
                vstack(unconcatenated_outs[i], 'csr')
                for i in range(len(unconcatenated_outs))
            ]
        if len(unconcatenated_outs) == 1:
            return np.concatenate(unconcatenated_outs[0], axis=0)
        return [
            np.concatenate(unconcatenated_outs[i], axis=0)
            for i in range(len(unconcatenated_outs))
        ]
    else:
        # Sample-based predictions.
        outs = []
        batches = make_batches(num_samples, batch_size)
        index_array = np.arange(num_samples)
        for batch_index, (batch_start, batch_end) in enumerate(batches):
            batch_ids = index_array[batch_start:batch_end]
            if ins and isinstance(ins[-1], float):
                # Do not slice the training phase flag.
                ins_batch = slice_arrays(ins[:-1], batch_ids) + [ins[-1]]
            else:
                ins_batch = slice_arrays(ins, batch_ids)
            for i in indices_for_conversion_to_dense:
                ins_batch[i] = ins_batch[i].toarray()

            batch_outs = f(ins_batch)
            batch_outs = to_list(batch_outs)
            if batch_index == 0:
                # Pre-allocate the results arrays.
                for batch_out in batch_outs:
                    shape = (num_samples, ) + batch_out.shape[1:]
                    if is_sparse:
                        outs.append(lil_matrix(shape, dtype=batch_out.dtype))
                    else:
                        outs.append(np.zeros(shape, dtype=batch_out.dtype))
            for i, batch_out in enumerate(batch_outs):
                outs[i][batch_start:batch_end] = batch_out
            if verbose == 1:
                progbar.update(batch_end)
        if is_sparse:
            return unpack_singleton(list(map(lambda oo: oo.tocsr(), outs)))
        return unpack_singleton(outs)
Exemplo n.º 9
0
    def evaluate_generator_custom(model,
                                  generator,
                                  steps=None,
                                  max_queue_size=10,
                                  class_weight=None,
                                  workers=1,
                                  use_multiprocessing=False,
                                  verbose=0):
        """See docstring for `Model.evaluate_generator`."""
        model._make_test_function()

        stateful_metric_indices = []
        if hasattr(model, 'metrics'):
            for m in model.stateful_metric_functions:
                m.reset_states()
            stateful_metric_indices = [
                i for i, name in enumerate(model.metrics_names)
                if str(name) in model.stateful_metric_names
            ]
        else:
            stateful_metric_indices = []

        steps_done = 0
        wait_time = 0.01
        outs_per_batch = []
        batch_sizes = []
        is_sequence = isinstance(generator, Sequence)
        if not is_sequence and use_multiprocessing and workers > 1:
            warnings.warn(
                UserWarning('Using a generator with `use_multiprocessing=True`'
                            ' and multiple workers may duplicate your data.'
                            ' Please consider using the`keras.utils.Sequence'
                            ' class.'))
        if steps is None:
            if is_sequence:
                steps = len(generator)
            else:
                raise ValueError('`steps=None` is only valid for a generator'
                                 ' based on the `keras.utils.Sequence` class.'
                                 ' Please specify `steps` or use the'
                                 ' `keras.utils.Sequence` class.')
        enqueuer = None

        try:
            if workers > 0:
                if is_sequence:
                    enqueuer = OrderedEnqueuer(
                        generator, use_multiprocessing=use_multiprocessing)
                else:
                    enqueuer = GeneratorEnqueuer(
                        generator,
                        use_multiprocessing=use_multiprocessing,
                        wait_time=wait_time)
                enqueuer.start(workers=workers, max_queue_size=max_queue_size)
                output_generator = enqueuer.get()
            else:
                if is_sequence:
                    output_generator = iter(generator)
                else:
                    output_generator = generator

            if verbose == 1:
                progbar = Progbar(target=steps)

            while steps_done < steps:
                generator_output = next(output_generator)
                if not hasattr(generator_output, '__len__'):
                    raise ValueError('Output of generator should be a tuple '
                                     '(x, y, sample_weight) '
                                     'or (x, y). Found: ' +
                                     str(generator_output))
                if len(generator_output) == 2:
                    x, y = generator_output
                    sample_weight = None
                elif len(generator_output) == 3:
                    x, y, sample_weight = generator_output
                else:
                    raise ValueError('Output of generator should be a tuple '
                                     '(x, y, sample_weight) '
                                     'or (x, y). Found: ' +
                                     str(generator_output))

                # Ken: to weight validation examples, testing must re-weight the examples
                ###############################################################
                outs = model.test_on_batch_custom(x,
                                                  y,
                                                  sample_weight=sample_weight,
                                                  class_weight=class_weight)
                ###############################################################

                outs = to_list(outs)
                outs_per_batch.append(outs)

                if x is None or len(x) == 0:
                    # Handle data tensors support when no input given
                    # step-size = 1 for data tensors
                    batch_size = 1
                elif isinstance(x, list):
                    batch_size = x[0].shape[0]
                elif isinstance(x, dict):
                    batch_size = list(x.values())[0].shape[0]
                else:
                    batch_size = x.shape[0]
                if batch_size == 0:
                    raise ValueError('Received an empty batch. '
                                     'Batches should contain '
                                     'at least one item.')
                steps_done += 1
                batch_sizes.append(batch_size)
                if verbose == 1:
                    progbar.update(steps_done)

        finally:
            if enqueuer is not None:
                enqueuer.stop()

        averages = []
        for i in range(len(outs)):
            if i not in stateful_metric_indices:
                averages.append(
                    np.average([out[i] for out in outs_per_batch],
                               weights=batch_sizes))
            else:
                averages.append(np.float64(outs_per_batch[-1][i]))
        return unpack_singleton(averages)
Exemplo n.º 10
0
def run_internal_graph(model, inputs, mode, mask=None):
    """Computes output tensors for new inputs.
    # Note:
        - Expects `inputs` to be a list (potentially with 1 element).
        - Can be run on non-Keras tensors.
    # Arguments
        inputs: List of tensors
        masks: List of masks (tensors or None).
    # Returns
        Three lists: output_tensors, output_masks, output_shapes
    """
    is_training = mode == tf.estimator.ModeKeys.TRAIN
    inputs = to_list(inputs)

    if mask is None:
        masks = [None for _ in range(len(inputs))]
    else:
        masks = to_list(mask)

    cache_key = object_list_uid(inputs)
    cache_key += "_" + object_list_uid(masks)

    if cache_key in model._output_tensor_cache:
        return model._output_tensor_cache[cache_key]
    # Dictionary mapping reference tensors to tuples
    # (computed tensor, compute mask)
    # we assume a 1:1 mapping from tensor to mask
    # TODO: raise exception when a `.compute_mask()` call
    # does not return a list the same size as `call`
    tensor_map = {}
    for x, y, mask in zip(model.inputs, inputs, masks):
        tensor_map[str(id(x))] = (y, mask)

    depth_keys = list(model._nodes_by_depth.keys())
    depth_keys.sort(reverse=True)
    for depth in depth_keys:
        nodes = model._nodes_by_depth[depth]
        for node in nodes:
            # This is always a single layer, never a list.
            layer = node.outbound_layer
            reference_input_tensors = node.input_tensors
            reference_output_tensors = node.output_tensors

            # issue: https://github.com/tensorflow/tensorflow/issues/30208
            if not isinstance(reference_input_tensors, list):
                reference_input_tensors = [reference_input_tensors]

            if not isinstance(reference_output_tensors, list):
                reference_output_tensors = [reference_output_tensors]

            # If all previous input tensors are available in tensor_map,
            # then call node.inbound_layer on them.
            computed_data = []  # List of tuples (input, mask).
            for x in reference_input_tensors:
                if str(id(x)) in tensor_map:
                    computed_data.append(tensor_map[str(id(x))])

            if len(computed_data) == len(reference_input_tensors):
                # call layer
                with K.name_scope(layer.name):
                    if node.arguments:
                        kwargs = node.arguments
                    else:
                        kwargs = {}
                    if len(computed_data) == 1:
                        computed_tensor, computed_mask = computed_data[0]
                        if has_arg(layer.call, "mask"):
                            if "mask" not in kwargs:
                                kwargs["mask"] = computed_mask
                        if has_arg(layer.call, "training"):
                            kwargs["training"] = is_training
                        output_tensors = to_list(
                            layer.call(computed_tensor, **kwargs))
                        output_masks = layer.compute_mask(
                            computed_tensor, computed_mask)
                        if output_masks is None:
                            output_masks = [None for _ in output_tensors]
                        else:
                            output_masks = to_list(output_masks)
                        computed_tensors = [computed_tensor]

                        # computed_masks might be used in the future.
                        computed_masks = [computed_mask]
                    else:
                        computed_tensors = [x[0] for x in computed_data]
                        computed_masks = [x[1] for x in computed_data]
                        if has_arg(layer.call, "mask"):
                            if "mask" not in kwargs:
                                kwargs["mask"] = computed_masks
                        output_tensors = to_list(
                            layer.call(computed_tensors, **kwargs))
                        output_masks = layer.compute_mask(
                            computed_tensors, computed_masks)
                        if output_masks is None:
                            output_masks = [None for _ in output_tensors]
                        else:
                            output_masks = to_list(output_masks)
                    # Apply activity regularizer if any:
                    if (hasattr(layer, "activity_regularizer")
                            and layer.activity_regularizer is not None):
                        with K.name_scope("activity_regularizer"):
                            regularization_losses = [
                                layer.activity_regularizer(x)
                                for x in output_tensors
                            ]
                        layer.add_loss(regularization_losses,
                                       inputs=computed_tensors)

                    if len(output_masks) != len(output_tensors):
                        raise Exception(
                            "Layers should have equal number of output tensors "
                            "and output masks. Layer " + str(layer.name) +
                            " has"
                            " " + str(len(output_tensors)) + " output tensors "
                            "and " + str(len(output_masks)) + " output masks.")
                # Update model updates and losses:
                # Keep track of updates that depend on the inputs
                # (e.g. BN updates).
                model.add_update(layer.get_updates_for(computed_tensors),
                                 inputs)
                # Keep track of unconditional updates (e.g. a counter).
                model.add_update(layer.get_updates_for(None), None)
                # Keep track of losses that depend on the inputs
                # (e.g. activity regularizers).
                model.add_loss(layer.get_losses_for(computed_tensors), inputs)
                # Keep track of unconditional losses
                # (e.g. weight regularizers).
                model.add_loss(layer.get_losses_for(None), None)

                # Update _keras_shape.
                if all([hasattr(x, "_keras_shape") for x in computed_tensors]):
                    input_shapes = unpack_singleton(
                        [x._keras_shape for x in computed_tensors])
                    shapes = to_list(layer.compute_output_shape(input_shapes))
                    uses_learning_phase = any(
                        [x._uses_learning_phase for x in computed_tensors])

                    for x, s in zip(output_tensors, shapes):
                        x._keras_shape = s
                        _u = getattr(x, "_uses_learning_phase", False)
                        x._uses_learning_phase = _u or uses_learning_phase

                # Update tensor_map.
                for x, y, mask in zip(reference_output_tensors, output_tensors,
                                      output_masks):
                    tensor_map[str(id(x))] = (y, mask)

    output_tensors = []
    output_masks = []
    output_shapes = []
    for x in model.outputs:
        assert str(id(x)) in tensor_map, "Could not compute output " + str(x)
        tensor, mask = tensor_map[str(id(x))]
        if hasattr(tensor, "_keras_shape") and output_shapes is not None:
            shape = tensor._keras_shape
            output_shapes.append(shape)
        else:
            output_shapes = None
        output_tensors.append(tensor)
        output_masks.append(mask)

    # Update cache;
    # keys are based on ids on input tensors and inputs masks.
    cache_key = object_list_uid(inputs)
    cache_key += "_" + object_list_uid(masks)

    output_tensors = unpack_singleton(output_tensors)
    model._output_tensor_cache[cache_key] = output_tensors

    output_masks = unpack_singleton(output_masks)
    model._output_mask_cache[cache_key] = output_masks

    if output_shapes is not None:
        input_shapes = [x._keras_shape for x in inputs]
        cache_key = ", ".join([str(x) for x in input_shapes])

        output_shapes = unpack_singleton(output_shapes)
        model._output_shape_cache[cache_key] = output_shapes

    return output_tensors
async def evaluate_generator(model, generator, steps=None, verbose=1):
    """See docstring for `Model.evaluate_generator`."""
    model._make_test_function()

    if hasattr(model, 'metrics'):
        for m in model.stateful_metric_functions:
            m.reset_states()
        stateful_metric_indices = [
            i for i, name in enumerate(model.metrics_names)
            if str(name) in model.stateful_metric_names
        ]
    else:
        stateful_metric_indices = []

    steps_done = 0
    outs_per_batch = []
    batch_sizes = []

    if steps is None:
        steps = len(generator)

    output_generator = generator.async_next

    if verbose == 1:
        progbar = Progbar(target=steps)

    while steps_done < steps:
        generator_output = await output_generator()

        if not hasattr(generator_output, '__len__'):
            raise ValueError('Output of generator should be a tuple '
                             '(x, y, sample_weight) '
                             'or (x, y). Found: ' + str(generator_output))
        if len(generator_output) == 2:
            x, y = generator_output
            sample_weight = None
        elif len(generator_output) == 3:
            x, y, sample_weight = generator_output
        else:
            raise ValueError('Output of generator should be a tuple '
                             '(x, y, sample_weight) '
                             'or (x, y). Found: ' + str(generator_output))
        outs = model.test_on_batch(x, y, sample_weight=sample_weight)
        outs = to_list(outs)
        outs_per_batch.append(outs)

        if x is None or len(x) == 0:
            # Handle data tensors support when no input given
            # step-size = 1 for data tensors
            batch_size = 1
        elif isinstance(x, list):
            batch_size = x[0].shape[0]
        elif isinstance(x, dict):
            batch_size = list(x.values())[0].shape[0]
        else:
            batch_size = x.shape[0]
        if batch_size == 0:
            raise ValueError('Received an empty batch. '
                             'Batches should contain '
                             'at least one item.')
        steps_done += 1
        batch_sizes.append(batch_size)
        if verbose == 1:
            progbar.update(steps_done)

    generator.on_epoch_end()
    averages = []
    for i in range(len(outs)):
        if i not in stateful_metric_indices:
            averages.append(
                np.average([out[i] for out in outs_per_batch],
                           weights=batch_sizes))
        else:
            averages.append(np.float64(outs_per_batch[-1][i]))
    return unpack_singleton(averages)
Exemplo n.º 12
0
    def __call__(self, inputs, **kwargs):
        """
        Overriding the Layer's __call__ method for graph wrappers. 
        The overriding is mostly based on the __call__ code from 
        'keras/engine/base_layer.py' for the moment, with some changes 
        to handle graphs. 
        """
        # If arguments are 'keras-style' arguments, let keras to the job
        if K.is_tensor(inputs) or (isinstance(inputs, list)
                                   and not isinstance(inputs, GraphWrapper)):
            output = super(GraphLayer, self).__call__(inputs, **kwargs)
        else:
            if isinstance(inputs,
                          list) and not isinstance(inputs, GraphWrapper):
                inputs = inputs[:]

            with K.name_scope(self.name):
                # Build the layer
                if not self.built:
                    # Check the comatibilty of inputs for each inputs (some can
                    # be GraphWrapper)
                    if isinstance(inputs, list) and not isinstance(
                            inputs, GraphWrapper):
                        for i in inputs:
                            self.assert_input_compatibility(i)

                    # Collect input shapes to build layer.
                    input_shapes = []

                    if isinstance(inputs, GraphWrapper):
                        inputs = [inputs]

                    for x_elem in inputs:
                        if hasattr(x_elem, '_keras_shape'):
                            # For a GraphWrapper, _keras_shape is a GraphShape
                            # object
                            input_shapes.append(x_elem._keras_shape)
                        elif hasattr(K, 'int_shape'):
                            input_shapes.append(K.int_shape(x_elem))
                        else:
                            raise ValueError(
                                'You tried to call layer "' + self.name +
                                '". This layer has no information'
                                ' about its expected input shape, '
                                'and thus cannot be built. '
                                'You can build it manually via: '
                                '`layer.build(batch_input_shape)`')

                    self.build(unpack_singleton(input_shapes))
                    self._built = True

                    # Load weights that were specified at layer instantiation.
                    if self._initial_weights is not None:
                        self.set_weights(self._initial_weights)

                # Raise exceptions in case the input is not compatible
                # with the input_spec set at build time.
                if isinstance(inputs,
                              list) and not isinstance(inputs, GraphWrapper):
                    for i in inputs:
                        self.assert_input_compatibility(i)

                # Handle mask propagation.
                previous_mask = _collect_previous_mask(inputs)
                user_kwargs = copy.copy(kwargs)
                if not is_all_none(previous_mask):
                    # The previous layer generated a mask.
                    if has_arg(self.call, 'mask'):
                        if 'mask' not in kwargs:
                            # If mask is explicitly passed to __call__,
                            # we should override the default mask.
                            kwargs['mask'] = previous_mask
                # Handle automatic shape inference (only useful for Theano).
                input_shape = _collect_input_shape(inputs)

                # Actually call the layer,
                # collecting output(s), mask(s), and shape(s).
                # Note that inpputs can hold graph wrappers now
                output = self.call(unpack_singleton(inputs), **kwargs)
                output_mask = self.compute_mask(inputs, previous_mask)

                # If the layer returns tensors from its inputs, unmodified,
                # we copy them to avoid loss of tensor metadata.
                # output_ls = to_list(output)
                if isinstance(output, GraphWrapper):
                    output_ls = [output]
                # Unpack wrappers
                inputs_ls = list(
                    chain.from_iterable(
                        [i for i in inputs if isinstance(i, GraphWrapper)]))
                inputs_ls += [
                    i for i in inputs if not isinstance(i, GraphWrapper)
                ]

                # Unpack adjacency and nodes
                inpadj_ls = list(
                    chain.from_iterable([
                        to_list(i.adjacency) for i in inputs
                        if isinstance(i, GraphWrapper)
                    ]))
                inpnod_ls = to_list(
                    [i.nodes for i in inputs if isinstance(i, GraphWrapper)])

                output_ls_copy = []
                adj_ls = []
                for x in output_ls:
                    if K.is_tensor(x) and x in inputs_ls:
                        x = K.identity(x)
                    # Apply adjacency-wise and node-wise identity
                    elif isinstance(x, GraphWrapper):
                        # Store changed or copy of unchanged adjacency matrices
                        adj_ls.clear()
                        for adj in to_list(x.adjacency):
                            if adj in inpadj_ls:
                                adj_ls.append(K.identity(adj))
                            else:
                                adj_ls.append(adj)
                        # Assign to output graph
                        x.adjacency = unpack_singleton(adj_ls)
                        # Store unchanged nodes
                        if x.nodes in inpnod_ls:
                            x.nodes = K.identity(x.nodes)
                    output_ls_copy.append(x)

                output = unpack_singleton(output_ls_copy)

                # Inferring the output shape is only relevant for Theano.
                if all([s is not None for s in to_list(input_shape)]):
                    output_shape = self.compute_output_shape(input_shape)
                else:
                    if isinstance(input_shape, list):
                        output_shape = [None for _ in input_shape]
                    else:
                        output_shape = None

                if (not isinstance(output_mask, (list, tuple))
                        and len(output_ls) > 1):
                    # Augment the mask to match the length of the output.
                    output_mask = [output_mask] * len(output_ls)

                # Add an inbound node to the layer, so that it keeps track
                # of the call and of all new variables created during the call.
                # This also updates the layer history of the output tensor(s).
                # If the input tensor(s) had not previous Keras history,
                # this does nothing.
                self._add_inbound_node(input_tensors=inputs_ls,
                                       output_tensors=unpack_singleton(output),
                                       input_masks=previous_mask,
                                       output_masks=output_mask,
                                       input_shapes=input_shape,
                                       output_shapes=output_shape,
                                       arguments=user_kwargs)

                # Apply activity regularizer if any:
                if (hasattr(self, 'activity_regularizer')
                        and self.activity_regularizer is not None):
                    with K.name_scope('activity_regularizer'):
                        regularization_losses = [
                            self.activity_regularizer(x)
                            for x in to_list(output)
                        ]
                    self.add_loss(regularization_losses,
                                  inputs=to_list(inputs))
        return output
Exemplo n.º 13
0
    def _sup_rnn_call(self,
                      inputs,
                      initial_state=None,
                      constants=None,
                      **kwargs):
        # reshaped_input = Reshape((inputs._shape[1],inputs._keras_shape[2]*inputs._keras_shape[3]))(inputs)
        # super(RNNStackedAttention,self).__call__(reshaped_input,**kwargs)
        if isinstance(inputs, list):
            inputs = inputs[:]
        with K.name_scope(self.name):
            # Handle laying building (weight creating, input spec locking).
            if not self.built:
                input_shapes = []
                input_shapes.append(self.shape_lstm)

                # Collect input shapes to build layer.
                #input_shapes.append(self.shape_lstm)

                for x_elem in to_list(inputs):
                    if hasattr(x_elem, '_keras_shape'):
                        input_shapes.append(x_elem._keras_shape)
                    elif hasattr(K, 'int_shape'):
                        input_shapes.append(K.int_shape(x_elem))
                    else:
                        raise ValueError('You tried to call layer "' +
                                         self.name +
                                         '". This layer has no information'
                                         ' about its expected input shape, '
                                         'and thus cannot be built. '
                                         'You can build it manually via: '
                                         '`layer.build(batch_input_shape)`')

                self.build(unpack_singleton(input_shapes))
                self.built = True

                # Load weights that were specified at layer instantiation.
                if self._initial_weights is not None:
                    self.set_weights(self._initial_weights)

            # Raise exceptions in case the input is not compatible
            # with the input_spec set at build time.
            # self.assert_input_compatibility(inputs)

            # Handle mask propagation.
            # previous_mask = _collect_previous_mask(inputs)
            user_kwargs = kwargs.copy()
            # if not is_all_none(previous_mask):
            #     # The previous layer generated a mask.
            #     if has_arg(self.call, 'mask'):
            #         if 'mask' not in kwargs:
            #             # If mask is explicitly passed to __call__,
            #             # we should override the default mask.
            #             kwargs['mask'] = previous_mask
            # # Handle automatic shape inference (only useful for Theano).
            # input_shape = _collect_input_shape(inputs)

            # Actually call the layer,
            # collecting output(s), mask(s), and shape(s).
            output = self.call(inputs, **kwargs)
            # output_mask = self.compute_mask(inputs, previous_mask)

            # If the layer returns tensors from its inputs, unmodified,
            # we copy them to avoid loss of tensor metadata.
            output_ls = to_list(output)
            inputs_ls = to_list(inputs)
            output_ls_copy = []
            for x in output_ls:
                if id(x) in [id(i) for i in inputs_ls]:
                    x = K.identity(x)
                output_ls_copy.append(x)
            output = unpack_singleton(output_ls_copy)

            input_shape = _collect_input_shape(inputs)
            input_shape[0] = self.shape_lstm
            # Inferring the output shape is only relevant for Theano.
            if all([s is not None for s in to_list(input_shape)]):
                output_shape = self.compute_output_shape(input_shape)
            else:
                if isinstance(input_shape, list):
                    output_shape = [None for _ in input_shape]
                else:
                    output_shape = None
            #
            # if (not isinstance(output_mask, (list, tuple)) and
            #         len(output_ls) > 1):
            #     # Augment the mask to match the length of the output.
            #     output_mask = [output_mask] * len(output_ls)

            # Add an inbound node to the layer, so that it keeps track
            # of the call and of all new variables created during the call.
            # This also updates the layer history of the output tensor(s).
            # If the input tensor(s) had not previous Keras history,
            # this does nothing.
            previous_mask = None
            output_mask = None

            self._add_inbound_node(input_tensors=inputs,
                                   output_tensors=output,
                                   input_masks=previous_mask,
                                   output_masks=output_mask,
                                   input_shapes=input_shape,
                                   output_shapes=output_shape,
                                   arguments=user_kwargs)

            # Apply activity regularizer if any:
            if (hasattr(self, 'activity_regularizer')
                    and self.activity_regularizer is not None):
                with K.name_scope('activity_regularizer'):
                    regularization_losses = [
                        self.activity_regularizer(x) for x in to_list(output)
                    ]
                self.add_loss(regularization_losses, inputs=to_list(inputs))
        return output