当训练和验证精度为 1.000 但结果仍然很差时,这意味着什么?
What does it mean when training and validation accuracy are 1.000 but results are still poor?
我正在使用 Keras 执行地标检测 - 特别是在人的照片上定位 body 的部分。我已经收集了大约 2,000 个训练样本,并且正在使用带有 mse 损失函数的 rmsprop。训练我的 CNN 后,我得到 loss: 3.1597e-04 - acc: 1.0000 - val_loss: 0.0032 - val_acc: 1.0000
我认为这意味着我的模型在测试数据上表现良好,然而,预测点与标记点相差甚远。任何想法或帮助将不胜感激!
IMG_SIZE = 96
NUM_KEYPOINTS = 15
NUM_EPOCHS = 50
NUM_CHANNELS = 1
TESTING = True
def load(test=False):
# load data from CSV file
df = pd.read_csv(fname)
# convert Image to numpy arrays
df['Image'] = df['Image'].apply(lambda im: np.fromstring(im, sep=' '))
df = df.dropna() # drop rows with missing values
X = np.vstack(df['Image'].values) / 255. # scale pixel values to [0, 1]
X = X.reshape(X.shape[0], IMG_SIZE, IMG_SIZE, NUM_CHANNELS)
X = X.astype(np.float32)
y = df[df.columns[:-1]].values
y = (y - (IMG_SIZE / 2)) / (IMG_SIZE / 2) # scale target coordinates to [-1, 1]
X, y = shuffle(X, y, random_state=42) # shuffle train data
y = y.astype(np.float32)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
return X_train, X_test, y_train, y_test
def build_model():
# construct the neural network
model = Sequential()
model.add(Conv2D(16, (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, NUM_CHANNELS)))
model.add(MaxPooling2D(2, 2))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(2, 2))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(2, 2))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(NUM_KEYPOINTS * 2))
return model
if __name__ == '__main__':
X_train, X_test, y_train, y_test = load(test=TESTING)
model = build_model()
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='mse', metrics=['accuracy'])
hist = model.fit(X_train, y_train, epochs=NUM_EPOCHS, verbose=1, validation_split=0.2)
# save the model
model.save_weights("/output/model_weights.h5")
histFile = open("/output/training_history", "wb")
pickle.dump(hist.history, histFile)
从你的问题中无法判断,但我会根据你的数据拆分的一些含义来猜测一下。
通常,当一个人将一个人的数据分成两组以上时,一个人会使用除其中一组以外的所有组来训练某个参数或另一个参数。例如,第一次拆分用于选择模型权重,第二次拆分用于选择模型架构等。推测您正在使用 'validation' 集训练 something,否则你不会有它。因此,问题几乎可以肯定是过度拟合。通常,您检测过度拟合的方式是模型在用于训练模型的数据(通常是除一个分割之外的所有数据)上的准确性差异,您称之为 'training' 和 'validation' 拆分,以及您的模型未触及的拆分的准确性,您称之为 'test' 拆分。
因此,根据您的 question-comment "I assume if the validation accuracy is that high then there is no overfitting, right?"。不。如果你的模型在你用来训练任何东西的任何数据上的准确性高于你的模型在你的模型从未以任何形式或方式接触过的数据上的准确性,那么你过拟合了。你好像也是这样。
OTOH,可能是您没有对数据进行洗牌。在 training/testing 管道上没有 look-see 是不可能分辨的。
根据这个问题 你的 "accuracy" 被定义为绝对准确度,这对你的问题完全没有意义。
训练后,您的训练损失和验证损失之间存在 10 倍的差异,这表明过度拟合(如果没有图表和一些示例很难确定)。
开始修复它:
- 使用在您的上下文中有意义的指标,并且您了解它的作用和计算方式。
- 随机抽取指标非常好和非常差的示例,并手动验证情况是否确实如此(否则您需要不同的指标)。
在你的情况下,我会想象一个基于所需位置和预测位置之间距离的度量。这不是默认设置,您必须自己实施。
如果模型说它是完美的,请始终保持怀疑。
我正在使用 Keras 执行地标检测 - 特别是在人的照片上定位 body 的部分。我已经收集了大约 2,000 个训练样本,并且正在使用带有 mse 损失函数的 rmsprop。训练我的 CNN 后,我得到 loss: 3.1597e-04 - acc: 1.0000 - val_loss: 0.0032 - val_acc: 1.0000
我认为这意味着我的模型在测试数据上表现良好,然而,预测点与标记点相差甚远。任何想法或帮助将不胜感激!
IMG_SIZE = 96
NUM_KEYPOINTS = 15
NUM_EPOCHS = 50
NUM_CHANNELS = 1
TESTING = True
def load(test=False):
# load data from CSV file
df = pd.read_csv(fname)
# convert Image to numpy arrays
df['Image'] = df['Image'].apply(lambda im: np.fromstring(im, sep=' '))
df = df.dropna() # drop rows with missing values
X = np.vstack(df['Image'].values) / 255. # scale pixel values to [0, 1]
X = X.reshape(X.shape[0], IMG_SIZE, IMG_SIZE, NUM_CHANNELS)
X = X.astype(np.float32)
y = df[df.columns[:-1]].values
y = (y - (IMG_SIZE / 2)) / (IMG_SIZE / 2) # scale target coordinates to [-1, 1]
X, y = shuffle(X, y, random_state=42) # shuffle train data
y = y.astype(np.float32)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
return X_train, X_test, y_train, y_test
def build_model():
# construct the neural network
model = Sequential()
model.add(Conv2D(16, (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, NUM_CHANNELS)))
model.add(MaxPooling2D(2, 2))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(2, 2))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(2, 2))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(NUM_KEYPOINTS * 2))
return model
if __name__ == '__main__':
X_train, X_test, y_train, y_test = load(test=TESTING)
model = build_model()
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='mse', metrics=['accuracy'])
hist = model.fit(X_train, y_train, epochs=NUM_EPOCHS, verbose=1, validation_split=0.2)
# save the model
model.save_weights("/output/model_weights.h5")
histFile = open("/output/training_history", "wb")
pickle.dump(hist.history, histFile)
从你的问题中无法判断,但我会根据你的数据拆分的一些含义来猜测一下。
通常,当一个人将一个人的数据分成两组以上时,一个人会使用除其中一组以外的所有组来训练某个参数或另一个参数。例如,第一次拆分用于选择模型权重,第二次拆分用于选择模型架构等。推测您正在使用 'validation' 集训练 something,否则你不会有它。因此,问题几乎可以肯定是过度拟合。通常,您检测过度拟合的方式是模型在用于训练模型的数据(通常是除一个分割之外的所有数据)上的准确性差异,您称之为 'training' 和 'validation' 拆分,以及您的模型未触及的拆分的准确性,您称之为 'test' 拆分。
因此,根据您的 question-comment "I assume if the validation accuracy is that high then there is no overfitting, right?"。不。如果你的模型在你用来训练任何东西的任何数据上的准确性高于你的模型在你的模型从未以任何形式或方式接触过的数据上的准确性,那么你过拟合了。你好像也是这样。
OTOH,可能是您没有对数据进行洗牌。在 training/testing 管道上没有 look-see 是不可能分辨的。
根据这个问题
训练后,您的训练损失和验证损失之间存在 10 倍的差异,这表明过度拟合(如果没有图表和一些示例很难确定)。
开始修复它:
- 使用在您的上下文中有意义的指标,并且您了解它的作用和计算方式。
- 随机抽取指标非常好和非常差的示例,并手动验证情况是否确实如此(否则您需要不同的指标)。
在你的情况下,我会想象一个基于所需位置和预测位置之间距离的度量。这不是默认设置,您必须自己实施。
如果模型说它是完美的,请始终保持怀疑。