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)
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)