Как установить форму / формат массива target (y) для множественной выходной регрессии в Keras? - PullRequest
0 голосов
/ 08 февраля 2019
ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 4 array(s), but instead got the following list of 1 arrays: [array([[115.,  23.,  37.,  27.,  60.,  35.,  77.,  50., 104., 134.,  99.,
         59.,  52., 179.,  77.,  85.],
       [495., 457., 601., 602., 586., 549., 558., 627., 552., 500., 524.,
        587....

Это ошибка, которую я получаю, когда запускаю следующий код :

inp = Input((480,640,3))
x = Dense(13, activation = 'relu')(inp)
out1 = Dense(1 , activation = 'linear')(x)
out2 = Dense(1 , activation = 'linear')(x)
out3 = Dense(1 , activation = 'linear')(x)
out4 = Dense(1 , activation = 'linear')(x)
model = Model(inp , [out1,out2,out3,out4])
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit_generator(generator = imageLoader(train_can , 16) , steps_per_epoch = 14000/16 , epochs = 1)

Функция imageLoader выглядит следующим образом:

def imageLoader(files, batch_size = 16):

   L = len(files)

#this line is just to make the generator infinite, keras needs that    
   while True:

     batch_start = 0
     batch_end = batch_size

     while batch_start < L:
        limit = min(batch_end, L)
        X = someMethodToLoadImages(files[batch_start:limit])
        Y = rearrange(train_y[batch_start:limit])

        yield (X,Y) #a tuple with two numpy arrays with batch_size samples     

        batch_start += batch_size   
        batch_end += batch_size

Функция someMethodToLoadImages имеет следующий вид:

def someMethodToLoadImages(files ):
    images =  np.empty((0,480,640,3) , float)
    for file in files:
         img =  image.load_img(os.path.join("G:/flipkart/images" , file ) ) #no target size required as all images are of same size
         images = np.append(images ,  image.img_to_array(img).reshape(1,480,640,3), axis = 0)
    return images/255.0

Функция переставить выглядит следующим образом:

def rearrange(arr):
   length = arr.shape[0]
   arr_ = np.ones((4,length))
   for i,sample in enumerate(arr):
       for index,number in enumerate(sample):
            arr_[index,i] = number
   return arr_

Как решить эту проблему?Я проверил подобные вопросы в стеке, но я все еще не могу найти решение.

---------------------------------------- UPDATE -------------------------------

inp = Input((480,640,3))
#x = Dense(13, activation = 'relu')(inp)
x = Conv2D(filters = 10, kernel_size = (3,3), strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)(inp)
x1 = Flatten()(x)
out1 = Dense(1 , activation = 'linear')(x1)
out2 = Dense(1 , activation = 'linear')(x1)
out3 = Dense(1 , activation = 'linear')(x1)
out4 = Dense(1 , activation = 'linear')(x1)

model = Model(inp , [out1,out2,out3,out4])
model.compile(loss='mean_squared_error', optimizer='adam')

print(model.summary())

Это сводка модели :

Model Summary

При запуске:

model.fit_generator(generator = imageLoader(train_can , 16) , steps_per_epoch = 14000/16 , epochs = 1)

Я получил:

ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 4 array(s), but instead got the following list of 1 arrays: [array([[115.,  23.,  37.,  27.,  60.,  35.,  77.,  50., 104., 134.,  99.,
     59.,  52., 179.,  77.,  85.],
   [495., 457., 601., 602., 586., 549., 558., 627., 552., 500., 524.,
    587....

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Вы звонили model.summary(), чтобы увидеть, какова выходная форма ваших 4 выходных слоев?В современной версии Keras это будет (None, 480, 640, 1) для каждого из ваших 4 выходных слоев (None - размер пакета).Это скорее всего не то, что вы хотите.Посмотрев на то, как вы генерируете свои Y -значения, я предполагаю, что вы хотите просто иметь вместо него (None, 1).

Однако, какой бы ни была реальная форма вывода, которую вы хотите иметь, чтобы ответить на вашвопрос: Y должен быть обычный список размером 4 (потому что у вас есть 4 выходных слоя), где каждый элемент этого списка должен быть массивом-пустышкой, форма которого идеально соответствует выходной форме соответствующеговыходной слой.В вашем случае все выходные слои имеют одинаковую форму.Таким образом, для данного model, как вы его представляете в своем вопросе,

Y = [np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1)), np.ones((batch_size, 480, 640, 1))]

будет правильным возвращаемым значением вашей rearrange функции.Первая запись этого списка будет применена к выводу out1, вторая к out2 и т. Д.

Если мое предположение верно, и вы действительно хотите иметь 4 формы вывода (None, 1), затем сначала (конечно) вы должны изменить дизайн своей модели, чтобы получить эти выходные формы.И тогда

Y = [np.ones((batch_size, 1)), np.ones((batch_size, 1)), np.ones((batch_size, 1)), np.ones((batch_size, 1))]

будет тем, что вам нужно.

Обратите внимание, обычный список необходим, только если выходные слои имеют разные выходные формы.В этом конкретном примере, однако, все ваши выходные формы одинаковы, так что вместо обычного списка вы также можете вернуть Y = np.ones((4, batch_size, 1)).Поскольку это почти то, что вы в настоящее время делаете (все, что вам нужно, это позвоните по номеру reshape((4, batch_size, 1)), чтобы добавить недостающее последнее измерение), я очень уверен, что вы просто неправильно поняли, как работают Dense слои.Они только изменяют последнее измерение входного тензора.Слой Flatten - это самый простой способ получить одномерный тензор (фактически, двумерный, если вы учитываете размер пакета).Опять же, model.summary() ваш друг.

0 голосов
/ 08 февраля 2019

Ваша модель имеет четыре выхода, поэтому вы должны иметь метки заземления в виде списка из четырех элементов.Вместо этого вы возвращаете один массив numpy.См. this для примера нескольких моделей ввода / вывода.

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