在深度学习中,经常会使用到Keras、PyTorch、TensorFlow等框架。在使用这些框架进行模型训练时,我们会遇到一些错误,如KeyError”acc”和KeyError:”val_acc”等。这些错误是由于模型的指标名称与训练过程中所使用的名称不匹配导致的。接下来,我将详细讲解如何解决这些问题。
问题描述
在进行深度学习模型训练时,通常需要指定评估指标。常见的评估指标有精度(accuracy)、准确率(precision)、召回率(recall)、F1值等。但是,在测试过程中,我们有时会遇到以下错误:
KeyError: 'val_acc'
或者
KeyError: 'acc'
这些错误表示指标名称不匹配,需要我们进行调整。
解决方法
方法一:使用Keras框架
在使用Keras框架训练模型时,指定评估指标的代码通常如下所示:
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
这里metrics参数指定了评估指标。如果出现KeyError: ‘val_acc’的错误,说明模型在训练过程中没有记录验证集的准确率指标。需要在模型训练的时候记录它:
model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=10, batch_size=32, callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss', patience=10, min_delta=0.01)])
这里使用validation_data指定了验证集数据,callbacks参数里指定了EarlyStopping回调函数,其监控参数为’val_loss’。这样,模型训练的每个epoch的时候,都会计算并记录验证集的评估指标。在模型训练完成后,我们可以使用以下代码获取测试集的评估指标:
model.evaluate(X_test, y_test)
这里的evaluate()函数将返回测试集的损失和评估指标。
方法二:使用PyTorch框架
在使用PyTorch框架训练模型时,指定评估指标的代码通常如下所示:
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
这里的CrossEntropyLoss()函数指定了损失函数,SGD()函数指定了优化器。如果出现KeyError: ‘val_acc’的错误,说明模型在训练过程中没有记录验证集的准确率指标。需要在模型训练的时候记录它:
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100 * correct / total
print('Accuracy of the network on the test images: %d %%' % acc)
这里用了预测正确率来计算测试集的评估指标。代码中的net是指已经训练好的模型,testloader是测试集数据。在模型训练完成后,我们可以使用以下代码获取测试集的评估指标:
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100 * correct / total
print('Accuracy of the network on the test images: %d %%' % acc)
这里的代码和记录验证集评估指标的代码基本相同,只是将testloader替换为了测试集的数据。
示例说明
假设我们有一个Keras框架训练的MNIST手写数字分类模型(LeNet-5),使用以下代码进行模型训练:
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
x_train = x_train.astype('float32')/255.
x_test = x_test.astype('float32')/255.
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), activation='relu', input_shape=(14, 14, 6)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(120, activation='relu'))
model.add(Dense(84, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1, validation_data=(x_test, y_test))
训练过程中会出现KeyError: ‘val_acc’的错误,因为我们在模型训练的时候没有记录验证集评估指标。我们需要在模型训练的时候记录它:
model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1, validation_data=(x_test, y_test), callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, min_delta=0.01)])
这里使用了EarlyStopping回调函数来监控验证集的损失,可以在模型训练过程中自动停掉训练。在模型训练完成后,我们可以使用以下代码获取测试集的评估指标:
model.evaluate(x_test, y_test)
这里的evaluate()函数将返回测试集的损失和评估指标。
如果我们有一个PyTorch框架训练的文本分类模型,使用以下代码进行模型训练:
train_dataset = MyDataset(train_data)
test_dataset = MyDataset(test_data)
trainloader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=0)
testloader = torch.utils.data.DataLoader(test_dataset, batch_size=32, shuffle=False, num_workers=0)
net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(NUM_EPOCHS):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if epoch % 10 == 9:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
训练过程中会出现KeyError: ‘acc’的错误,因为我们使用了accuracy这个评价指标,但是在模型训练中没有记录它。我们需要在模型训练的时候记录它:
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
inputs, labels = data
outputs = net(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100 * correct / total
print('Accuracy of the network on the test images: %d %%' % acc)
这里使用了预测正确率来计算测试集的评估指标。在模型训练完成后,我们可以使用以下代码获取测试集的评估指标:
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
inputs, labels = data
outputs = net(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100 * correct / total
print('Accuracy of the network on the test images: %d %%' % acc)
这里的代码和记录验证集评估指标的代码基本相同,只是将testloader替换为了测试集的数据。