Вы передаете список пустых массивов для model.fit. Следующий код создает список массивов для x_train_encode и X_test_encode.
X_train_encode = [one_hot(d, vocab_size,lower=True, split=' ') for d in X_train]
X_test_encode = [one_hot(d, vocab_size,lower=True, split=' ') for d in X_test]
Измените эти списки на массив numpy при передаче методу model.fit.
X_train_encode = np.array(X_train_encode)
X_test_encode = np.array(X_test_encode)
И я не вижу необходимости в one_hot кодировать X_train и X_test, слой встраивания ожидает целое число (в ваших словах-индексах), а не одно горячее закодированное значение индексов слов. Поэтому, если X_train и X_test являются массивом индексов слов, вы можете напрямую передать это в метод model.fit.
EDIT:
В настоящее время используется потеря mse. Поскольку последний слой является слоем софтмакс, кросс-энтропийная потеря здесь более применима. А также выходные данные представляют собой целочисленные значения класса (слова), которые должны использоваться в качестве разреженных категорий для потери.
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])