Reputation: 1679
I am trying to use an LSTM to learn a binary classification on two classes of text sequences. However, I keep getting the following error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-56-2fc4b1cd1003> in <module>()
101 epochs=5,
102 batch_size=32,
--> 103 validation_data=(valid_x, valid_y))
2 frames
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
1087 sample_weight=sample_weight,
1088 class_weight=class_weight,
-> 1089 batch_size=batch_size)
1090
1091 # Prepare validation data.
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
793 feed_output_shapes,
794 check_batch_axis=False, # Don't enforce the batch size.
--> 795 exception_prefix='target')
796
797 # Generate sample-wise weight values given the `sample_weight` and
/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
139 ': expected ' + names[i] + ' to have shape ' +
140 str(shape) + ' but got array with shape ' +
--> 141 str(data_shape))
142 return data
143
ValueError: Error when checking target: expected dense_16 to have shape (2,) but got array with shape (1,)
This is my code:
# read in raw data
file_list = glob.glob('data/*')
df_list = []
for path in file_list:
df = pd.read_csv(path)
df_list.append(df)
df_list_ = []
for df in df_list:
df_list_.append(df)
data = []
labels = []
for df in df_list_:
samples = df.data.tolist()
label = df.labels.to_list()
labels.append(label)
data_ = []
for i in samples:
data_.append(i.split())
data.append(data_)
flat_data = [item for sublist in data for item in sublist]
flat_label = [item for sublist in labels for item in sublist]
data = flat_data
labels = flat_label
# tokenize and vectorize text data to prepare for embedding
tokenizer = Tokenizer()
tokenizer.fit_on_texts(data)
sequences = tokenizer.texts_to_sequences(data)
word_index = tokenizer.word_index
print(f'Found {len(word_index)} unique tokens.')
# load in and build pre-trained word embedding from GloVe 50d
embeddings_index = {}
f = open('glove.6B.50d.txt')
for line in f:
values = line.split()
word = values[0]
coefs = np.asarray(values[1:], dtype='float32')
embeddings_index[word] = coefs
f.close()
print('Found %s word vectors.' % len(embeddings_index))
embedding_matrix = np.zeros((len(word_index) + 1, 50))
for word, i in word_index.items():
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all-zeros.
embedding_matrix[i] = embedding_vector
# setting variables
vocab_size = len(word_index)
# Input_dim: This is the size of the vocabulary in the text data.
input_dim = vocab_size + 1
# This is the size of the vector space in which words will be embedded.
output_dim = 32
# This is the length of input sequences
max_sequence_length = len(max(sequences, key=len))
data = pad_sequences(sequences, maxlen=max_sequence_length)
# keras automatically pads to maxlen if left without input
data = pad_sequences(sequences)
labels = to_categorical(labels, num_classes=2, dtype='float32')
# Create test/train data
train_x, train_y = data[:round(len(data)*.6)], labels[:round(len(data)*.6)]
valid_x, valid_y = data[round(len(data)*.6):round(len(data)*.8)], labels[round(len(data)*.6):round(len(data)*.8)]
test_x, test_y = data[round(len(data)*.8):], labels[round(len(data)*.8):]
### LSTM
LSTM = Sequential()
LSTM.add(Embedding(input_dim,
50,
weights=[embedding_matrix],
input_length=max_sequence_length,
trainable=False))
LSTM.add(layers.LSTM(32))
LSTM.add(layers.Dropout(.5))
LSTM.add(Dense(2, activation='sigmoid'))
LSTM.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
history = LSTM.fit(train_x,
train_y,
epochs=5,
batch_size=32,
validation_data=(valid_x, valid_y))
The code ran perfectly earlier, but then this started without me making any changes (so I thought). I cannot figure out whats going wrong. Any assistance would be greatly appreciated.
When I switch the last layer number of hidden units from 2 to 1, I get this error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-cb3a85d91810> in <module>()
101 epochs=5,
102 batch_size=32,
--> 103 validation_data=(valid_x, valid_y))
2 frames
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
1108 val_x, val_y,
1109 sample_weight=val_sample_weight,
-> 1110 batch_size=batch_size)
1111 if self._uses_dynamic_learning_phase():
1112 val_inputs = val_x + val_y + val_sample_weights + [0.]
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
793 feed_output_shapes,
794 check_batch_axis=False, # Don't enforce the batch size.
--> 795 exception_prefix='target')
796
797 # Generate sample-wise weight values given the `sample_weight` and
/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
139 ': expected ' + names[i] + ' to have shape ' +
140 str(shape) + ' but got array with shape ' +
--> 141 str(data_shape))
142 return data
143
ValueError: Error when checking target: expected dense_16 to have shape (1,) but got array with shape (2,)
Upvotes: 0
Views: 87
Reputation: 1134
The reason you are receiving the error is due to the number of labels you assign your features and the number of labels the last layer expects. Here you have assigned each feature to one label while your dense layer expects two. Although there are two classes, you gave each feature only one which is shown in the shape of your array. You can just change the number of units in your last dense layer to one to fix the output shape.
Upvotes: 1