如何使Keras密集层处理3D张量作为此Softmax全连接层的输入?

问题描述

我正在处理一个自定义问题,我必须更改完全连接的层(使用softmax进行密集处理),我的模型代码是这样的(使用Keras Framework):

.......
batch_size = 8
inputs = tf.random.uniform(shape=[batch_size,1024,256],dtype=tf.dtypes.float32)
preds = Dense(num_classes,activation='softmax')(x) #final layer with softmax activation
....
model = Model(inputs=base_model.input,outputs=preds)

因此,我必须更改密集层代码以输出具有[batch_size,1024,num_classes]形状的概率张量,而无需使用for循环,我需要对其进行优化而不是耗时的功能

我要更改的密集代码版本:

class Dense(Layer):
"""Just your regular densely-connected NN layer.

`Dense` implements the operation:
`output = activation(dot(input,kernel) + bias)`
where `activation` is the element-wise activation function
passed as the `activation` argument,`kernel` is a weights matrix
created by the layer,and `bias` is a bias vector created by the layer
(only applicable if `use_bias` is `True`).

Note: if the input to the layer has a rank greater than 2,then
it is flattened prior to the initial dot product with `kernel`.

# Example

```python
    # as first layer in a sequential model:
    model = Sequential()
    model.add(Dense(32,input_shape=(16,)))
    # now the model will take as input arrays of shape (*,16)
    # and output arrays of shape (*,32)

    # after the first layer,you don't need to specify
    # the size of the input anymore:
    model.add(Dense(32))
```

# Arguments
    units: Positive integer,dimensionality of the output space.
    activation: Activation function to use
        (see [activations](../activations.md)).
        If you don't specify anything,no activation is applied
        (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean,whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix
        (see [initializers](../initializers.md)).
    bias_initializer: Initializer for the bias vector
        (see [initializers](../initializers.md)).
    kernel_regularizer: Regularizer function applied to
        the `kernel` weights matrix
        (see [regularizer](../regularizers.md)).
    bias_regularizer: Regularizer function applied to the bias vector
        (see [regularizer](../regularizers.md)).
    activity_regularizer: Regularizer function applied to
        the output of the layer (its "activation").
        (see [regularizer](../regularizers.md)).
    kernel_constraint: Constraint function applied to
        the `kernel` weights matrix
        (see [constraints](../constraints.md)).
    bias_constraint: Constraint function applied to the bias vector
        (see [constraints](../constraints.md)).

# Input shape
    nD tensor with shape: `(batch_size,...,input_dim)`.
    The most common situation would be
    a 2D input with shape `(batch_size,input_dim)`.

# Output shape
    nD tensor with shape: `(batch_size,units)`.
    For instance,for a 2D input with shape `(batch_size,input_dim)`,the output would have shape `(batch_size,units)`.
"""

def __init__(self,units,activation=None,use_bias=True,kernel_initializer='glorot_uniform',bias_initializer='zeros',kernel_regularizer=None,bias_regularizer=None,activity_regularizer=None,kernel_constraint=None,bias_constraint=None,**kwargs):
    if 'input_shape' not in kwargs and 'input_dim' in kwargs:
        kwargs['input_shape'] = (kwargs.pop('input_dim'),)
    super(Dense,self).__init__(**kwargs)
    self.units = units
    self.activation = activations.get(activation)
    self.use_bias = use_bias
    self.kernel_initializer = initializers.get(kernel_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.kernel_constraint = constraints.get(kernel_constraint)
    self.bias_constraint = constraints.get(bias_constraint)
    self.input_spec = InputSpec(min_ndim=2)
    self.supports_masking = True

def build(self,input_shape):
    assert len(input_shape) >= 2 
    input_dim = input_shape[-1]  

    self.kernel = self.add_weight(shape=(input_dim,self.units),initializer=self.kernel_initializer,name='kernel',regularizer=self.kernel_regularizer,constraint=self.kernel_constraint)
    if self.use_bias:
        self.bias = self.add_weight(shape=(self.units,),initializer=self.bias_initializer,name='bias',regularizer=self.bias_regularizer,constraint=self.bias_constraint)
    else:
        self.bias = None
    self.input_spec = InputSpec(min_ndim=2,axes={-1: input_dim})
    self.built = True

def call(self,inputs):
    output = K.dot(inputs,self.kernel)
    if self.use_bias:
        output = K.bias_add(output,self.bias)
    if self.activation is not None:
        output = self.activation(output)
    return output

def compute_output_shape(self,input_shape):
    assert input_shape and len(input_shape) >= 2
    assert input_shape[-1]
    output_shape = list(input_shape)
    output_shape[-1] = self.units
    return tuple(output_shape)

def get_config(self):
    config = {
        'units': self.units,'activation': activations.serialize(self.activation),'use_bias': self.use_bias,'kernel_initializer': initializers.serialize(self.kernel_initializer),'bias_initializer': initializers.serialize(self.bias_initializer),'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),'bias_regularizer': regularizers.serialize(self.bias_regularizer),'activity_regularizer': regularizers.serialize(self.activity_regularizer),'kernel_constraint': constraints.serialize(self.kernel_constraint),'bias_constraint': constraints.serialize(self.bias_constraint)
    }
    base_config = super(Dense,self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)