tensorflow 在训练和验证过程中准确度高,在使用相同数据集进行预测时准确度低

vc9ivgsu  于 2022-11-25  发布在  其他
关注(0)|答案(3)|浏览(243)

所以我尝试训练Keras模型。在训练和验证时有很高的准确度(我使用f1score,但准确度也很高)。但当我尝试预测一些数据集时,我得到的准确度较低。即使我预测训练集。所以我猜这不是过度拟合问题。那么问题是什么?

import matplotlib.pyplot as plt

skf = StratifiedKFold(n_splits=5)
for train_index, test_index in skf.split(X, y):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    X_train,x_val,y_train,y_val = train_test_split(X_train, y_train, test_size=0.5,stratify = y_train)
    y_train = encode(y_train)
    y_val = encode(y_val)
    
    model = Sequential()
    model.add(Dense(50,input_dim=X_train.shape[1],activation='tanh'))
    model.add(Dropout(0.5))
    model.add(Dense(25,activation='tanh'))
    model.add(Dropout(0.5))
    model.add(Dense(10,activation='tanh'))
    model.add(Dropout(0.5))
    model.add(Dense(2, activation='softmax'))   
    
    opt = Adam(learning_rate=0.001)
    model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['acc', ta.utils.metrics.f1score])  
    history = model.fit(X_train, y_train, 
                        validation_data=(x_val, y_val),
                        epochs=5000,
                        verbose=0)
    
    plt.plot(history.history['f1score'])
    plt.plot(history.history['val_f1score'])
    plt.title('model accuracy')
    plt.ylabel('f1score')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='upper left')
    plt.show()
    break

结果是here。如您所见,结果在训练集和验证集中较高。
和预测代码:

from sklearn.metrics import f1_score

y_pred = model.predict(x_train)
y_pred = decode(y_pred)
y_train_t = decode(y_train)
print(f1_score(y_train_t, y_pred))

结果为0.64,低于预期的0.9。
我的解码和编码:

def encode(y):
    Y=np.zeros((y.shape[0],2))
    for i in range(len(y)):
        if y[i]==1:
            Y[i][1]=1
        else :
            Y[i][0]=1
    return Y

def decode(y):
    Y=np.zeros((y.shape[0]))
    for i in range(len(y)):
        if np.argmax(y[i])==1:
            Y[i]=1
        else :
            Y[i]=0
    return Y
mccptt67

mccptt671#

由于您使用了最后一层

model.add(Dense(2, activation='softmax')

您不应该在model.compile()中使用loss='binary_crossentropy',而应该使用loss='categorical_crossentropy'
由于这个错误,模型拟合过程中显示的结果可能是错误的-sklearn的f1_score返回的结果是真实的的。
与你的问题无关(我猜接下来的问题是 * 如何改进它?*),我们实际上从来没有使用activation='tanh'作为隐藏层(尝试relu代替)。注解掉所有丢弃的层,只有在模型过拟合时才将其添加回来(已知在不需要时使用丢弃会损害性能)。

dauxcl2d

dauxcl2d2#

我认为您应该将binary_crossentropy更改为categorical_crossentropy,因为您使用了one-hot编码。

tjjdgumg

tjjdgumg3#

不知何故,图像生成器和predict_generator()函数或Keras模型的predict()函数的组合并没有像预期的那样工作。与其使用图像生成器来做预测,我宁愿一个接一个地循环所有测试图像,并在每次迭代中得到每个图像的预测。我使用Plaid-ML Keras作为我的后端,为了得到预测,我使用了下面的代码。

import os
from PIL import Image
import keras
import numpy

###
# I am not including code to load models or train model
###

print("Prediction result:")
dir = "/path/to/test/images"
files = os.listdir(dir)
correct = 0
total = 0
#dictionary to label all traffic signs class.
classes = {
    0:'This is Cat',
    1:'This is Dog',
}
for file_name in files:
    total += 1
    image = Image.open(dir + "/" + file_name).convert('RGB')
    image = image.resize((100,100))
    image = numpy.expand_dims(image, axis=0)
    image = numpy.array(image)
    image = image/255
    pred = model.predict_classes([image])[0]
    sign = classes[pred]
    if ("cat" in file_name) and ("cat" in sign):
        print(correct,". ", file_name, sign)
        correct+=1
    elif ("dog" in file_name) and ("dog" in sign):
        print(correct,". ", file_name, sign)
        correct+=1
print("accuracy: ", (correct/total))

相关问题