Keras Conv2D CNN — ошибка при проверке цели — ожидаемый меньший результат

Я складываю 6 слоев 2D-спутниковых изображений (данные x) и пытаюсь запустить CNN по ним, чтобы классифицировать земной покров (используя 8 классов земного покрова, взятых из переформатированного слоя данных о культурах Министерства сельского хозяйства США - данные y).

Данные x сформированы (2004, 2753, 6), а y сформированы (2004, 2753, 8) изначально, и я использовал data_x.reshape(-1,2004,2752,6) (то же самое для y), чтобы добавить дополнительное измерение в качестве модели.

8 категорий в наборе данных y представляют 8 возможных категорий земного покрова в числовом формате в 8 диапазонах (т. е. 1-й диапазон — это кукуруза и представлен единицами для положительного результата и 0 для отсутствия кукурузы).

Однако, когда я пытаюсь запустить модель, ожидаемая форма не соответствует тому, что ей передается. Я не уверен, использую ли я правильную структуру модели или структуру данных - одной из идей было бы взять 8 полос набора данных y.

Основываясь на серьезном поиске в Google, я научился получать данные в правильном формате с правильным количеством измерений и т. д., но чувствую, что падаю на последнее препятствие в отношении измерений (и, скорее всего, правильная подготовка данных x & y наборы).

Ниже представлена ​​модель CNN.

input_shape=([2004, 2753, 6])

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),strides=(1, 1),activation='relu',input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2, 2), padding="same"))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2), padding="same"))
model.add(Dropout(0.25))
#model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(8, activation='softmax'))
#model.add(Flatten())
model.summary()

Резюме модели - ожидаем 500, 687, 8 в конце

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_54 (Conv2D)           (None, 2002, 2751, 32)    1760      
_________________________________________________________________
max_pooling2d_52 (MaxPooling (None, 1001, 1376, 32)    0         
_________________________________________________________________
conv2d_55 (Conv2D)           (None, 999, 1374, 32)     9248      
_________________________________________________________________
max_pooling2d_53 (MaxPooling (None, 500, 687, 32)      0         
_________________________________________________________________
dropout_57 (Dropout)         (None, 500, 687, 32)      0         
_________________________________________________________________
dense_59 (Dense)             (None, 500, 687, 128)     4224      
_________________________________________________________________
dropout_58 (Dropout)         (None, 500, 687, 128)     0         
_________________________________________________________________
dense_60 (Dense)             (None, 500, 687, 8)       1032      
=================================================================
Total params: 16,264
Trainable params: 16,264
Non-trainable params: 0
_________________________________________________________________

компилировать

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(loss='categorical_crossentropy',
            optimizer='sgd',
            metrics=['accuracy'])

fit - и где я получаю сообщение об ошибке

history = model.fit(x_train3d, y_train3d,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_split=0.2, validation_data=None)

форма x_train3D = (1, 2004, 2753, 6) форма y_train3D = (1, 2004, 2753, 8)

сообщение об ошибке

ValueError: Error when checking target: expected dense_58 to have shape (500, 687, 8) but got array with shape (2004, 2753, 8)

Опять же, я подозреваю, что это связано с необходимостью получения данных в правильном формате как для ввода, так и для вывода, но также, вероятно, что-то не так в спецификации модели. Буду признателен за некоторые рекомендации, поскольку я новичок в Керасе.


person Andrew Holden    schedule 25.08.2019    source источник
comment
Что представляет собой y?   -  person gorjan    schedule 25.08.2019
comment
Y — данные о земном покрове, это растровый файл, который охватывает 8 категорий земного покрова (например, сельскохозяйственные культуры, города, вода и т. д.), взятые из уровня данных о культурах. Это данные, на которых я хочу обучить спутниковое изображение. developers.google.com/earth-engine/datasets/catalog/   -  person Andrew Holden    schedule 25.08.2019


Ответы (2)


Не могли бы вы объяснить, что вы пытаетесь классифицировать и каков ваш ожидаемый y_train3D (это изображение или какое-то значение для классификации, например, 1/2/3.. или x/y/z..etc)

person mkAllThings    schedule 25.08.2019
comment
Я пытаюсь классифицировать земной покров, используя спутниковые данные (6-канальное изображение от Sentinel 2) - в основном пытаюсь провести различие между кукурузой и соей (и 6 другими категориями земного покрова, всего 8). y_train3D — это растровый файл земного покрова США, разделенный на 8 категорий. так что это растровое изображение с 8 возможными категориями (надеюсь, это поможет прояснить) разработчики. google.com/earth-engine/datasets/catalog/ - person Andrew Holden; 25.08.2019

Просто для обновления по этому поводу - мне удалось устранить ошибку (а теперь об ошибке памяти, но это другой вопрос).

Решил проблему 2 способами. 1. В конец модели добавлена ​​повышающая дискретизация, чтобы вернуть данные к исходному размеру — новый код ниже.

model = Sequential()
model.add(Conv2D(32, (3, 3), padding="same", activation="relu",input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2, 2)))

model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3), padding="same", activation="relu"))

#Upsampling
model.add(UpSampling2D(size=(2,2),interpolation='nearest'))
model.add(UpSampling2D(size=(2,2),interpolation='nearest'))

model.add(Dense(8, activation='relu'))
model.summary()

Дайте мне следующее резюме


Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 2004, 2752, 32)    1760      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 1002, 1376, 32)    0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 1002, 1376, 64)    18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 501, 688, 64)      0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 501, 688, 128)     73856     
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 1002, 1376, 128)   0         
_________________________________________________________________
up_sampling2d_2 (UpSampling2 (None, 2004, 2752, 128)   0         
_________________________________________________________________
dense_1 (Dense)              (None, 2004, 2752, 8)     1032      
=================================================================
Total params: 95,144
Trainable params: 95,144
Non-trainable params: 0

Часть 2 — обеспечение того, чтобы массивы данных x и y делились на 4, в противном случае это означало, что я терял часть данных в модели из-за округления. Приведенное ниже относится к моему коду и не является надежным, но работает

if x_train3d.shape[2] % 2:
    x_train3d_adj =  x_train3d_adj[:,:,:-1,:]
    y_train3d_adj =  y_train3d_adj[:,:,:-1,:]

Еще не полное решение, но приближает меня к конечной цели

person Andrew Holden    schedule 27.08.2019