Keras - плотность_3 имеет неправильный плотный (6,), но должен быть (1,) - PullRequest
0 голосов
/ 22 марта 2020

Я изучаю нейронные сети и хочу создать модель, которая предсказывает стоимость домена. Чтобы упростить, я создал drank, который может быть 0,1,2,3,4 или 5.

То, что я делаю:

  1. изменение кадра данных, фильтрация данных и т. Д. c
  2. токенизация доменных имен в двумерный массив целых чисел (на основе символов)
  3. разбиение на X, y train, тест
  4. модель компиляции

Выходные данные должны быть от 0 до 5 целых чисел, так что последний слой должен иметь форму (6,), по моему мнению. Но очевидно, что что-то не так.

ValueError: Ошибка при проверке цели: ожидается, что плотность_3 имеет форму (6,), но получен массив с формой (1,)

Вы знаете, что делать?

from datetime import timedelta, date, datetime
import json
import locale

from keras import Sequential
from keras.layers import Dense
from keras_preprocessing.sequence import pad_sequences
from keras_preprocessing.text import Tokenizer
import pandas as pd
from sklearn.model_selection import train_test_split

locale.setlocale(locale.LC_ALL, '')
LISTINGS_JSON_PATH = '....path to json'

def get_drank(rank):
    if rank>5:
        return 5
    return rank

with open(LISTINGS_JSON_PATH) as f:
    d = json.loads(f.read())

today = datetime.combine(date.today(), datetime.min.time())
df = pd.DataFrame(d['data'])
df = df[['domainName', 'auctionEndTime', 'numberOfBids']]
df['domainName'] = df['domainName'].str.lower()
df['auctionEndTime'] = pd.to_datetime(df['auctionEndTime'].str.slice(0, 10), format='%Y-%m-%d')
df['days_to_end'] = df['auctionEndTime'].apply(lambda x: (x - today).days + 1)
df['rank'] = df['numberOfBids'] * (df['days_to_end'])
df['drank'] = df['rank'].apply(lambda x:get_drank(x))
df = df[(df['rank'] != 0.0)|(df['days_to_end']==0.0)]

tk = Tokenizer(num_words=None, char_level=True)
tk.fit_on_texts(df['domainName'])
sequences = tk.texts_to_sequences(df['domainName'])
sequences = pad_sequences(sequences, padding='post')

X_train, X_test, y_train, y_test  = train_test_split(sequences, df['drank'], test_size=0.2, random_state=1)

print(X_train)
print(X_test)

model = Sequential([
    Dense(32, activation='relu', input_shape=(sequences[0].__len__(),)),
    Dense(32, activation='relu'),
    Dense(6, activation='softmax'),
])

model.compile(optimizer='adam',
              loss='categorical_crossentropy', )

hist = model.fit(X_train, y_train,
                 batch_size=32, epochs=10,
                 validation_data=(X_test, y_test))

OUT:

[[15  5 11 ...  0  0  0]
 [11 21  6 ...  0  0  0]
 [12  1  3 ...  0  0  0]
 ...
 [ 8  1  1 ...  0  0  0]
 [ 3  1  8 ...  0  0  0]
 [20  1 14 ...  0  0  0]]
187869    0
14522     0
191921    0
38952     0
273009    0
         ..
117583    0
73349     0
416735    5
267336    0
128037    0

1 Ответ

0 голосов
/ 22 марта 2020

Выходные данные должны быть от 0 до 6 целых чисел, поэтому последний слой должен иметь форму (4,), на мой взгляд.

Я не уверен, что вы подразумеваете под этим утверждением , Вы имеете в виду форму (1,) или форму (7,)?

Сначала вам нужно определить, должно ли drank быть порядковым или номинальным .

В порядковом случае это означает, что порядок целочисленных значений для выходной метки имеет значение. Например, если выходные данные равны 1 или 0, где 1 означает ВЫСОКИЙ, а 0 означает НИЗКИЙ, тогда логическое значение имеет порядок 0 < 1. Тогда, если ваша выходная форма Y_train, Y_test - это форма (1,), вам нужно изменить функцию потерь на loss=sparse_categorical_cross_entropy.

В номинальном случае порядок не имеет значения. Например, если y принимает значения между APPLE, ORANGE и BANANA, у нас может быть такой массив:

# Original data: 0=apple, 1=orange, 2=banana
y = [ [2], [0], ...]
# One hot encoded
y = [ [0,0,1],  # For banana
      [1,0,0],  # for apple
    ]

, где APPLE < BANANA не имеет никакого смысла. Это можно сделать, используя sklearn.preprocessing.OneHotEncoder и преобразовав ваши цели в приведенную выше форму, и ваша модель архитектуры должна работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...