Exemplo n.º 1
0
def neural_graph_fingerprints(radius, fingerprint_len, feature_size):
    input_graph = layers.Input(shape=(None, None), name="input_graph")
    input_layer_rep = layers.Input(shape=(None, feature_size),
                                   name="input_layer_rep")
    graph = layers.Lambda(lambda x: k.temporal_padding(x, (0, 80)))(
        input_graph)
    layer_rep = layers.Lambda(lambda x: k.temporal_padding(x, (0, 80)))(
        input_layer_rep)

    all_outputs = []
    for i in range(1, radius):
        layer_rep, layer_fp = fingerprint_model_layer(graph, layer_rep,
                                                      fingerprint_len,
                                                      feature_size)
        layer_fp = layers.Lambda(lambda x: k.sum(x, axis=1))(layer_fp)
        all_outputs.append(layer_fp)

    #final_fp = layers.merge(all_outputs, mode='sum', name="final_merge")
    final_fp = layers.Lambda(lambda x: k.sum(x, axis=1))(all_outputs)

    neural_fp = models.Model(inputs=[input_graph, input_layer_rep],
                             outputs=final_fp)
    neural_fp.compile(optimizer=optimizers.Adam(),
                      loss='categorical_crossentropy')
    return neural_fp
Exemplo n.º 2
0
 def call(self, inputs):
     if isinstance(inputs, list):
         x, x_mask = inputs
     else:
         x, x_mask = inputs, None
     seq_dim = K.int_shape(x)[-1]
     # 补足长度,保证可以reshape
     seq_len = K.shape(x)[1]
     pad_len = self.rate - seq_len % self.rate
     x = K.temporal_padding(x, (0, pad_len))
     if x_mask is not None:
         x_mask = K.temporal_padding(x_mask, (0, pad_len))
     new_seq_len = K.shape(x)[1]
     # 变换shape
     x = K.reshape(x, (-1, new_seq_len // self.rate, self.rate, seq_dim))
     x = K.permute_dimensions(x, (0, 2, 1, 3))
     x = K.reshape(x, (-1, new_seq_len // self.rate, seq_dim))
     if x_mask is not None:
         x_mask = K.reshape(x_mask,
                            (-1, new_seq_len // self.rate, self.rate, 1))
         x_mask = K.permute_dimensions(x_mask, (0, 2, 1, 3))
         x_mask = K.reshape(x_mask, (-1, new_seq_len // self.rate, 1))
     # 做attention
     if x_mask is not None:
         x = self.reuse(self.attention, [x, x, x, x_mask, x_mask])
     else:
         x = self.reuse(self.attention, [x, x, x])
     # 恢复shape
     x = K.reshape(x,
                   (-1, self.rate, new_seq_len // self.rate, self.out_dim))
     x = K.permute_dimensions(x, (0, 2, 1, 3))
     x = K.reshape(x, (-1, new_seq_len, self.out_dim))
     x = x[:, :-pad_len]
     return x
Exemplo n.º 3
0
 def loss(y_true, y_pred):
     sent_rels = K.expand_dims(_sent_rels, axis=-1)  # (*, doc_maxsentlen, 1)
     virtual_pred1 = K.temporal_padding(y_pred, [1, 0])  # (*, doc_maxsentlen+1, 1)
     virtual_pred2 = K.temporal_padding(y_pred, [0, 1])  # (*, doc_maxsentlen+1, 1)
     virtual_pred_diff = virtual_pred1 - virtual_pred2  # (*, doc_maxsentlen+1, 1)
     virtual_pred_diff = virtual_pred_diff[:, :-1, :]  # (*, doc_maxsentlen, 1)
     virtual_pred_diff = K.squeeze(virtual_pred_diff, axis=-1)  # (*, doc_maxsentlen)
     virtual_pred_diff = K.square(virtual_pred_diff)  # (*, doc_maxsentlen)
     sent_rels = K.squeeze(sent_rels, axis=-1)  # (*, doc_maxsentlen)
     loss_sum = K.batch_dot(K.square(virtual_pred_diff), sent_rels, axes=(1, 1))  # (*, 1)
     loss_value = K.mean(K.squeeze(loss_sum, axis=-1))
     return loss_value
Exemplo n.º 4
0
 def call(self, inputs):
     # For each caption, remove the last word vector and append a zero-vector to the beginning.
     _inputs = K.temporal_padding(inputs[:, 0:-1, :], padding=(1, 0))
     # _inputs[:, 0, idxBOS] += 1.
     scatter = K.tf.scatter_nd([[0, self.idxBOS]], K.tf.constant([1.]),
                               K.tf.constant(_inputs.shape.as_list()[1:]))
     return _inputs + scatter
Exemplo n.º 5
0
    def call(self, x, mask=None):
        #i_ shape = [none, 600, 300) t_ shape = [4,300]
        x_, t_ = x
        t_ = K.transpose(t_)
        g = K.dot(x_, t_)

        normal_g = K.dot(K.l2_normalize(x_, axis=-1), K.l2_normalize(t_))

        g /= normal_g
        print(g.shape)
        #g = K.exp(g)
        #g /= K.cast(K.sum(g, axis=-1, keepdims=True)+K.epsilon(), K.floatx())
        g_padding = K.temporal_padding(g, padding=(self.r, self.r))
        print(g_padding.shape)
        g_padding = tf.transpose(g_padding, perm=[0, 2, 1])
        gw = []
        g_array = tf.unstack(g_padding, axis=-1)
        for i in range(self.r, g_padding.shape[-1] - self.r):
            g_pad = K.stack(g_array[i - self.r:i + self.r], axis=-1)
            gw_e = K.squeeze(K.dot(g_pad, K.expand_dims(self.W)), axis=-1)

            gw.append(K.max(gw_e, axis=-1))

        gw = K.stack(gw, axis=-1)
        print(gw.shape)
        ul = K.relu(gw + self.b)

        bate = K.exp(ul)
        bate /= K.sum(bate, axis=-1, keepdims=True) + K.epsilon()

        return x_ * K.expand_dims(bate)
Exemplo n.º 6
0
def extract_seq_patches(x, kernel_size, rate):
    """x.shape = [None, seq_len, seq_dim]
    滑动地把每个窗口的x取出来,为做局部attention作准备。
    Args:
        x:需要分窗口的变量
        kernel_size:窗口长度,会padding kernel_size-1个空白,(类似CNN中的same padding)
    Exampe:    
        kvar = K.variable(value=np.array([[[1,1],[3,4]]]))  # 最里层为一个句子
        K.eval((extract_seq_patches(kvar, 3, 1)))
        Out[135]: 
        array([[[[0., 0.],
                 [1., 1.],
                 [3., 4.]],
        
                [[1., 1.],
                 [3., 4.],
                 [0., 0.]]]], dtype=float32)
    """
    # 获取句子维数和句子长度,用于最后的reshape
    seq_dim = K.int_shape(x)[-1]
    seq_len = K.shape(x)[1]
    # 由kernel_size决定temporal_padding的多少,p_left==p_left
    # 左右两侧都padding kernel_size-1个空白,
    k_size = kernel_size + (rate - 1) * (kernel_size - 1)
    p_right = (k_size - 1) // 2
    p_left = k_size - 1 - p_right
    # 进行padding
    x = K.temporal_padding(x, (p_left, p_right))
    # 按句子的单词进行划分,只选取其中一部分单词
    xs = [x[:, i:i + seq_len] for i in range(0, k_size, rate)]
    # 按照axis = 2连接
    x = K.concatenate(xs, 2)
    # 每个句子中分为若干个窗口,所以多了一个维度,输出为4维数,np.array,第一个维数为batch_size
    return K.reshape(x, (-1, seq_len, kernel_size, seq_dim))
 def call(self, x):
     new_vec_list = []
     shape = K.get_value(self.floor(K.int_shape(x)[1]))
     for l in self.ovl:
         temp_vec_list = []
         for i in range(l):
             self.window_size = K.get_value(self.ceil(
                 K.int_shape(x)[1] / l))
             self.stride = K.get_value(self.floor(K.int_shape(x)[1] / l))
             if (self.stride * i + self.window_size) <= shape:
                 temp = x[:, self.stride * i:self.stride * i +
                          self.window_size]
             else:
                 temp = x[:, self.stride * i:, :]
                 temp = K.temporal_padding(
                     temp, (0, self.window_size -
                            K.get_value(self.floor(K.int_shape(temp)[1]))))
             temp = K.max(temp, axis=1, keepdims=True)
             temp_vec_list.append(temp)
         if l == 1:
             new_vec_list = temp_vec_list
         else:
             new_vec_list.append(
                 keras.layers.concatenate(temp_vec_list, axis=1))
     if len(self.ovl) == 1:
         return new_vec_list
     ret = keras.layers.concatenate(new_vec_list, axis=1)
     # print(self.compute_output_shape(x.shape))
     return ret
Exemplo n.º 8
0
 def get_keras_pad(cls, x, pads, dim, data_format=None):
     """
     implement pad in conv or pool operator
     :param x: input tensor
     :param pads: pads attribute in conv or pool operator
     :param dim: the pad dim
     :param data_format: data format of x
     :return: the result tensor of input tensor implementing padding operation
     """
     if sum(pads) == 0:
         return x
     if len(pads) == dim * 2:
         pads = list(
             np.transpose(
                 np.array(pads).reshape([2, dim]).astype(np.int32)))
         pads = tuple(tuple(i) for i in pads)
     elif len(pads) == dim:
         pads = tuple((i, i) for i in pads)
     if dim == 1:
         return Lambda(lambda _x: K.temporal_padding(_x, pads))(x)
     elif dim == 2:
         return Lambda(
             lambda _x: K.spatial_2d_padding(_x, pads, data_format))(x)
     elif dim == 3:
         return Lambda(
             lambda _x: K.spatial_3d_padding(_x, pads, data_format))(x)
     else:
         raise NotImplementedError(
             "padding with dim {} is not implemented.".format(dim))
Exemplo n.º 9
0
    def preprocess_input(self, inputs, training=None):
        if self.window_size > 1:
            inputs = K.temporal_padding(inputs, (self.window_size - 1, 0))
        inputs = K.expand_dims(inputs, 2)  # add a dummy dimension

        output = K.conv2d(
            inputs,
            self.kernel,
            strides=self.strides,
            padding="valid",
            data_format="channels_last",
        )
        output = K.squeeze(output, 2)  # remove the dummy dimension
        if self.use_bias:
            output = K.bias_add(output, self.bias, data_format="channels_last")

        if self.dropout is not None and 0.0 < self.dropout < 1.0:
            z = output[:, :, :self.units]
            f = output[:, :, self.units:2 * self.units]
            o = output[:, :, 2 * self.units:]
            f = K.in_train_phase(1 - _dropout(1 - f, self.dropout),
                                 f,
                                 training=training)
            return K.concatenate([z, f, o], -1)
        else:
            return output
Exemplo n.º 10
0
def concat(x, x_concat):
    """
    
    """
    diff = K.shape(x_concat)[1] - K.shape(x)[1]
    x = K.temporal_padding(x, padding=(diff // 2, diff - diff // 2))
    return x
Exemplo n.º 11
0
    def call(self, inputs, mask=None):
        if self.input_type == 'sentence':
            # inputs are untokenized sentences
            embeddings = self.elmo(inputs=K.squeeze(K.cast(inputs, tf.string),
                                                    axis=1),
                                   signature="default",
                                   as_dict=True)[self.output_mode]
            elmo_max_length = K.int_shape(embeddings)[1]
            if self.max_length > elmo_max_length:
                embeddings = K.temporal_padding(embeddings,
                                                padding=(0, self.max_length -
                                                         elmo_max_length))
            elif elmo_max_length > self.max_length:
                # embeddings = tf.slice(embeddings, begin=[0, 0, 0], size=[-1, self.max_length, -1])
                embeddings = embeddings[:, :
                                        self.max_length, :]  # more pythonic
        else:
            # inputs are tokenized word id sequence
            # convert inputs to word sequence
            inputs = tf.cast(inputs, dtype=tf.int64)
            sequence_lengths = tf.cast(tf.count_nonzero(inputs, axis=1),
                                       dtype=tf.int32)
            embeddings = self.elmo(inputs={
                'tokens': self.lookup_table.lookup(inputs),
                'sequence_len': sequence_lengths
            },
                                   signature="tokens",
                                   as_dict=True)[self.output_mode]
            if self.output_mode != 'defalut':
                output_mask = K.expand_dims(K.cast(K.not_equal(inputs, 0),
                                                   tf.float32),
                                            axis=-1)
                embeddings *= output_mask

        return embeddings
Exemplo n.º 12
0
 def call(self, x, mask=None):
     if self.causal:
         x = K.temporal_padding(x,
                                padding=(self.atrous_rate *
                                         (self.filter_length - 1), 0))
     # return super(CausalAtrousConvolution1D, self).call(x, mask)
     return super(CausalDilatedConv1D, self).call(x)
Exemplo n.º 13
0
def _add_context(x, context_frames, pad_frames):
    x = K.temporal_padding(x, (pad_frames, pad_frames))
    to_concat = [
        x[:, offset:-(context_frames - offset - 1), :]
        for offset in range(context_frames - 1)
    ]
    to_concat.append(x[:, (context_frames - 1):, :])
    x = K.concatenate(to_concat, axis=2)
    return x
Exemplo n.º 14
0
def same_padding_second_dim(x, padding_length, name):
    if (padding_length % 2 == 0):
        l, r = padding_length / 2, padding_length / 2 - 1
    else:
        l, r = padding_length / 2, padding_length / 2 + 1
    l, r = int(l), int(r)

    # x = Lambda(lambda x: K.temporal_padding(x, padding=(l,r)), name='same_padding_second_dim' + str(name))
    x = Lambda(lambda x: K.temporal_padding(x, padding=(l, r)))
    # x = K.temporal_padding(x, padding=(l,r))
    return x
Exemplo n.º 15
0
 def call(self, x):
     new_vec_list = []
     for i in range(self.splits):
         if (self.stride * i + self.window_size) <= int(self.in_shape[1]):
             temp = x[:, self.stride * i:self.stride * i + self.window_size]
         else:
             temp = x[:, self.stride * i:int(self.in_shape[1])]
             temp = K.temporal_padding(
                 temp, (0, self.window_size - K.int_shape(temp)[1]))
         new_vec_list.append(temp)
     return new_vec_list
def same_padding_second_dim(x, padding_length, name):
    if(padding_length % 2 == 0 ):
        l , r = padding_length/2 , padding_length/2 - 1
    else:
        l , r = padding_length/2 , padding_length/2 + 1
    l , r = int(l), int(r)
    if(l < 0 ):l = 0
    if(r < 0): r = 0
    x = Lambda(lambda x: K.temporal_padding(x, padding=(l, r)))
    # x = K.temporal_padding(x, padding=(l,r))
    return x
Exemplo n.º 17
0
def extract_seq_patches(x, kernel_size, rate):
    """x.shape = [None, seq_len, seq_dim]
    滑动地把每个窗口的x取出来,为做局部attention作准备。
    """
    seq_dim = K.int_shape(x)[-1]
    seq_len = K.shape(x)[1]
    k_size = kernel_size + (rate - 1) * (kernel_size - 1)
    p_right = (k_size - 1) // 2
    p_left = k_size - 1 - p_right
    x = K.temporal_padding(x, (p_left, p_right))
    xs = [x[:, i:i + seq_len] for i in range(0, k_size, rate)]
    x = K.concatenate(xs, 2)
    return K.reshape(x, (-1, seq_len, kernel_size, seq_dim))
Exemplo n.º 18
0
        def special_cube_conv(in_tensor, filter_size):
            """
            Takes in a None (samples) x 54 x ? (filters) tensor.

            It embedds it into 5 x 5 grid, and does a 3D convolution
            using only the nodes in the orginal embedding.

            To speed things up, it actually does the folowing:
            - pads the end with a zero (in the last dimension):
                None (samples) x 55 x ? (filters) (neighbors)
            - align neighbors to get an output of dim:
                None (samples) x 54 x 27 x ? (filters) (neighbors)
            - 2d convolution with filter (1, 27) and no padding to get an output of dim:
                None (samples) x 54 x filter_size
            - reshape to remove last dimension:
                None (samples) x filter_size x 54
            """
            assert in_tensor.shape[1] == 54, in_tensor.shape

            # pad (output dim: None x 55 x ?)
            padded = Lambda(lambda x: K.temporal_padding(x, (0, 1)))(
                in_tensor)  # just pad end
            assert padded.shape[1] == 55, padded.shape

            # align neighbors (output dim: None x 54 x 27 x ?)
            #aligned = K.gather(padded, neighbors)
            #aligned = padded[ neighbors[np.newaxis].astype(np.int32), :]
            aligned = Lambda(lambda x: tf.gather(x, neighbors, axis=1))(padded)
            assert aligned.shape[1:3] == (54, 27), aligned.shape

            # 2D convolution in one axis (output dim: None x 54 x 1 x filter_size)
            conv = Conv2D(filter_size,
                          kernel_size=(1, 27),
                          strides=(1, 1),
                          padding='valid',
                          data_format="channels_last",
                          kernel_regularizer=l2(0.001),
                          bias_regularizer=l2(0.001))(aligned)
            assert conv.shape[1:3] == (54, 1), conv.shape

            # reshape (output dim: None x 54 x filter_size)
            out_tensor = Lambda(lambda x: K.squeeze(x, axis=2))(conv)
            assert out_tensor.shape[1] == 54, out_tensor.shape

            return out_tensor
Exemplo n.º 19
0
        def special_cube_conv(in_tensor, filter_size):
            """
            Takes in a None (samples) x 54 x ? (filters) tensor.

            It embedds it into 5 x 5 grid, and does a 3D convolution
            using only the nodes in the orginal embedding.

            To speed things up, it actually does the folowing:
            - pads the end with a zero (in the last dimension):
                None (samples) x 55 x ? (filters) (neighbors)
            - align neighbors to get an output of dim:
                None (samples) x 54 x 27 x ? (filters) (neighbors)
            - 2d convolution with filter (1, 27) and no padding to get an output of dim:
                None (samples) x 54 x filter_size
            - reshape to remove last dimension:
                None (samples) x filter_size x 54
            """
            assert in_tensor.shape[1] == 54, in_tensor.shape

            # pad (output dim: None x 55 x ?)
            padded = Lambda(lambda x: K.temporal_padding(x, (0, 1)))(in_tensor) # just pad end
            assert padded.shape[1] == 55, padded.shape

            # align neighbors (output dim: None x 54 x 27 x ?)
            #aligned = K.gather(padded, neighbors)
            #aligned = padded[ neighbors[np.newaxis].astype(np.int32), :]
            aligned = Lambda(lambda x: tf.gather(x, neighbors, axis=1))(padded)
            assert aligned.shape[1:3] == (54, 27), aligned.shape

            # 2D convolution in one axis (output dim: None x 54 x 1 x filter_size)
            conv = Conv2D(filter_size, kernel_size=(1, 27),
                          strides=(1, 1),
                          padding='valid',
                          data_format="channels_last",
                          kernel_regularizer=l2(0.001),
                          bias_regularizer=l2(0.001))(aligned)
            assert conv.shape[1:3] == (54, 1), conv.shape

            # reshape (output dim: None x 54 x filter_size)
            out_tensor = Lambda(lambda x: K.squeeze(x, axis=2))(conv)
            assert out_tensor.shape[1] == 54, out_tensor.shape

            return out_tensor
Exemplo n.º 20
0
 def call(self, x):
     self.new_layers_list = []
     out_vecs = []
     for window in self.windows:
         window = int(window)
         new_vec_list = []
         i = 0
         while K.int_shape(x)[1] > window * (i + 1):
             temp = x[:, window * i:window * (i + 1)]
             new_vec_list.append(temp)
             i += 1
         temp = x[:, window * i:]
         temp = K.temporal_padding(temp,
                                   padding=(0, window * (i + 1) -
                                            K.int_shape(x)[1]))
         new_vec_list.append(temp)
         temp = concatenate(new_vec_list, axis=-1)
         temp = K.mean(temp, axis=-1, keepdims=True)
         out_vecs.append(temp)
     return out_vecs
        def stdev_pooling(inputs, stride):
            import keras.backend as K

            data = inputs

            padding = K.shape(data)[1] % stride
            data = K.switch(
                padding > 0,
                K.temporal_padding(data, padding=(0, stride - padding)), data)
            num_windows = K.shape(data)[1] / stride
            idxs = K.arange(num_windows) * stride

            windows = K.map_fn(lambda w: data[:, w:(w + stride), :],
                               idxs,
                               dtype=K.floatx())
            windows = K.permute_dimensions(windows, (1, 0, 2, 3))

            stds = K.map_fn(lambda w: K.std(w, axis=1), windows)

            return stds
Exemplo n.º 22
0
    def call(self, x):
        # input shape: (nb_samples, time (padded with zeros), input_dim)
        # note that the .build() method of subclasses MUST define
        # self.input_spec with a complete input shape.
        input_shape = self.input_spec[0].shape

        if self.window_size > 1:
            x = K.temporal_padding(x, (self.window_size-1, 0))
        x = K.expand_dims(x, 2)  # add a dummy dimension

        # z, g
        output = K.conv2d(x, self.kernel, strides=self.strides,
                          padding='valid',
                          data_format='channels_last')
        output = K.squeeze(output, 2)  # remove the dummy dimension
        if self.use_bias:
            output = K.bias_add(output, self.bias, data_format='channels_last')
        z  = output[:, :, :self.output_dim]
        g = output[:, :, self.output_dim:]

        return self.activation(z) * K.sigmoid(g)
Exemplo n.º 23
0
 def get_keras_pad(cls, x, pads, dim, data_format=None):
     if sum(pads) == 0:
         return x
     if len(pads) == dim * 2:
         pads = list(
             np.transpose(
                 np.array(pads).reshape([2, dim]).astype(np.int32)))
         pads = tuple(tuple(i) for i in pads)
     elif len(pads) == dim:
         pads = tuple((i, i) for i in pads)
     if dim == 1:
         return Lambda(lambda _x: K.temporal_padding(_x, pads))(x)
     elif dim == 2:
         return Lambda(
             lambda _x: K.spatial_2d_padding(_x, pads, data_format))(x)
     elif dim == 3:
         return Lambda(
             lambda _x: K.spatial_3d_padding(_x, pads, data_format))(x)
     else:
         raise NotImplementedError(
             "padding with dim {} is not implemented.".format(dim))
Exemplo n.º 24
0
    def preprocess_input(self, x):
        if self.window_size > 1:
            x = K.temporal_padding(x, (self.window_size - 1, 0))
        x = K.expand_dims(x, 2)  # add a dummy dimension

        output = K.conv2d(x,
                          self.W,
                          strides=self.subsample,
                          padding='valid',
                          data_format='channels_last')
        output = K.squeeze(output, 2)  # remove the dummy dimension
        if self.bias:
            output += K.reshape(self.b, (1, 1, self.output_dim * 3))

        if self.dropout is not None and 0. < self.dropout < 1.:
            z = output[:, :, :self.output_dim]
            f = output[:, :, self.output_dim:2 * self.output_dim]
            o = output[:, :, 2 * self.output_dim:]
            f = K.in_train_phase(1 - _dropout(1 - f, self.dropout), f)
            return K.concatenate([z, f, o], -1)
        else:
            return output
Exemplo n.º 25
0
 def call(self, inputs):
     if isinstance(inputs, list):
         x, x_mask = inputs
     else:
         x, x_mask = inputs, None
     seq_dim = K.int_shape(x)[-1]
     # 补足长度,保证可以reshape
     seq_len = K.shape(x)[1]
     pad_len = self.rate - seq_len % self.rate
     x = K.temporal_padding(x, (0, pad_len))
     if x_mask is not None:
         x_mask = K.temporal_padding(x_mask, (0, pad_len))
     new_seq_len = K.shape(x)[1]
     x = K.reshape(x, (-1, new_seq_len,
                       seq_dim))  # 经过padding后shape可能变为None,所以重新声明一下shape
     # 线性变换
     qw = self.reuse(self.q_dense, x)
     kw = self.reuse(self.k_dense, x)
     vw = self.reuse(self.v_dense, x)
     # 提取局部特征
     kernel_size = 1 + 2 * self.neighbors
     kwp = extract_seq_patches(
         kw, kernel_size,
         self.rate)  # shape=[None, seq_len, kernel_size, out_dim]
     vwp = extract_seq_patches(
         vw, kernel_size,
         self.rate)  # shape=[None, seq_len, kernel_size, out_dim]
     if x_mask is not None:
         xp_mask = extract_seq_patches(x_mask, kernel_size, self.rate)
     # 形状变换
     qw = K.reshape(qw, (-1, new_seq_len // self.rate, self.rate,
                         self.heads, self.key_size))
     kw = K.reshape(kw, (-1, new_seq_len // self.rate, self.rate,
                         self.heads, self.key_size))
     vw = K.reshape(vw, (-1, new_seq_len // self.rate, self.rate,
                         self.heads, self.size_per_head))
     kwp = K.reshape(kwp, (-1, new_seq_len // self.rate, self.rate,
                           kernel_size, self.heads, self.key_size))
     vwp = K.reshape(vwp, (-1, new_seq_len // self.rate, self.rate,
                           kernel_size, self.heads, self.size_per_head))
     if x_mask is not None:
         x_mask = K.reshape(x_mask,
                            (-1, new_seq_len // self.rate, self.rate, 1, 1))
         xp_mask = K.reshape(
             xp_mask,
             (-1, new_seq_len // self.rate, self.rate, kernel_size, 1, 1))
     # 维度置换
     qw = K.permute_dimensions(
         qw, (0, 3, 2, 1, 4))  # shape=[None, heads, r, seq_len // r, size]
     kw = K.permute_dimensions(kw, (0, 3, 2, 1, 4))
     vw = K.permute_dimensions(vw, (0, 3, 2, 1, 4))
     qwp = K.expand_dims(qw, 4)
     kwp = K.permute_dimensions(
         kwp,
         (0, 4, 2, 1, 3,
          5))  # shape=[None, heads, r, seq_len // r, kernel_size, out_dim]
     vwp = K.permute_dimensions(vwp, (0, 4, 2, 1, 3, 5))
     if x_mask is not None:
         x_mask = K.permute_dimensions(x_mask, (0, 3, 2, 1, 4))
         xp_mask = K.permute_dimensions(xp_mask, (0, 4, 2, 1, 3, 5))
     # Attention1
     a = K.batch_dot(qw, kw, [4, 4]) / self.key_size**0.5
     a = K.permute_dimensions(a, (0, 1, 2, 4, 3))
     a = to_mask(a, x_mask, 'add')
     a = K.permute_dimensions(a, (0, 1, 2, 4, 3))
     if self.mask_right:
         ones = K.ones_like(a[:1, :1, :1])
         mask = (ones - K.tf.matrix_band_part(ones, -1, 0)) * 1e10
         a = a - mask
     # Attention2
     ap = K.batch_dot(qwp, kwp, [5, 5]) / self.key_size**0.5
     ap = K.permute_dimensions(ap, (0, 1, 2, 3, 5, 4))
     if x_mask is not None:
         ap = to_mask(ap, xp_mask, 'add')
     ap = K.permute_dimensions(ap, (0, 1, 2, 3, 5, 4))
     if self.mask_right:
         mask = np.ones((1, kernel_size))
         mask[:, -self.neighbors:] = 0
         mask = (1 - K.constant(mask)) * 1e10
         for _ in range(4):
             mask = K.expand_dims(mask, 0)
         ap = ap - mask
     ap = ap[..., 0, :]
     # 合并两个Attention
     A = K.concatenate([a, ap], -1)
     A = K.softmax(A)
     a, ap = A[..., :K.shape(a)[-1]], A[..., K.shape(a)[-1]:]
     # 完成输出1
     o1 = K.batch_dot(a, vw, [4, 3])
     # 完成输出2
     ap = K.expand_dims(ap, -2)
     o2 = K.batch_dot(ap, vwp, [5, 4])
     o2 = o2[..., 0, :]
     # 完成输出
     o = o1 + o2
     o = to_mask(o, x_mask, 'mul')
     o = K.permute_dimensions(o, (0, 3, 2, 1, 4))
     o = K.reshape(o, (-1, new_seq_len, self.out_dim))
     o = o[:, :-pad_len]
     return o
Exemplo n.º 26
0
def divisible_temporal_padding(x, n):
    """将一维向量序列右padding到长度能被n整除
    """
    r_len = K.shape(x)[1] % n
    p_len = K.switch(r_len > 0, n - r_len, 0)
    return K.temporal_padding(x, (0, p_len))
Exemplo n.º 27
0
 def _delay(self, x):
     return K.temporal_padding(x, (1, 0))[:, :-1]
Exemplo n.º 28
0
 def call(self, inputs):
     return K.temporal_padding(inputs, padding=self.padding)
Exemplo n.º 29
0
def neighbour_lookup(atoms, edges, maskvalue=0, include_self=False):
    ''' Looks up the features of an all atoms neighbours, for a batch of molecules.

    # Arguments:
        atoms (K.tensor): of shape (batch_n, max_atoms, num_atom_features)
        edges (K.tensor): of shape (batch_n, max_atoms, max_degree) with neighbour
            indices and -1 as padding value
        maskvalue (numerical): the maskingvalue that should be used for empty atoms
            or atoms that have no neighbours (does not affect the input maskvalue
            which should always be -1!)
        include_self (bool): if True, the featurevector of each atom will be added
            to the list feature vectors of its neighbours

    # Returns:
        neigbour_features (K.tensor): of shape (batch_n, max_atoms(+1), max_degree,
            num_atom_features) depending on the value of include_self

    # Todo:
        - make this function compatible with Tensorflow, it should be quite trivial
            because there is an equivalent of `T.arange` in tensorflow.
    '''

    # The lookup masking trick: We add 1 to all indices, converting the
    #   masking value of -1 to a valid 0 index.
    masked_edges = edges + 1
    # We then add a padding vector at index 0 by padding to the left of the
    #   lookup matrix with the value that the new mask should get
    # masked_atoms = temporal_padding(atoms, (1,0), padvalue=maskvalue)  # OLD code. Use keras.backend.temporal_padding
    masked_atoms = K.temporal_padding(atoms, padding=(1, 0))

    # Import dimensions
    atoms_shape = K.shape(masked_atoms)  # shape (batch_n, max_atoms + 1, num_atom_features) +1 from padding
    batch_n = atoms_shape[0]  # number of molecules in batch aka number of examples per batch
    lookup_size = atoms_shape[1]  # number of atoms in one molecule aka atoms in one example
    num_atom_features = atoms_shape[2]  # number of atom features

    edges_shape = K.shape(masked_edges)
    max_atoms = edges_shape[1]  # number of atoms in one molecule
    max_degree = edges_shape[2]  # max number of connections an atom can have, usually is 5

    # create broadcastable offset
    offset_shape = (batch_n, 1, 1)
    # print(K.dtype(masked_edges))  # equals int32
    # changed T.arange to K.arange
    offset = K.reshape(K.arange(batch_n, dtype=K.dtype(masked_edges)), offset_shape)
    offset *= lookup_size

    # apply offset to account for the fact that after reshape, all individual
    #   batch_n indices will be combined into a single big index
    flattened_atoms = K.reshape(masked_atoms, (-1, num_atom_features))
    flattened_edges = K.reshape(masked_edges + offset, (batch_n, -1))

    # Gather flattened
    flattened_result = K.gather(flattened_atoms, flattened_edges)

    # Unflatten result
    output_shape = (batch_n, max_atoms, max_degree, num_atom_features)
    # output = T.reshape(flattened_result, output_shape)  # OLD
    output = K.reshape(x=flattened_result, shape=output_shape)

    if include_self:
        # EDIT: changed dim=2 to axis=2
        return K.concatenate([K.expand_dims(atoms, axis=2), output], axis=2)
    return output