Numpy Массив тензорного потока.keras.preprocessing.text.Tokenizer.texts_to_sequence дает странный вывод, список ([2]) вместо [[2]] - PullRequest
1 голос
/ 15 февраля 2020

Numpy Массив tensorflow.keras.preprocessing.text.Tokenizer.texts_to_sequences дает странный вывод для учебных ярлыков, как показано ниже:

(training_label_list[0:10]) = [list([1]) list([1]) list([1]) list([1]) list([1]) list([1]) list([1]) list([1]) list([1]) list([1])]

, но печатает обычный массив для проверочных ярлыков,

(validation_label_list[0:10]) = [[16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]]

Другими словами, type(training_label_list[0]) = <class 'list'>, но

type(validation_label_list[0]) =  <class 'numpy.ndarray'>

Следовательно, при обучении модели с использованием Keras Model.fit это приводит к следующей ошибке,

ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type list).

Это ссылка Google Colab , чтобы легко воспроизвести ошибку.

Полный код для воспроизведения ошибки приведен ниже:

!pip install tensorflow==2.1

# For Preprocessing the Text => To Tokenize the Text
from tensorflow.keras.preprocessing.text import Tokenizer
# If the Two Articles are of different length, pad_sequences will make the length equal
from tensorflow.keras.preprocessing.sequence import pad_sequences

# Package for performing Numerical Operations
import numpy as np

Unique_Labels_List = ['India', 'USA', 'Australia', 'Germany', 'Bhutan', 'Nepal', 'New Zealand', 'Israel', 'Canada', 'France', 'Ireland', 'Poland', 'Egypt', 'Greece', 'China', 'Spain', 'Mexico']


Train_Labels = Unique_Labels_List[0:14]
#print('Train Labels = {}'.format(Train_Labels))

Val_Labels =  Unique_Labels_List[14:]
#print('Val_Labels = {}'.format(Val_Labels))

No_Of_Train_Items = [248, 200, 200, 218, 248, 248, 249, 247, 220, 200, 200, 211, 224, 209]
No_Val_Items = [212, 200, 219]

T_L = []
for Each_Label, Item in zip(Train_Labels, No_Of_Train_Items):
    T_L.append([Each_Label] * Item)

T_L = [item for sublist in T_L for item in sublist]

V_L = []
for Each_Label, Item in zip(Val_Labels, No_Val_Items):
    V_L.append([Each_Label] * Item)

V_L = [item for sublist in V_L for item in sublist]


len(T_L)

len(V_L)

label_tokenizer = Tokenizer()

label_tokenizer.fit_on_texts(Unique_Labels_List)

# Since it should be a Numpy Array, we should Convert the Sequences to Numpy Array, for both Training and 
# Test Labels

training_label_list = np.array(label_tokenizer.texts_to_sequences(T_L))

validation_label_list = np.array(label_tokenizer.texts_to_sequences(V_L))

print('(training_label_list[0:10]) = {}'.format((training_label_list[0:10])))
print('(validation_label_list[0:10]) = {}'.format((validation_label_list[0:10])))

print('type(training_label_list[0]) = ', type(training_label_seq[0]))
print('type(validation_label_seq[0]) = ', type(validation_label_seq[0]))

Я буду благодарен, если кто-нибудь подскажет мне, как я могу получить и Учебные ярлыки, и Валидационные ярлыки в одном формате, так как я потратил на это так много времени.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2020

Замена np.array на np.hstack, как упомянуто в этом Ответе переполнения стека исправила эту проблему для меня.

Теперь правильный вывод -

(training_label_seq[0:10]) = [1 1 1 1 1 1 1 1 1 1]
(validation_label_seq[0:10]) = [16 16 16 16 16 16 16 16 16 16]
type(training_label_list[0]) =  <class 'numpy.int64'>
type(validation_label_seq[0]) =  <class 'numpy.int64'>

Ссылка рабочего кода находится в этом Google Colab .

Ниже приведен рабочий код (на всякий случай, если выше ссылка не работает):

!pip install tensorflow==2.1

# For Preprocessing the Text => To Tokenize the Text
from tensorflow.keras.preprocessing.text import Tokenizer
# If the Two Articles are of different length, pad_sequences will make the length equal
from tensorflow.keras.preprocessing.sequence import pad_sequences

# Package for performing Numerical Operations
import numpy as np

Unique_Labels_List = ['India', 'USA', 'Australia', 'Germany', 'Bhutan', 'Nepal', 'New Zealand', 'Israel', 'Canada', 'France', 'Ireland', 'Poland', 'Egypt', 'Greece', 'China', 'Spain', 'Mexico']


Train_Labels = Unique_Labels_List[0:14]
#print('Train Labels = {}'.format(Train_Labels))

Val_Labels =  Unique_Labels_List[14:]
#print('Val_Labels = {}'.format(Val_Labels))

No_Of_Train_Items = [248, 200, 200, 218, 248, 248, 249, 247, 220, 200, 200, 211, 224, 209]
No_Val_Items = [212, 200, 219]

T_L = []
for Each_Label, Item in zip(Train_Labels, No_Of_Train_Items):
    T_L.append([Each_Label] * Item)

T_L = [item for sublist in T_L for item in sublist]

V_L = []
for Each_Label, Item in zip(Val_Labels, No_Val_Items):
    V_L.append([Each_Label] * Item)

V_L = [item for sublist in V_L for item in sublist]


len(T_L)

len(V_L)

label_tokenizer = Tokenizer()

label_tokenizer.fit_on_texts(Unique_Labels_List)

# Since it should be a Numpy Array, we should Convert the Sequences to Numpy Array, for both Training and 
# Test Labels

training_label_list = np.hstack(label_tokenizer.texts_to_sequences(T_L))

validation_label_list = np.hstack(label_tokenizer.texts_to_sequences(V_L))

print('(training_label_list[0:10]) = {}'.format((training_label_list[0:10])))
print('(validation_label_list[0:10]) = {}'.format((validation_label_list[0:10])))

print('type(training_label_list[0]) = ', type(training_label_seq[0]))
print('type(validation_label_seq[0]) = ', type(validation_label_seq[0]))
0 голосов
/ 15 февраля 2020

Ваша проблема в том, что когда вы преобразуете свои тренировочные данные в массив numpy, указанный массив c numpy состоит из элементов списка, поэтому возникает ошибка

ValueError: Не удалось преобразовать массив NumPy в Tensor (список неподдерживаемых типов объектов).

Ошибка более тонкая, чем кажется; некоторые сообщили, что им пришлось переключиться обратно с 2.1.0 на 2.0.0. В чем разница между функциями Numpy для работы с массивами () и asarray ()?

Я бы лично попробовал это:

  1. Использовать training_label_list = np.asarray(label_tokenizer.texts_to_sequences(T_L)) вместо np.array. Tensorflow - ValueError: Не удалось преобразовать массив NumPy в Tensor (неподдерживаемый тип объекта с плавающей точкой)
  2. В соответствии с этим:

Список списков в numpy массив

вам придется принудительно использовать приведение (хотя это странно, но это должно работать):

x=[[1,2],[1,2,3],[1]]
y=numpy.array([numpy.array(xi) for xi in x])
type(y)
>>><type 'numpy.ndarray'>
type(y[0])
>>><type 'numpy.ndarray'>

При попытке помочь вам в этом вопросе, я обнаружил интересный факт о numpy кастинге:

CASE 1:

   my_list = [[1,2],[2],[3]]
   my_numpy_array = np.array(my_list)
   print(type(my_numpy_array))
   print(type(my_numpy_array[0]))
   <class 'numpy.ndarray'>
   <class 'list'>

CASE 2:

    my_list = [[1],[2],[3]]
    my_numpy_array = np.array(my_list)
    print(type(my_numpy_array))
    print(type(my_numpy_array[0]))
    <class 'numpy.ndarray'>
    <class 'numpy.ndarray'>

Краткое заключение: Если длины подсписков различаются, по-видимому, они остаются в виде списков и не преобразуются в numpy массивы.

Я тестировал ваш код, теперь он работает:

training_label_seq = np.asarray(label_tokenizer.texts_to_sequences(T_L))

training_label_seq = np.array([np.array(training_element) for training_element in training_label_seq])

validation_label_seq = np.asarray(label_tokenizer.texts_to_sequences(V_L))



print('(training_label_seq[0:10]) = {}'.format((training_label_seq[0:10])))
print('(validation_label_seq[0:10]) = {}'.format((validation_label_seq[0:10])))

print('type(training_label_list[0]) = ', type(training_label_seq[0]))
print('type(validation_label_seq[0]) = ', type(validation_label_seq[0]))



(training_label_seq[0:10]) = [array([1]) array([1]) array([1]) array([1]) array([1]) array([1])
 array([1]) array([1]) array([1]) array([1])]
(validation_label_seq[0:10]) = [[16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]
 [16]]
type(training_label_list[0]) =  <class 'numpy.ndarray'>
type(validation_label_seq[0]) =  <class 'numpy.ndarray'>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...