准确性在 keras 上的跨时代没有增长

Posted

技术标签:

【中文标题】准确性在 keras 上的跨时代没有增长【英文标题】:Accuracy not growing across epochs on keras 【发布时间】:2020-10-17 01:11:48 【问题描述】:

我是机器学习和深度学习的新手,我正在尝试使用神经网络对 5 个类别的文本进行分类。为此,我制作了一个字典,以便将单词转换为索引,最后得到一个包含索引列表的数组。此外,我将标签更改为整数。我也做了填充和那些东西。问题是,当我拟合模型时,准确度保持很低(~0.20)并且在各个时期都没有变化。我尝试更改了很多参数,比如词汇表的大小、神经元的数量、dropout 概率、优化器参数等。代码的关键部分如下。

# Arrays with indexes (that works fine)
X_train = tokens_to_indexes(tokenized_tr_mrp, vocab, return_vocab=False)
X_test, vocab_dict = tokens_to_indexes(tokenized_te_mrp, vocab)

# Labels to integers
labels_dict = 
labels_dict['Alzheimer'] = 0
labels_dict['Bladder Cancer'] = 1
labels_dict['Breast Cancer'] = 2
labels_dict['Cervical Cancer'] = 3
labels_dict['Negative'] = 4

y_train = np.array([labels_dict[i] for i in y_tr])
y_test = np.array([labels_dict[i] for i in y_te])

# One-hot encoding of labels
from keras.utils import to_categorical
encoded_train = to_categorical(y_train)
encoded_test = to_categorical(y_test)

# Padding
max_review_length = 235
X_train_pad = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test_pad = sequence.pad_sequences(X_test, maxlen=max_review_length)

# Model
# Vocab size
top_words = len(list(vocab_dict.keys()))
# Neurone type
rnn = LSTM
# dropout
set_dropout = True
p = 0.2
# embedding size
embedding_vector_length = 64
# regularization strength
L = 0.0005
# Number of neurones
N = 50

# Model
model = Sequential()
# Embedding layer
model.add(Embedding(top_words,
                   embedding_vector_length,
                   embeddings_regularizer=regularizers.l1(l=L),
                   input_length=max_review_length
                    #,embeddings_constraint=UnitNorm(axis=1)
                   ))

# Dropout layer
if set_dropout:
    model.add(Dropout(p))

# Recurrent layer
model.add(rnn(N))

# Output layer
model.add(Dense(5, activation='softmax'))

# Compilation
model.compile(loss='categorical_crossentropy',
             optimizer=Adam(lr=0.001),
             metrics=['Accuracy'])

# Split training set for validation
X_tr, X_va, y_tr_, y_va = train_test_split(X_train_pad, encoded_train, 
                                          test_size=0.3, random_state=2)

# Parameters
batch_size = 50
# N epochs
n_epocas = 20

best_val_acc  = 0
best_val_loss = 1e20
best_i        = 0

best_weights = []
acum_tr_acc = []
acum_tr_loss = []
acum_val_acc = []
acum_val_loss = []

# Training
for e in range(n_epocas):
    h = model.fit(X_tr, y_tr_,
                batch_size=batch_size,
                validation_data=(X_va, y_va),
                epochs=1, verbose=1)
  
    acum_tr_acc  = acum_tr_acc  + h.history['accuracy']
    acum_tr_loss = acum_tr_loss + h.history['loss']
    val_acc  = h.history['val_accuracy'][0]
    val_loss = h.history['val_loss'][0]
    acum_val_acc  = acum_val_acc  + [val_acc]
    acum_val_loss = acum_val_loss + [val_loss]
#   if val_acc  > best_val_acc:
    if val_loss < best_val_loss:
        best_i        = len(acum_val_acc)-1
        best_val_acc  = val_acc
        best_val_loss = val_loss
        best_weights = model.get_weights().copy()
    if len(acum_tr_acc)>1 and (len(acum_tr_acc)+1) % 1 == 0:
        if e>1:
            clear_output()

【问题讨论】:

你不能对一个输出神经元使用 softmax,你有 4 个类,对吧?然后你应该有 4 个输出神经元,并且 one-hot 编码你的标签(或使用稀疏分类交叉熵) 感谢您的回答。我使用 to_categorical 对我的标签(5 个类)进行了一次热编码,并将输出层更改为 Dense(5, activation=softmax)。但是现在准确率仍然是 0。有什么线索吗? 不说细节就难说了,是不是损失减少了?你能用你的新代码更新你的问题吗? 对不起。是的,损失正在减少。我确实更新了代码 【参考方案1】:

您发布的代码是非常糟糕的做法。

您可以使用当前方法训练n_epocas 并添加回调以获得最佳权重(例如ModelCheckpoint)或使用tf.GradientTape,但一次使用model.fit() 可能会导致奇怪的结果,因为您的优化器不知道它处于哪个时期。

我建议保留您当前的代码,但一次性训练n_epocas 并在此处报告结果(准确性 + 损失)。

【讨论】:

感谢您的建议。我按照你说的做了 (model.fit(epochs=20...)) 但准确率始终保持为 0。损失在验证集中波动,最小为 0.65。【参考方案2】:

有人给了我解决方案。我只需要更改这一行:

model.compile(loss='categorical_crossentropy',
             optimizer=Adam(lr=0.001),
             metrics=['Accuracy'])

为此:

model.compile(loss='categorical_crossentropy',
                 optimizer=Adam(lr=0.001),
                 metrics=['acc'])

我还更改了最终循环中与准确性有关的行。 one-hot 编码也是必要的。

【讨论】:

以上是关于准确性在 keras 上的跨时代没有增长的主要内容,如果未能解决你的问题,请参考以下文章

精度随着时代的增加而降低

keras.models.Model.fit 中的“时代”是啥?

如何在 scikit-learn 管道中将时代添加到 Keras 网络

精细化运营时代,金融魔镜如何助力各产品线实现业务增长

数据爆发时代,英特尔携手腾讯构筑全面的数据长城

巨头洼地:B2B电商3.0时代将诞生万亿级估值企业