Fit with class_weights throws 3+ dimensional error

975 views
Skip to first unread message

gt1...@gmail.com

unread,
Mar 3, 2021, 4:24:39 PM3/3/21
to Keras-users
I am fitting a 3 class segmentation model in Keras 2.4.3 using model.fit and passing in a generator. When I pass in class_weight = {0:0.75,1:0.075,2:0.175} I get the following error:

(<class 'ValueError'>, ValueError('`class_weight` not supported for 3+ dimensional targets.'), <traceback object at 0x000002073FD271C8>)

I've used class weights successfully in 2.3 calling the fit_generator method. 

It seems that it comes from the rank of my y tensor.
from line 1397 of data_adapter.py

if y.shape.rank > 2:
   raise ValueError("`class_weight` not supported for "
   "3+ dimensional targets.")

What is the best method to apply weights to the Y  tensor with shape (200,160,3)? 

Thanks
Ryan

Lance Norskog

unread,
Mar 4, 2021, 9:25:41 PM3/4/21
to gt1...@gmail.com, Keras-users
Can you post a simple version of the code? 

--
You received this message because you are subscribed to the Google Groups "Keras-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to keras-users...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/keras-users/196ba212-c2a3-4f4a-9850-1b54c5f09347n%40googlegroups.com.


--
Lance Norskog
lance....@gmail.com
Redwood City, CA

Ryan H

unread,
Mar 5, 2021, 12:29:12 PM3/5/21
to Lance Norskog, Keras-users

Sure thing, I’ve stripped out what I deemed not necessary. If i’ve removed something critical let me know. Thanks

if __name__ == '__main__':
    num_cols = 160
    num_rows = 200
    num_classes = 3  
    # yields batches of images/segments in the shape (batches,num_rows,num_cols,1),(batches,num_rows,num_cols,num_classes)
    train_generator = image_segmentation_generator(image_path,
        segments_path,
        batch_size=20,
        n_classes=num_classes,
        input_height= num_rows,
        input_width=num_cols,
        output_height= num_rows,
        output_width=num_cols)
    model = BuildModel()
    model.compile(optimizer= keras.optimizers.Adam(learning_rate=0.001) ,loss = 'categorical_crossentropy', metrics=['categorical_accuracy'])
    model.fit_generator(train_generator,verbose=0,steps_per_epoch =20,epochs = 15,callbacks=[csv_logger,cb,mcp_save],class_weight=   {0:0.75,1:0.075,2:0.175}   )

def BuildModel(startingLayers = 14, convolutionSize = (3,3)):
    #num_cols = 160
    #num_rows = 200
    #num_classes = 3
    img_input = keras.layers.Input(shape=(num_cols,num_rows,1))# 8bit monochrome image scaled to 0 - 1

    conv1 = Conv2D(startingLayers, convolutionSize, activation='relu', padding='same')(img_input)
    conv1 = Dropout(0.2)(conv1)
    conv1 = Conv2D(startingLayers, convolutionSize, activation='relu', padding='same')(conv1)
    pool1 = MaxPooling2D((2, 2))(conv1)

    conv2 = Conv2D(startingLayers*2, convolutionSize, activation='relu', padding='same')(pool1)
    conv2 = Dropout(0.2)(conv2)
    conv2 = Conv2D(startingLayers*2, convolutionSize, activation='relu', padding='same')(conv2)
    pool2 = MaxPooling2D((2, 2))(conv2)

    conv3 = Conv2D(startingLayers*4, convolutionSize, activation='relu', padding='same')(pool2)
    conv3 = Dropout(0.2)(conv3)
    conv3 = Conv2D(startingLayers*4, convolutionSize, activation='relu', padding='same')(conv3)

    up1 = concatenate([UpSampling2D((2, 2))(conv3), conv2], axis=-1)
    conv4 = Conv2D(startingLayers*2, convolutionSize, activation='relu', padding='same')(up1)
    conv4 = Dropout(0.2)(conv4)
    conv4 = Conv2D(startingLayers*2, convolutionSize, activation='relu', padding='same')(conv4)

    up2 = concatenate([UpSampling2D((2, 2))(conv4), conv1], axis=-1)
    conv5 = Conv2D(startingLayers, convolutionSize, activation='relu', padding='same')(up2)
    conv5 = Dropout(0.2)(conv5)
    conv5 = Conv2D(startingLayers, convolutionSize, activation='relu', padding='same')(conv5)

    out = Conv2D( num_classes, (1, 1) , padding='same')(conv5)
    out2 = Reshape((num_cols*num_rows,-1))(out)
    out3= Activation("softmax")(out)

    return Model(inputs = img_input,outputs = out3 )

Lance Norskog

unread,
Mar 5, 2021, 3:19:54 PM3/5/21
to Ryan H, Keras-users
Maybe model.fit is using the training data as labels?

I think that the final Reshape is wrong. "-1" should always be first. Try printing the model.summary() to see what shape is being output.
Usually these networks have a Dense layer at the end to generate the class labels.

Ryan H

unread,
Mar 5, 2021, 6:28:12 PM3/5/21
to Lance Norskog, Keras-users
It seems that the reshape isn't being used (should have been removed). 

The output of the last layer is (None,200,160,3)  , I've also tried with the reshape, yielding (None,32000,3) but that also throws the same error. I also added a dense to this to yield (None,3) and it fails as well. 

My Y is shape (200,160,3) so rank is def>2.

It seems it's only expecting a rank 2 Y in the shape of (BatchSize,Num_Classes) not a segmented image like the attached. 

Should I scale each of my 3 class output layers with appropriate values when I build the model?
0.png
0.png

Lance Norskog

unread,
Mar 5, 2021, 9:38:49 PM3/5/21
to Ryan H, Keras-users
This is a working example of what you are trying to do in the output part:



william hamilton

unread,
Jan 26, 2023, 1:46:12 PM1/26/23
to Keras-users
Hey did you find a workaround for this? I have the same exact problem... it worked fine using an older version of tensorflow with keras but since updating to a newer tensorflow it's thrown the 3+ dimensions error when setting class_weights in .fit()   (also multi-class segmentation). Thanks!

Jozef Galandak

unread,
Mar 22, 2023, 5:15:39 PM3/22/23
to Keras-users
Hi, I have the same problem with SegNet segmentation network. Did you find any solution for this problem please ?? (@william hamilton ?)

Dátum: štvrtok 26. januára 2023, čas: 19:46:12 UTC+1, odosielateľ: william hamilton
Reply all
Reply to author
Forward
0 new messages