keras-team / keras-contrib

Keras community contributions
MIT License
1.58k stars 650 forks source link

AttributeError: 'CRF' object has no attribute 'inbound_nodes' #234

Open o-P-o opened 6 years ago

o-P-o commented 6 years ago

I'm following the example from here: https://www.depends-on-the-definition.com/sequence-tagging-lstm-crf/#comment-89 (building a BiLSTM conditional random field named entity recognition classifier in keras).

When compiling the keras model:

model.compile(optimizer='rmsprop', loss=crf.loss_function, metrics=[crf.accuracy]) the following error is returned:

Traceback (most recent call last):
  File "ner_lstm_crf.py", line 108, in <module>
    model.compile(optimizer='rmsprop', loss=crf.loss_function, metrics=[crf.accuracy])
  File "/Users/Olly/anaconda2/lib/python2.7/site-packages/keras/engine/training.py", line 830, in compile
    sample_weight, mask)
  File "/Users/Olly/anaconda2/lib/python2.7/site-packages/keras/engine/training.py", line 429, in weighted
    score_array = fn(y_true, y_pred)
  File "build/bdist.macosx-10.6-x86_64/egg/keras_contrib/layers/crf.py", line 287, in loss
AttributeError: 'CRF' object has no attribute 'inbound_nodes'

Any help would be greatly appreciated.

If you need it, below is the entirety of the python code up to the error point (line 73):

import pandas as pd 
import numpy as np 
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
from keras.models import Model, Input 
from keras.layers import LSTM, Embedding, Dense, TimeDistributed, Dropout, Bidirectional 
from keras_contrib.layers import CRF
from sklearn.model_selection import train_test_split

from keras.models import Sequential
from keras.models import model_from_json
import os

data = pd.read_csv('Data/ner_dataset.csv', encoding='latin1')
data = data.fillna(method='ffill')

words = list(set(data["Word"].values))
words.append('ENDPAD')
n_words = len(words)

tags = list(set(data["Tag"].values))
n_tags = len(tags)

class SentenceGetter(object):

    def __init__(self, data):
        self.n_sent = 1
        self.data = data 
        self.empty = False 
        agg_func = lambda s: [(w, p, t) for w, p, t in zip(s["Word"].values.tolist(), s["POS"].values.tolist(), s["Tag"].values.tolist())]
        self.grouped = self.data.groupby("Sentence #").apply(agg_func)
        self.sentences = [s for s in self.grouped]

    def get_next(self):
        try:
            s = self.grouped["Sentence: {}".format(self.n_sent)]
            self.n_sent += 1
            return s 
        except: 
            return None 

getter = SentenceGetter(data)
sent = getter.get_next()
sentences = getter.sentences

max_len = 75
word2idx = { w : i for i, w in enumerate(words) }
tag2idx = { t : i for i, t in enumerate(tags) }

X = [[word2idx[w[0]] for w in s] for s in sentences]
y = [[tag2idx[w[2]] for w in s] for s in sentences]
X = pad_sequences(maxlen=max_len, sequences=X, padding='post', value=0)
y = pad_sequences(maxlen=max_len, sequences=y, padding='post', value=tag2idx['O'])
y = [to_categorical(i, num_classes=n_tags) for i in y]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)

''' =================== BUILD MODEL =================== '''

input = Input(shape=(max_len,))
model = Embedding(input_dim=n_words+1, output_dim=20, input_length=max_len, mask_zero=True)(input)
model = Bidirectional(LSTM(units=50, return_sequences=True, recurrent_dropout=0.1))(model)
model = TimeDistributed(Dense(50, activation='relu'))(model)

crf = CRF(n_tags)
out = crf(model)

model = Model(input, out)

model.compile(optimizer="rmsprop", loss=crf.loss_function, metrics=[crf.accuracy])
FredRodrigues commented 6 years ago

Check if this solves your problem. #215

anushkumarv commented 6 years ago

Even i am having the same issue