Tensorflow : Logits와 Label은 크기가 같아야합니다.

Sep 03 2020

저는 현재 다음과 같이 획득 한 데이터 세트를 사용하여 Google / Udacity의 Tensorflow 과정에서 프로젝트를 시도하고 있습니다.

_URL = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"

zip_file = tf.keras.utils.get_file(origin=_URL,
                                   fname="flower_photos.tgz",
                                   extract=True)

불행히도 다음 오류가 발생했습니다.

InvalidArgumentError:  logits and labels must have the same first dimension, got logits shape [100,5] and labels shape [500]
     [[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at <ipython-input-43-02964d57939c>:8) ]] [Op:__inference_test_function_3591]

다른 게시물을 살펴 보았지만 여전히 파악하기가 조금 까다로 웠습니다. 처음에는 잘못된 손실 기능을 사용하고있을 수 있다고 생각했습니다.

다음은 문제가있는 코드입니다.

image_gen = ImageDataGenerator(rescale = 1./255, horizontal_flip=True, zoom_range=0.5, rotation_range=45, width_shift_range=0.15, height_shift_range=0.15)

train_data_gen = image_gen.flow_from_directory(batch_size=BATCH_SIZE, directory = train_dir, shuffle=True, target_size=(IMG_SHAPE,IMG_SHAPE),class_mode='binary')

image_gen = ImageDataGenerator(rescale = 1./255)

val_data_gen = image_gen.flow_from_directory(batch_size=BATCH_SIZE, directory = val_dir, shuffle=True, target_size=(IMG_SHAPE,IMG_SHAPE))


model = tf.keras.models.Sequential([
                                    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150,150,3)),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
                                    tf.keras.layers.MaxPooling2D(2,2),
                                    tf.keras.layers.Dropout(0.5),
                                    tf.keras.layers.Flatten(),
                                    tf.keras.layers.Dense(512, activation='relu'),
                                    tf.keras.layers.Dense(5),
                                    
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
model.summary()

배치 크기는 100이고 입력 차원은 150,150입니다. 요약은 다음과 같습니다. 모델 : "순차적 _4"


레이어 (유형) 출력 모양 매개 변수 #

conv2d_12 (Conv2D) (없음, 148, 148, 16) 448


max_pooling2d_12 (MaxPooling (없음, 74, 74, 16) 0


conv2d_13 (Conv2D) (없음, 72, 72, 32) 4640


max_pooling2d_13 (MaxPooling (없음, 36, 36, 32) 0


conv2d_14 (Conv2D) (없음, 34, 34, 64) 18496


max_pooling2d_14 (MaxPooling (없음, 17, 17, 64) 0


dropout_4 (드롭 아웃) (없음, 17, 17, 64) 0


flatten_4 (Flatten) (없음, 18496) 0


density_8 (밀도) (없음, 512) 9470464


density_9 (밀도) (없음, 5) 2565

총 매개 변수 : 9,496,613 학습 가능한 매개 변수 : 9,496,613 학습 불가능한 매개 변수 : 0

무엇이 잘못되었을 지에 대한 생각이 있습니까?

답변

1 MarcoCerliani Sep 03 2020 at 03:59

생성기의 class_mode에주의

'int': 레이블이 정수로 인코딩됨을 의미합니다 (예 : sparse_categorical_crossentropy 손실의 경우). 'categorical'은 레이블이 범주 형 벡터로 인코딩됨을 의미합니다 (예 : categorical_crossentropy 손실의 경우). 'binary'는 레이블 (2 개만있을 수 있음)이 값이 0 또는 1 인 float32 스칼라로 인코딩됨을 의미합니다 (예 : binary_crossentropy의 경우). 없음 (레이블 없음).

기차 및 유효성 검사 생성기 모두에 'binary'대신 'int'가 필요한 것 같습니다.