def fully_connected(inputs,
                    activation,
                    num_outputs,
                    out_caps_shape,
                    routing_method='EMRouting',
                    reuse=None):
    '''A capsule fully connected layer.
    Args:
        inputs: A tensor with shape [batch_size, num_inputs] + in_caps_shape.
        activation: [batch_size, num_inputs]
        num_outputs: Integer, the number of output capsules in the layer.
        out_caps_shape: A list with two elements, pose shape of output capsules.
    Returns:
        pose: [batch_size, num_outputs] + out_caps_shape
        activation: [batch_size, num_outputs]
    '''
    in_pose_shape = inputs.get_shape().as_list()
    # it confuses me a lot. please refer to https://blog.csdn.net/loseinvain/article/details/78762739
    # in_pose_shape=tf.shape(inputs) # dynamic shape, i can not get its shape without feed_dict
    # num_inputs=in_pose_shape.eval()[1]
    num_inputs = 24 * 24 * 32  # 18432
    # with tf.Session() as sess:
    #     num_outputs=sess.run(tf.shape(inputs))
    # num_inputs=tf.unstack(tf.shape(num_outputs))[1]
    batch_size = in_pose_shape[0]
    T_size = get_transformation_matrix_shape(in_pose_shape[-2:],
                                             out_caps_shape)
    T_shape = [1, num_inputs, num_outputs] + T_size
    # T_matrix = tf.get_variable('transformation_matrix', shape=T_shape)
    T_matrix = tf.get_variable(name='transformation_matrix', shape=T_shape)
    T_matrix = tf.tile(T_matrix, [batch_size, 1, 1, 1, 1])
    inputs = tf.tile(tf.expand_dims(inputs, axis=2), [1, 1, num_outputs, 1, 1])
    with tf.variable_scope('transformation'):
        # vote: [batch_size, num_inputs, num_outputs] + out_caps_shape
        vote = tf.matmul(T_matrix, inputs)
    with tf.variable_scope('routing'):
        if routing_method == 'EMRouting':
            shape = [-1] + activation.get_shape().as_list()[1:] + [1, 1]
            activation = tf.reshape(activation, shape=shape)
            vote = tf.reshape(vote,
                              shape=[batch_size, num_inputs, num_outputs, -1])
            pose, activation = routing(vote, activation, num_outputs,
                                       out_caps_shape, routing_method)
            pose = tf.reshape(pose,
                              shape=[batch_size, num_outputs] + out_caps_shape)
            activation = tf.reshape(activation, shape=[batch_size, -1])
        elif routing_method == 'DynamicRouting':
            pose, _ = routing(vote,
                              activation,
                              num_outputs=num_outputs,
                              out_caps_shape=out_caps_shape,
                              method=routing_method)
            pose = tf.squeeze(pose, axis=1)
            activation = tf.squeeze(euclidean_norm(pose))
    return (pose, activation)
示例#2
0
文件: layers.py 项目: 2018OCR/OCR
def fully_connected(inputs,
                    activation,
                    num_outputs,
                    out_caps_shape,
                    routing_method='DynamicRouting',
                    reuse=None):
    """
    A capsule fully connected layer.
    Args:
        inputs: A tensor with shape [batch_size, num_inputs] + in_caps_shape.
        activation: [batch_size, num_inputs]
        num_outputs: Integer, the number of output capsules in the layer.
        out_caps_shape: A list with two elements, pose shape of output capsules.
    Returns:
        pose: [batch_size, num_outputs] + out_caps_shape
        activation: [batch_size, num_outputs]
    """
    in_pose_shape = inputs.get_shape().as_list()
    num_inputs = in_pose_shape[1]
    batch_size = in_pose_shape[0]
    T_size = get_transformation_matrix_shape(in_pose_shape[-2:],
                                             out_caps_shape)
    T_shape = [1, num_inputs, num_outputs] + T_size
    T_matrix = tf.get_variable("transformation_matrix", shape=T_shape)
    T_matrix = tf.tile(T_matrix, [batch_size, 1, 1, 1, 1])
    inputs = tf.tile(tf.expand_dims(inputs, axis=2), [1, 1, num_outputs, 1, 1])
    with tf.variable_scope('transformation'):
        # vote: [batch_size, num_inputs, num_outputs] + out_caps_shape
        vote = tf.matmul(T_matrix, inputs)
    with tf.variable_scope('routing'):
        if routing_method == 'EMRouting':
            activation = tf.reshape(activation,
                                    shape=activation.get_shape().as_list() +
                                    [1, 1])
            vote = tf.reshape(vote,
                              shape=[batch_size, num_inputs, num_outputs, -1])
            pose, activation = routing(vote, activation, num_outputs,
                                       out_caps_shape, routing_method)
            pose = tf.reshape(pose,
                              shape=[batch_size, num_outputs] + out_caps_shape)
            activation = tf.reshape(activation, shape=[batch_size, -1])
        elif routing_method == 'DynamicRouting':
            pose, _ = routing(vote,
                              activation,
                              num_outputs=num_outputs,
                              out_caps_shape=out_caps_shape,
                              method=routing_method)
            pose = tf.squeeze(pose, axis=1)
            activation = tf.squeeze(euclidean_norm(pose))
    return pose, activation
def primaryCaps(input,
                filters,
                kernel_size,
                strides,
                out_caps_shape,
                method=None,
                regularizer=None):
    '''PrimaryCaps layer
    Args:
        input: [batch_size, in_height, in_width, in_channels].
        filters: Integer, the dimensionality of the output space.
        kernel_size: ...
        strides: ...
        out_caps_shape: ...
        method: the method of calculating probability of entity existence(logistic, norm, None)
    Returns:
        pose: [batch_size, out_height, out_width, filters] + out_caps_shape
        activation: [batch_size, out_height, out_width, filters]
    '''
    # pose matrix
    pose_size = reduce(lambda x, y: x * y, out_caps_shape)
    pose = tf.layers.conv2d(input,
                            filters * pose_size,
                            kernel_size=kernel_size,
                            strides=strides,
                            activation=None,
                            activity_regularizer=regularizer)
    pose_shape = [-1] + pose.get_shape().as_list()[1:3] + [filters
                                                           ] + out_caps_shape
    pose = tf.reshape(pose, shape=pose_shape)

    if method == 'logistic':
        # logistic activation unit
        activation = tf.layers.conv2d(input,
                                      filters,
                                      kernel_size=kernel_size,
                                      strides=strides,
                                      activation=tf.nn.sigmoid,
                                      activity_regularizer=regularizer)
    elif method == 'norm':
        activation = euclidean_norm(pose)
    else:
        activation = None

    return (pose, activation)