Получение ValueError: numpy не может изменить массив размером 5342252 в размер (5342252, 200, 1) во время обучения lstm - PullRequest
0 голосов
/ 19 сентября 2018

Я тренирую генератор текста lstm, чтобы воссоздать текст Шекспира в качестве учебного упражнения.Тем не менее, мой код получает ошибку при запуске.ValueError: cannot reshape array of size 5342252 into shape (5342252,200,1) Буду признателен за любую помощь, так как я все еще изучаю основы lstm и rnn's.Мой код Python:

import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.callbacks import ModelCheckpoint
from keras.utils import np_utils

filename = "shakespeare.txt"
raw_text = open(filename, 'r').read()

chars = sorted(list(set(raw_text)))
char_to_int = {c:i for i, c in enumerate(chars)}

n_chars = len(raw_text)
n_vocab = len(chars)

seq_length = 200
dataX = []
dataY = []
for i in range(0, n_chars - seq_length):
    seq_in = raw_text[i: i+seq_length]
    seq_out = raw_text[i+seq_length]
    dataX.append([char_to_int[char]] for char in seq_in)
    dataY.append(char_to_int[seq_out])
n_patterns = len(dataX)

dataX = numpy.array(dataX)
X = numpy.reshape(dataX, (n_patterns, seq_length, 1))
X = X / float(n_vocab)
y = np_utils.to_categorical(dataY)

lstm = Sequential()
lstm.add(LSTM(256, input_shape=(X.shape[1], X.shape[2])))
lstm.add(Dropout(0.2))
lstm.add(Dense(y.shape[1], activation='softmax'))
lstm.compile(loss='categorical_crossentropy', optimizer='adam')

filepath = "weights-improvement-{epoch:02d}-{loss:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, 
save_best_only=True, mode='min')
callbacks_list = [checkpoint]

lstm.fit(X, y, epochs=20, batch_size=128, callbacks=callbacks_list)

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Проблема в том, что dataX.append(...) добавляет в конец списка в одну длинную последовательность.Вам нужно создать двумерный массив данных, для которого один из вариантов - объявить ваши dataX и dataY как массивы с нуля для начала и добавить большее количество массивов с фигурами (1, seq_length).См. Реализацию ниже

seq_length = 200
dataX = numpy.empty((0,seq_length))
dataY = numpy.empty((0,1))
for i in range(0, n_chars - seq_length):
    seq_in = raw_text[i: i+seq_length]
    seq_out = raw_text[i+seq_length]
    new x = numpy.array([[char_to_int[char]] for char in seq_in]).reshape(1,-1)
    newy = numpy.array([char_to_int[seq_out]]).reshape(1,-1)
    dataX = numpy.append(dataX, newx, axis=0)
    dataY = numpy.append(dataY, newy, axis=0)
n_patterns = len(dataX)

Однако это зависит от расширения массивов dataX и dataY, что является медленным.Более быстрый способ состоит в том, чтобы выделить обе эти памяти заранее:

seq_length = 200
dataX = numpy.zeros((n_chars-seq_length,seq_length))
dataY = numpy.zeros((n_chars-seq_length,1))
for i in range(0, n_chars - seq_length):
    seq_in = raw_text[i: i+seq_length]
    seq_out = raw_text[i+seq_length]
    dataX[i] = [char_to_int[char] for char in seq_in]
    dataY[i] = [char_to_int[seq_out]]
n_patterns = len(dataX)

В качестве альтернативы, не являющейся пустой, вы можете просто добавить несколько квадратных скобок к добавляемому элементу, сделав

seq_length = 200
dataX = []
dataY = []
print(numpy.shape(dataX))
for i in range(0, n_chars - seq_length):
    seq_in = raw_text[i: i+seq_length]
    seq_out = raw_text[i+seq_length]
    dataX.append([[char_to_int[char]] for char in seq_in])
    dataY.append([char_to_int[seq_out]])
n_patterns = len(dataX)

хотя это будет медленнее, чем в предыдущем методе.

0 голосов
/ 19 сентября 2018

Чтобы изменить форму,

X = numpy.reshape(dataX, (n_patterns, seq_length, 1))

размеры должны соответствовать.5342252 x 200 x 1 = 1 064 505 600 должно быть количеством элементов в dataX, если вы хотите эту форму.

Не ясно, чего вы пытаетесь достичь, но я предполагаю, что

n_patterns = len(dataX)

должно быть

n_patterns = len(dataX)/seq_length
...