{"record":{"id":"32da211cd22bd16d","repo":"hankcs/HanLP","slug":"the-last-dimension-of-the-inputs-to-crf-should-b","errorCode":null,"errorMessage":"The last dimension of the inputs to `CRF` should be defined. Found `None`.","messagePattern":"The last dimension of the inputs to `CRF` should be defined\\. Found `None`\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"hanlp/layers/crf/crf_layer_tf.py","lineNumber":70,"sourceCode":"        self.supports_masking = False\n        sequence_lengths = None\n\n    def get_config(self):\n        config = {\n            'output_dim': self.output_dim,\n            'supports_masking': self.supports_masking,\n            'transitions': tf.keras.backend.eval(self.transitions)\n        }\n        base_config = super(CRF, self).get_config()\n        return dict(list(base_config.items()) + list(config.items()))\n\n    def build(self, input_shape):\n        assert len(input_shape) == 3\n        f_shape = tf.TensorShape(input_shape)\n        input_spec = tf.keras.layers.InputSpec(min_ndim=3, axes={-1: f_shape[-1]})\n\n        if f_shape[-1] is None:\n            raise ValueError('The last dimension of the inputs to `CRF` '\n                             'should be defined. Found `None`.')\n        if f_shape[-1] != self.output_dim:\n            raise ValueError('The last dimension of the input shape must be equal to output'\n                             ' shape. Use a linear layer if needed.')\n        self.input_spec = input_spec\n        self.transitions = self.add_weight(name='transitions',\n                                           shape=[self.output_dim, self.output_dim],\n                                           initializer='glorot_uniform',\n                                           trainable=True)\n        self.built = True\n\n    def compute_mask(self, inputs, mask=None):\n        # Just pass the received mask from previous layer, to the next layer or\n        # manipulate it if this layer changes the shape of the input\n        return mask\n\n    # pylint: disable=arguments-differ\n    def call(self, inputs, sequence_lengths=None, mask=None, training=None, **kwargs):","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/hankcs/HanLP/blob/ddb1299bddff079e447af52ec12549c50636bfa8/hanlp/layers/crf/crf_layer_tf.py#L52-L88","documentation":"Thrown by the TensorFlow CRF layer's build() when the input tensor's last dimension is undefined (None). Keras needs a concrete feature dimension to create the transitions weight matrix of shape (output_dim, output_dim), so an undefined channel count cannot be built. This is the standard check carried over from keras-contrib's CRF implementation.","triggerScenarios":"Feeding inputs with dynamic/undefined last dimension, e.g. an Input(shape=(None, None)), a layer upstream that produces unknown channel size, or input_shape passed without a defined final axis when calling the layer directly.","commonSituations":"Using tf.keras Input with variable feature dimension; building a model where the embedding/feature dimension is inferred as None; upgrading Keras versions where shape inference behavior changed.","solutions":["Define a fixed last dimension in the input, e.g. Input(shape=(None, hidden_size))","Insert a Dense(hidden_size) layer before CRF so the last dim is concrete","If calling build manually, pass an input_shape tuple whose final element is an int"],"exampleFix":"# before\ninputs = tf.keras.layers.Input(shape=(None, None))\ncrf = CRFLayer(units)  # build fails\n# after\ninputs = tf.keras.layers.Input(shape=(None, hidden_size))\ncrf = CRFLayer(hidden_size)","handlingStrategy":"validation","validationCode":"assert inputs.shape[-1] is not None and isinstance(inputs.shape[-1], int)","typeGuard":"def has_defined_last_dim(shape) -> bool:\n    return len(shape) == 3 and isinstance(shape[-1], (int,)) and shape[-1] > 0","tryCatchPattern":null,"preventionTips":["Always give Input a concrete feature dimension","Add a Dense projection before CRF","Pin Keras version to keep shape inference stable"],"tags":["hanlp","tensorflow","keras","crf","input-shape"],"backgroundTag":"undefined-input-dimension","analyzedSha":"ddb1299bddff079e447af52ec12549c50636bfa8","analyzedAt":"2026-08-27T03:36:54.287Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}