首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何更正此错误: ValueError: logits和labels必须具有相同的形状((None,2) vs (None,1))

如何更正此错误: ValueError: logits和labels必须具有相同的形状((None,2) vs (None,1))
EN

Stack Overflow用户
提问于 2021-02-08 22:59:46
回答 1查看 223关注 0票数 0

我是CNNs的新手,所以我猜我在这里犯了一个基本的错误。我正在尝试对UTKFace数据集进行年龄估计和性别分类。我制作了一个数据帧,看起来像这样:

我已经使用Sklearn train_test_split拆分了数据

代码语言:javascript
复制
train_validation, test_df = train_test_split(df, test_size=0.25)


train_df, validation_df = train_test_split(train_validation, test_size=0.3333)

我写了下面的代码来做一些数据扩充:

代码语言:javascript
复制
from keras.preprocessing.image import ImageDataGenerator


train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True,
    fill_mode = 'nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
 
batch_size = 32

train_generator = train_datagen.flow_from_dataframe(
    train_df,
    x_col="file",
    y_col=["age","gender"],
    batch_size=batch_size,
    class_mode='multi_output')

val_generator = test_datagen.flow_from_dataframe(
    validation_df,
    x_col="file",
    y_col=["age","gender"],
    batch_size=batch_size,
    class_mode='multi_output')

然后我编辑了这篇文章(https://towardsdatascience.com/building-a-multi-output-convolutional-neural-network-with-keras-ed24c7bc1178)中的模型,只有模型的年龄和性别分支:

代码语言:javascript
复制
class UtkMultiOutputModel():

    def make_default_hidden_layers(self, inputs):
        """
        Used to generate a default set of hidden layers. The structure used in this network is defined as:
        
        Conv2D -> BatchNormalization -> Pooling -> Dropout
        """

        
        x = Conv2D(16, (3, 3), padding="same")(inputs)
        x = Activation("relu")(x)
        x = BatchNormalization(axis=-1)(x)
        x = MaxPooling2D(pool_size=(3, 3))(x)
        x = Dropout(0.25)(x)
        x = Conv2D(32, (3, 3), padding="same")(x)
        x = Activation("relu")(x)
        x = BatchNormalization(axis=-1)(x)
        x = MaxPooling2D(pool_size=(2, 2))(x)
        x = Dropout(0.25)(x)
        x = Conv2D(32, (3, 3), padding="same")(x)
        x = Activation("relu")(x)
        x = BatchNormalization(axis=-1)(x)
        x = MaxPooling2D(pool_size=(2, 2))(x)
        x = Dropout(0.25)(x)
        return x
  
    def build_gender_branch(self, inputs, num_genders=2):
        """
        Used to build the gender branch of our face recognition network.
        This branch is composed of three Conv -> BN -> Pool -> Dropout blocks, 
        followed by the Dense output layer.
        """
        x = Lambda(lambda c: tf.image.rgb_to_grayscale(c))(inputs)
        x = self.make_default_hidden_layers(inputs)
        x = Flatten()(x)
        x = Dense(128)(x)
        x = Activation("relu")(x)
        x = BatchNormalization()(x)
        x = Dropout(0.5)(x)
        x = Dense(num_genders)(x)
        x = Activation("sigmoid", name="gender_output")(x)
        return x
    def build_age_branch(self, inputs):   
        """
        Used to build the age branch of our face recognition network.
        This branch is composed of three Conv -> BN -> Pool -> Dropout blocks, 
        followed by the Dense output layer.
        """
        x = self.make_default_hidden_layers(inputs)
        x = Flatten()(x)
        x = Dense(128)(x)
        x = Activation("relu")(x)
        x = BatchNormalization()(x)
        x = Dropout(0.5)(x)
        x = Dense(1)(x)
        x = Activation("linear", name="age_output")(x)
        return x
    def assemble_full_model(self, width, height):
        """
        Used to assemble our multi-output model CNN.
        """
        input_shape = (height, width, 3)
        inputs = Input(shape=input_shape)
        age_branch = self.build_age_branch(inputs)
        gender_branch = self.build_gender_branch(inputs)
        model = Model(inputs=inputs,
                     outputs = [age_branch, gender_branch],
                     name="modelA")
        return model
    
num_races=len(dataset_dict['race_alias']))
modelA = UtkMultiOutputModel().assemble_full_model(IM_WIDTH, IM_HEIGHT)
modelA.summary()

然后我训练并编译:

代码语言:javascript
复制
from keras.optimizers import Adam
init_lr = 1e-4
epochs = 100
opt = Adam(lr=init_lr, decay=init_lr / epochs)
modelA.compile(optimizer=opt, 
              loss={ 
                  'age_output': 'mean_squared_error',  
                  'gender_output': 'binary_crossentropy'},
              loss_weights={
                  'age_output': 4., 
                  'gender_output': 0.1},
              metrics={
                  'age_output': 'mean_absolute_error', 
                  'gender_output': 'accuracy'})
batch_size = 32
history = modelA.fit_generator(train_generator, 
                    steps_per_epoch=len(train_df)//batch_size,
                    epochs=20,
                    validation_data=val_generator,
                    validation_steps=len(validation_df)//batch_size) 

我得到了以下错误,我正在努力理解它。

代码语言:javascript
复制
    ValueError: logits and labels must have the same shape ((None, 2) vs (None, 1))

从这里的其他帖子中可以看出,这可能是由于标签的尺寸错误。我不明白当我使用Keras flow_from_dataframe的时候,怎么会出现这种情况,它的数据帧格式跟我一样。有人能帮上忙吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-08 23:12:25

logits可能是单热编码的。但是,您的性别列仅为1和0。尝试对它们进行一次热编码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66104028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档