Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary classification with additional dimension (subclasses)

Suppose I have an array of 10 observations (belong to class A or B), 5 columns and 2 subclasses (C, D) as an additional dimension and I would like to make a binary classification (to A or B class) in Keras R. What should the network architecture look like in this case?

library("keras")

df = data.frame(class = c(rep("A", 10), rep("B", 10)),
                subclass = rep(c("C", "D"), 10),
                feature1 = rnorm(20),
                feature2 = rnorm(20),
                feature3 = rnorm(20))

df1 = df[df$subclass == "C", ]
df2 = df[df$subclass == "D", ]
df_list = list(df1, df2)

build_model = function() {
  model = keras_model_sequential() 

  model %>%
    # input_shape is 3 features and 2 subclasses
    layer_dense(units = 2, activation = 'sigmoid', input_shape = c(3, 2))

  model %>%
    compile(
      optimizer = "adam",
      loss = "binary_crossentropy",
      metrics = list("accuracy")
    )
}

# one hot encoding to A, B classes
labels = to_categorical(as.integer(df_list[[1]][, "class"]) - 1)

# drop factor columns
data = lapply(df_list, function(x) x[, -(1:2)])

# convert to array
data_array = array(unlist(c(data[[1]], data[[2]])), dim = c(10, 3, 2))

model = build_model()

# error appears in the following function:
history = model %>% fit(
  x = data_array,
  y = labels
)

Error:

Error in py_call_impl(callable, dots$args, dots$keywords):

ValueError: A target array with shape (10, 2) was passed for an output of shape (None, 3, 2) while using as loss binary_crossentropy. This loss expects targets to have the same shape as the output.

That error is related to the difference between dimensions of the input and output data, but I don't know what it should look like correctly. My sample data dimensions are 10 observations, 3 features and 2 subclasses.

Model info:

Model: "sequential"
____________________________________________________________________
Layer (type)                Output Shape               Param #    
====================================================================
dense (Dense)               (None, 3, 2)               6          
====================================================================
Total params: 6
Trainable params: 6
Non-trainable params: 0
____________________________________________________________________
like image 619
nukubiho Avatar asked Nov 18 '25 08:11

nukubiho


1 Answers

Your error says that your model output shape is (None, 3, 2) but you give him output with shape (10,2) (labels). To fix this you should fix your input shape: Your input shpt is 3, not (3,2) because you have 3 features and you expect to have 2 outputs.

Change this line:

layer_dense(units = 2, activation = 'sigmoid', input_shape = c(3, 2))

to this:

layer_dense(units = 2, activation = 'sigmoid', input_shape = c(3))

I tested it with python, and it seems to work well:

import keras
model = keras.Sequential()
model.add(keras.layers.Dense(units = 2,activation="sigmoid",input_shape=(3,)))
model.summary()


Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_4 (Dense)              (None, 2)                 8         
=================================================================
Total params: 8
Trainable params: 8
Non-trainable params: 0
_________________________________________________________________
like image 143
Dvir Samuel Avatar answered Nov 19 '25 22:11

Dvir Samuel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!