Keras 模型给出了 1.0 的测试精度

Posted

技术标签:

【中文标题】Keras 模型给出了 1.0 的测试精度【英文标题】:Keras Model gives test accuracy 1.0 【发布时间】:2018-04-17 17:41:13 【问题描述】:

下面是预测第二天是涨还是跌的代码(涨=1,跌=0)

我所做的是创建一个数据框并预测只是使用 PriceChange(今日收盘-昨日收盘)预测次日价格上涨或下跌(次日收盘-今日收盘)

df['PriceChange'] = (df['Close'] > df['Close'].shift(1)).astype(int)
df['Closeupnextday'] = (df['Close'].shift(-1) > df['Close']).astype(int)

所以数据框看起来像这样:

            PriceChange  Closeupnextday
    0             0               1
    1             1               1
    2             1               1
    3             1               1
    4             1               0
    5             0               0
    6             0               0
    7             0               1

它不断给我 1.000 的准确度 公平地说,它应该只有 50+% 的准确率。 我认为下面的代码有问题,但我找不到。

我应该补充一点,在 20/500 纪元之后,它不断给我 1.000 的准确度

有什么建议吗?

def load_data(stock, seq_len):
    amount_of_features = len(stock.columns)
    data = stock.as_matrix() #pd.DataFrame(stock)
    sequence_length = seq_len + 1
    result = []
    for index in range(len(data) - sequence_length):
        result.append(data[index: index + sequence_length])

    result = np.array(result)
    row = round(0.9 * result.shape[0])
    train = result[:int(row), :]
    x_train = train[:, :-1]
    y_train = train[:, -1][:,-1]
    x_test = result[int(row):, :-1]
    y_test = result[int(row):, -1][:,-1]

    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], amount_of_features))
    x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], amount_of_features))  

    return [x_train, y_train, x_test, y_test]

def build_model(layers):
    model = Sequential()

    model.add(LSTM(
        input_dim=layers[0],
        output_dim=layers[1],
        return_sequences=True))
    model.add(Dropout(0.0))

    model.add(LSTM(
        layers[2],
        return_sequences=False))
    model.add(Dropout(0.0))

    model.add(Dense(
        output_dim=layers[2]))
    model.add(Activation("linear"))

    start = time.time()
    model.compile(loss="mse", optimizer="rmsprop",metrics=['accuracy'])
    print("Compilation Time : ", time.time() - start)
    return model

def build_model2(layers):
        d = 0.2
        model = Sequential()
        model.add(LSTM(128, input_shape=(layers[1], layers[0]), return_sequences=True))
        model.add(Dropout(d))
        model.add(LSTM(64, input_shape=(layers[1], layers[0]), return_sequences=False))
        model.add(Dropout(d))
        model.add(Dense(16, activation="relu", kernel_initializer="uniform"))        
        model.add(Dense(1, activation="relu", kernel_initializer="uniform"))
        model.compile(loss='mse',optimizer='adam',metrics=['accuracy'])
        return model


window = 5
X_train, y_train, X_test, y_test = load_data(df[::-1], window)
print("X_train", X_train.shape)
print("y_train", y_train.shape)
print("X_test", X_test.shape)
print("y_test", y_test.shape) 

# model = build_model([3,lag,1])
model = build_model2([len(df.columns),window,1]) #11 = Dataframe axis 1

model.fit(
    X_train,
    y_train,
    batch_size=512,
    epochs=500,
    validation_split=0.1,
    verbose=1)


trainScore = model.evaluate(X_train, y_train, verbose=0)
print('Train Score: %.2f MSE (%.2f RMSE)' % (trainScore[0], math.sqrt(trainScore[0])))

testScore = model.evaluate(X_test, y_test, verbose=0)
print('Test Score: %.2f MSE (%.2f RMSE)' % (testScore[0], math.sqrt(testScore[0])))


# print(X_test[-1])
diff=[]
ratio=[]
p = model.predict(X_test)
for u in range(len(y_test)):
    pr = p[u][0]
    ratio.append((y_test[u]/pr)-1)
    diff.append(abs(y_test[u]- pr))
    #print(u, y_test[u], pr, (y_test[u]/pr)-1, abs(y_test[u]- pr))


print(p)
print(y_test)

【问题讨论】:

检查天气,您不小心将目标值包含为训练数据。除非你犯了那种错误,否则我猜这是不可能的。 我的数据框没有问题...我认为它与代码有关,但我无法弄清楚 出于好奇,您为什么选择最小化 MSE 并将最后一层作为分类的 ReLU? 这是改编自另一个代码,因此它的默认值我没有更改,有什么建议会更好吗? 您是否已将一组测试数据输出到可能的 csv 以进行视觉检查?这总是有助于确定我是否有一个好的模型或有什么问题。此外,正如其他人也逃避的那样,mse 用于回归问题,这是二元分类,你的 y 应该是二元的,你的损失应该是 binary_crossentropy 【参考方案1】:

(由于您没有澄清它,我假设您在这里谈论的是 test 准确度 - 训练准确度确实可以为 1.0,具体取决于您的数据和模型的详细信息。)

好吧,当人们将问题、损失和指标搞砸时,此类问题很常见 - 请参阅 this answer of mine 以了解在 Keras 中将 binary_crossentropy 用作多类分类问题的损失时类似的混淆。

在尝试任何补救措施之前,请尝试手动预测几个示例(即使用model.predict 而不是model.evaluate);因为我没有您的数据,所以我自己无法做到这一点,但我敢打赌,您将获得的结果将符合您的 model.evaluate 结果所暗示的完美准确度。

问题的核心:既然你有一个二元分类问题,你应该绝对在你的模型编译中要求loss='binary_crossentropy',而不是mse

无法确定您从 model.evaluate 获得的 1.0 的确切值是多少,但正如我在上面链接的答案中所示,Keras 为使用 metrics=['accuracy'] 编译的模型返回的评估指标在很大程度上取决于各自的loss 的条目;即使我最终能够弄清楚那个问题的问题是什么,我什至无法想象这里到底发生了什么,你请求accuracy(即分类指标) 回归损失 (mse)...

【讨论】:

以上是关于Keras 模型给出了 1.0 的测试精度的主要内容,如果未能解决你的问题,请参考以下文章

使用 keras 顺序模型获得较差的分类精度

加载相同的保存模型后,Keras 模型精度有所不同

Keras 功能 API:采用多个输入的拟合和测试模型

Keras猫狗大战五:采用全部数据集训练,精度提高到90%

使用 Keras 评估模型时的测试分数与测试准确度

VGG16 Keras微调:精度低