模型返回错误 - ValueError:logits和labels必须具有相同的形状((无,18)vs(无,1))

3

我正在研究基于Keras的多标签分类器。我创建了一个函数,用于加载训练和测试数据,然后在函数内部对X/Y进行处理/拆分。但是,在运行模型时出现了错误,但不确定意思:

以下是我的代码:

def KerasClassifer(df_train, df_test):
  X_train = df_train[columnType].copy()
  y_train = df_train[variableToPredict].copy()
  labels = y_train.unique()
  print(X_train.shape[1])
  #using keras to do classification
  from tensorflow import keras
  from tensorflow.keras.models import Sequential
  from tensorflow.keras.layers import Dense, Dropout, Activation
  from tensorflow.keras.optimizers import SGD

  model = Sequential()
  model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))
  model.add(Dropout(0.1))
  model.add(Dense(600, activation='relu'))
  model.add(Dropout(0.1))
  model.add(Dense(len(labels), activation='sigmoid'))

  sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
  model.compile(loss='binary_crossentropy',
                optimizer=sgd)

  model.fit(X_train, y_train, epochs=5, batch_size=2000)

  preds = model.predict(X_test)
  preds[preds>=0.5] = 1
  preds[preds<0.5] = 0

  score = model.evaluate(X_test, y_test, batch_size=2000)
  score

以下是我的数据属性(如果有帮助):
x train shape  (392436, 109)
y train shape  (392436,)
len of y labels 18

我该如何修复代码以避免出现此错误?
2个回答

5
如果你有18个类别,y_train的形状应该是(392436, 18)。你可以使用tf.one_hot来实现:
import tensorflow as tf

y_train = tf.one_hot(y_train, depth=len(labels))

如果您的价值观只来自于一列,我怀疑这不是“multi-label”,而是多类别问题。一个样本可以真的属于多个类别吗?如果不行,那么您还需要做一些其他变更。例如,您需要使用softmax激活:
model.add(Dense(len(labels), activation='softmax'))

此外,还有分类交叉熵损失函数:

model.compile(loss='categorical_crossentropy', optimizer=sgd)

4

如果你的标签是一维的,而你的目标是进行多标签任务,那么你需要对它们进行独热编码。你可以简单地使用

tf.keras.utils.to_categorical(y, num_classes)

这样可以将你的目标从 (n_sample) 转换为 (n_sample, num_classes)。

如果这只是一个简单的多类别问题,那么你有以下两种可能性:

1) 如果你有一维整数编码的目标,你可以使用 sparse_categorical_crossentropy 作为损失函数,并使用 softmax 激活函数生成概率。

n_class = 3
n_features = 100
n_sample = 1000

X = np.random.randint(0,10, (n_sample,n_features))
y = np.random.randint(0,n_class, n_sample)

inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)

model = Model(inp, out)
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)

pred = np.argmax(model.predict(X), 1)

第二种可能) 如果您已经对目标进行了one-hot编码以获得2D形状(n_samples, num_classes),则可以使用具有softmax激活的categorical_crossentropy来生成概率。

n_class = 3
n_features = 100
n_sample = 1000

X = np.random.randint(0,10, (n_sample,n_features))
y = tf.keras.utils.to_categorical(np.random.randint(0,n_class, n_sample))

inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)

model = Model(inp, out)
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)

pred = np.argmax(model.predict(X), 1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接