Esempio n. 1
0
def F(args):
    if args and args[0] in act_funcs:
        activation = act_funcs[args[0]]
        args = args[1:]
    else:
        activation = 'rel'
    size = args[0]
    assert isinstance(size, int), "{}".format(size)
    return layers.FullyConnected(size, activation=activation)
Esempio n. 2
0
def get_in_out_layers(task_type, in_shape, out_shape, data_name='default',
                      targets_name='targets', projection_name=None,
                      outlayer_name=None, mask_name=None, use_conv=None):
    """Prepare input and output layers for building a network.

    This is a helper function for quickly building networks.
    It returns an ``Input`` layer and a projection layer which is a
    ``FullyConnected`` or ``Convolution2D`` layer depending on the shape of the
    targets. It creates a mask layer if a mask name is provided, and connects
    it appropriately.

    An appropriate layer to compute the matching loss is connected, depending
    on the task_type:

    classification:
    The projection layer is connected to a SoftmaxCE layer, which receives
    targets from the input layer. This is suitable for a single-label
    classification task.

    multi-label:
    The projection layer is connected to a SigmoidCE layer, which receives
    targets from the input layer. This is suitable for a multi-label
    classification task.

    regression:
    The projection layer is connected to a SquaredError layer, which
    receives targets from the input layer. This is suitable for least squares
    regression.

    Note:
        The projection layer uses parameters, so it should be initialized after
        network creation. Check argument descriptions to understand how it will
        be named.

    Example:
        >>> from brainstorm import tools, Network, layers
        >>> inp, out = tools.get_in_out_layers('classification', 784, 10)
        >>> net = Network.from_layer(inp >> layers.FullyConnected(1000) >> out)
    Args:
        task_type (str): one of ['classification', 'regression', 'multi-label']
        in_shape (int or tuple[int]): Shape of the input data.
        out_shape (int or tuple[int]): Shape of the network output.
        data_name (Optional[str]):
            Name of the input data which will be provided by a data iterator.
            Defaults to 'default'.
        targets_name (Optional[str]):
            Name of the ground-truth target data which will be provided by a
            data iterator. Defaults to 'targets'.
        projection_name (Optional[str]):
            Name for the projection layer which connects to the softmax layer.
            If unspecified, will be set to ``outlayer_name`` + '_projection' if
            ``outlayer_name`` is provided, and 'Output_projection' otherwise.
        outlayer_name (Optional[str]):
            Name for the output layer. If unspecified, named to 'Output'.
        mask_name (Optional[str]):
            Name of the mask data which will be provided by a data iterator.
            Defaults to None.

            The mask is needed if error should be injected
            only at certain time steps (for sequential data).
        use_conv (Optional[bool]):
            Specify whether the projection layer should be convolutional.
            If true the projection layer will use 1x1 convolutions otherwise
            it will be fully connected.
            Default is to autodetect this based on the output shape.
    Returns:
        tuple[Layer]
    """
    in_shape = (in_shape,) if isinstance(in_shape, int) else in_shape
    out_shape = (out_shape,) if isinstance(out_shape, int) else out_shape
    outlayer_name = outlayer_name or 'Output'
    projection_name = projection_name or outlayer_name + '_projection'

    if len(out_shape) == 1 or use_conv is False:
        proj_layer = layers.FullyConnected(out_shape, activation='linear',
                                           name=projection_name)
    elif len(out_shape) == 3 or use_conv is True:
        proj_layer = layers.Convolution2D(out_shape[-1], (1, 1),
                                          activation='linear',
                                          name=projection_name)
    else:
        raise ValueError('Unsupported output length {}'.format(len(out_shape)))

    if task_type == 'classification':
        out_layer = layers.SoftmaxCE(name=outlayer_name)
    elif task_type == 'multi-label':
        out_layer = layers.SigmoidCE(name=outlayer_name)
    elif task_type == 'regression':
        out_layer = layers.SquaredError(name=outlayer_name)
    else:
        raise ValueError('Unknown task type {}'.format(task_type))

    proj_layer >> 'default' - out_layer

    if task_type == 'classification':
        t_shape = out_shape[:-1] + (1,)
    else:
        t_shape = out_shape
    if mask_name is None:
        inp_layer = layers.Input(
            out_shapes={data_name: ('T', 'B') + in_shape,
                        targets_name: ('T', 'B') + t_shape})
        inp_layer - targets_name >> 'targets' - out_layer
        out_layer - 'loss' >> layers.Loss()
    else:
        inp_layer = layers.Input(
            out_shapes={data_name: ('T', 'B') + in_shape,
                        targets_name: ('T', 'B') + t_shape,
                        mask_name: ('T', 'B', 1)})
        mask_layer = layers.Mask()
        inp_layer - targets_name >> 'targets' - out_layer
        out_layer - 'loss' >> mask_layer >> layers.Loss()
        inp_layer - mask_name >> 'mask' - mask_layer

    return inp_layer, proj_layer