Использование fit_generator в Керасе - PullRequest
2 голосов
/ 08 марта 2020

Я новичок в использовании fit_generator в Керасе, поэтому я попытался написать простой скрипт, чтобы помочь мне понять, как он работает.

X = np.array([[1,2],[10,3],[2,4],[20,5],[30,1],[3,5],[4,6],[7,4],[5,10],[1,7]])
Y = np.array([[2,3],[30,13],[8,6],[100,25],[30,31],[15,8],[24,10],[28,11],[50,15],[7,8]])

def generator(feat,labels):
    i=0
    while (True):
        yield feat[i],labels[i]
        i+=1

model_fnn = tf.keras.models.Sequential()
model_fnn.add(tf.keras.layers.Dense(50, input_dim=X.shape[1], activation=tf.nn.relu))
model_fnn.add(tf.keras.layers.Dense(Y.shape[1], activation=tf.keras.activations.linear))

nb_epoch = 3000

model_fnn.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])
model_fnn.fit_generator(generator(X,Y), steps_per_epoch=10, epochs=nb_epoch, verbose=0)

Но это дало мне ошибку:

ValueError: Error when checking input: expected dense_2_input to have shape (2,) but got array with shape (1,)

Может ли кто-нибудь помочь, пожалуйста? Спасибо!

Ответы [ 2 ]

3 голосов
/ 09 марта 2020

Эта ошибка, по-видимому, вызвана тем фактом, что вам нужно свернуть каждый ввод / метку в массив Numpy, который будет тренировочной партией. Код для этого генератора будет:

def generator(feat,labels):
    i=0
    while (True):
        yield np.array([feat[i]]), np.array([labels[i]])
        i+=1

И ваша ошибка должна быть устранена. Вы будете тренироваться с размером партии 1, так как каждый массив, переданный на обучение, будет содержать только 1 объект.

Но, чтобы тренироваться с использованием генератора с выходом, вы должны убедиться, что цикл не будет cra sh, так как это бесконечный l oop, а у вас нет бесконечных данных. Это может быть достигнуто с помощью itertools.cycle:

import itertools

def generator(feat,labels):
    pairs = [(x, y) for x in feat for y in labels]
    cycle_pairs = itertools.cycle(pairs)
    while (True):
        f, p = next(cycle_pairs)
        return np.array([f]), np.array([p])

И, чтобы сделать еще один шаг в использовании генераторов, использующих yield, вы можете дать функции параметр для указания размера пакета (как указано в комментарий от PyGirl ). Это должно выглядеть примерно так:

def generator(feat, labels, batch_size):
    pairs = [(x, y) for x in feat for y in labels]
    cycle_pairs = itertools.cycle(pairs)
    while (True):
        x = []
        y = []
        for _ in range(batch_size):
            f, p = next(cycle_pairs)
            x.append(f)
            y.append(p)
        yield np.array(x), np.array(y)

Это означает, что на каждом шаге генератор будет выдавать массив Numpy с batch_size элементами для обучения.

Чтобы больше узнать о том, как тренироваться с fit_generator в Керасе, я бы также порекомендовал прочитать немного о Последовательности Кераса , который безопаснее использовать, чем генератор.

Позвольте Я знаю, если это поможет!

1 голос
/ 08 марта 2020

Я не уверен, но если вы добавите размер пакета 1, то это сработает, то есть, разверните (2,) -> (1,2)

def generator(feat,labels, batch_size):

  samples_per_epoch = feat.shape[0]
  number_of_batches = samples_per_epoch/batch_size
  counter=0

  while 1:

    X_batch = np.array(feat[batch_size*counter:batch_size*(counter+1)]).astype('float32')
    y_batch = np.array(labels[batch_size*counter:batch_size*(counter+1)]).astype('float32')
    counter += 1
    yield X_batch,y_batch

    #restart counter to yeild data in the next epoch as well
    if counter >= number_of_batches:
        counter = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...