簡體   English   中英

TensorFlow LSTM:為什么測試准確率變低,但不訓練?

[英]TensorFlow LSTM: Why does test accuracy become low, but not training one?

我嘗試用 TensorFlow 構建 LSTM 模型。 LSTM 的訓練似乎運行良好,准確率超過 90%。 困擾我的一個問題是“測試准確率”非常低。 所以,我認為這是由於過度擬合? 但是增加訓練批次或減少 element_size(從 10 到 5)等嘗試都是白費力氣,應用“dropout”也沒有解決。 我想要一些關於如何改進我的代碼以獲得高測試准確性的指導。 以下是我的數據/參數的摘要

Input variable is economic time series data standardized
Output variable is categorical features (labels) converted by one-hot encoding

Sequence_length : 20
Element_size: 5
Hidden_layer : 80
Categories (labels): 30 
Training batch : 924
Test batch : 164
Learn rate is 0.0005 (Is it low?)

這是我構建的代碼

#Split x_buch and y_batch
train_x,test_x=np.split(x_batch,[int(batch_size*0.85)])
train_y,test_y=np.split(y_batch,[int(batch_size*0.85)])
print('train_x shape: {0} and test_x shape: {1}'.format(train_x.shape,test_x.shape))
print('train_y shape: {0} and test_y shape: {1}'.format(train_y.shape,test_y.shape))

#Create placehold for inpt, labels
inputs=tf.placeholder(tf.float32,shape=[None,step_time,element_size],name='inputs')
y=tf.placeholder(tf.float32,shape=[None,label_num],name='y')

#Tensorflow  built-in functinon
with tf.variable_scope('lstm'):
    lstm_cell=tf.contrib.rnn.LSTMCell(hidden_layer,forget_bias=1.0)
    cell_drop=tf.contrib.rnn.DropoutWrapper(lstm_cell, output_keep_prob=0.7)
    outputs,states=tf.nn.dynamic_rnn(cell_drop,inputs,dtype=tf.float32) 
    print('outputs shape: {0}'.format(outputs.shape))

W1={'linear_layer':tf.Variable(tf.truncated_normal([hidden_layer,label_num],mean=0,stddev=.01))}
b1={'linear_layer':tf.Variable(tf.truncated_normal([label_num],mean=0,stddev=.01))}

#Extract the last relevant output and use in a linear layer
final_output=tf.matmul(outputs[:,-1,:],W1['linear_layer'])+b1['linear_layer']

with tf.name_scope('cross_entropy'):
    softmax=tf.nn.softmax_cross_entropy_with_logits(logits=final_output,labels=y)
    cross_entropy=tf.reduce_mean(softmax)

with tf.name_scope('train'):
    train_step=tf.train.AdamOptimizer(learn_rate,0.9).minimize(cross_entropy)

with tf.name_scope('accracy'):
    correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(final_output,1))
    accuracy=(tf.reduce_mean(tf.cast(correct_prediction,tf.float32)))*100

#Training
with tf.Session()as sess:
    sess.run(tf.global_variables_initializer())    
    for step in range(5000):
        sess.run(train_step,feed_dict={inputs:train_x,y:train_y})
        if step % 500 == 0:
            acc=sess.run(accuracy,feed_dict={inputs:train_x,y:train_y})
            loss=sess.run(cross_entropy,feed_dict={inputs:train_x,y:train_y})
            print('Inter'+str(step)+',Minibatch loss= '+'{:.6f}'.format(loss)+', Traning Accracy='+'{:.5f}'.format(acc))

# Test
    test_acc=sess.run(accuracy,feed_dict={inputs:test_x,y:test_y})
    print("Test Accuracy is {0}".format(test_acc))

它的結果是

Input Shape: (21760, 5)
Output Shape: (21760, 30)
x_batch shape: (1088, 20, 5)
y_batch shape: (1088, 30)
train_x shape: (924, 20, 5) and test_x shape: (164, 20, 5)
train_y shape: (924, 30) and test_y shape: (164, 30)
outputs shape: (?, 20, 80)
Inter0,Minibatch loss= 3.398923, Traning Accracy=5.30303
Inter500,Minibatch loss= 2.027734, Traning Accracy=38.09524
Inter1000,Minibatch loss= 1.340760, Traning Accracy=61.79654
Inter1500,Minibatch loss= 1.010518, Traning Accracy=72.83550
Inter2000,Minibatch loss= 0.743997, Traning Accracy=79.76190
Inter2500,Minibatch loss= 0.687736, Traning Accracy=79.76190
Inter3000,Minibatch loss= 0.475408, Traning Accracy=85.17316
Inter3500,Minibatch loss= 0.430477, Traning Accracy=87.22944
Inter4000,Minibatch loss= 0.359262, Traning Accracy=89.17749
Inter4500,Minibatch loss= 0.274463, Traning Accracy=90.69264
Test Accuracy is 4.878048419952393

我從來沒有使用過 TensorFlow 和 LSTM 模型,所以,這是第一次,因此我知道我做錯了什么,但不能指指點點

那么,有人可以提供幫助嗎?

在我詳細介紹之前:
我假設您在談論element_size時指的是batch_size 如果我的假設有誤,請在這里糾正我。

正如另一個答案所提到的,一個潛在的原因可能是過度擬合,即您“對訓練數據過於努力”。 解決此問題的一種通用方法是使用保留的驗證樣本跟蹤未見過的訓練數據的性能。 即,您有第三個驗證集(通常與測試數據的大小相同),而不是分成兩種方式(訓練/測試),並在訓練期間不時檢查您的模型在此驗證數據上的表現。

一個常見的觀察結果是以下曲線: 在此處輸入圖片說明 如您所見,該模型在訓練數據上不斷改進,但它確實如此,因為它犧牲了泛化到看不見的數據的能力

通常,您會嘗試在驗證集上的錯誤最小時停止訓練 - 即使這並不能保證您的訓練數據獲得最佳結果。 我們希望它在(完全未知的)之前的測試集上表現最好。

順便提一下,如果您在 TensorFlow 中執行此操作(我不是 100% 熟悉):通常,您必須將模型從訓練“切換”到評估,以獲得驗證集的實際結果(而不是不小心也對它們進行了訓練),但是您可以在網上找到很多實際的實現。

此外,如果您有太多神經元,過度擬合可能是一個問題! 在您的情況下,您只有 800 個示例,但已經有 80 個神經元,這是 IMO 的比率太高了。 您可以嘗試使用更少的神經元,看看這是否會提高測試集的准確性,即使這也可能會降低訓練數據的准確性。
最后,您希望對您的問題有一個簡潔的描述,而不是一個“學習”識別每個訓練實例的網絡。

此外,如果您確實使用小批量,您可以嘗試進一步減少數量。 我真的很喜歡Yann LeCun 的這條推文,所以我也會在這里發帖 ;-)
撇開笑話不談,小批量的訓練也可以導致更好的泛化,這聽起來很荒謬。 大批量通常只有在您有大量訓練集或正在 GPU 上訓練時才真正有用(從那時起,從 GPU 到內存的復制成本非常高,而小批量減少了此類操作的數量),或者如果你需要很長時間才能達到收斂。

由於您使用的是 LSTM 架構(由於其順序性,它在 CPU 和 GPU 上具有相似的性能,因為沒有太多可並行化的),因此大批量可能不會提高您的(計算)性能,但具有較小的批次可能會提高精度性能。

最后,這就是我最初評論另一個答案的原因,我們在這里的解釋可能完全不同,畢竟這可能是一個完全不同的原因。

許多人往往忘記的是對您的測試/訓練拆分進行一些初步的探索性分析。 如果您的測試集中只有一個類的代表,而您的訓練數據中幾乎沒有,結果可能不會很好。 同樣,如果您只訓練 30 個班級中的 29 個,網絡將很難識別第 30 個班級的任何樣本。

為避免這種情況,請確保您有一定程度的均勻分布(即,在測試和訓練集中為每個類采樣一定數量的類),並檢查類是否分布均勻

這樣做可能會在以后為您節省大量的痛苦,並且通常還有助於提高全新訓練數據的性能。 永遠記住 - 深度學習並不能神奇地解決您在預測分析中遇到的所有問題,它只是為您提供了一個非常強大的工具來解決特定的子問題。

根據內容豐富的丹林格的回答,我似乎得出了一個答案。 最重要的是,我將訓練數據分為六組(x_1、x_2...x_6 和 y_1、y_2、...y_6),每組的測試數據大小相同。 我不確定將它用作您提到的第三個驗證集,但請嘗試應用它。 更重要的是,我檢查了每個集合不包含哪些類,例如 y_1 不包含類 No.11、16、21、22 和 25

train_y
[]
y_1
[11, 16, 21, 22, 25]
y_2
[11, 14, 16, 23]
y_3
[11, 19, 21, 23]
y_4
[14, 21, 23]
y_5
[16, 21, 22, 23]
y_6
[11, 21, 22, 23]
test_y
[11, 21, 22, 23]

第一個檢查(validation)是在x_1/y_1集上訓練,計算測試數據的准確率。雖然我在每一步都停止訓練,但性能沒有提高,幾乎是一樣的結果。

Stop at step 1000
Inter500,Minibatch loss= 1.976426, Traning Accracy=46.01227
Test Accuracy is 7.317072868347168
Stop at step1500
Inter1000,Minibatch loss= 1.098709, Traning Accracy=66.25767
Test Accuracy is 4.2682929039001465
Stop at step 2000
Inter1500,Minibatch loss= 0.906059, Traning Accracy=74.23312
Test Accuracy is 6.097560882568359
Stop at step 2500
Inter2000,Minibatch loss= 0.946361, Traning Accracy=76.07362
Test Accuracy is 6.707317352294922

接下來,我嘗試檢查幾種組合的性能,結果如下

Train on x_6/y_6 sets and test on test data
Inter2500,Minibatch loss= 0.752621, Traning Accracy=79.77941
Test Accuracy is 78.65853881835938

Train on x_6/y_6 sets and test on x_5/y_5 sets
Inter2500,Minibatch loss= 0.772954, Traning Accracy=78.67647
Test Accuracy is 3.658536434173584

Train on training data and test on x_4/y_4 sets
Inter3000,Minibatch loss= 1.980538, Traning Accracy=41.01731
Test Accuracy is 37.42331314086914

有趣的是,在 x_6/y_6 集上訓練並在測試數據上進行測試的組合可以比之前的組合表現更好,測試准確率提高到 78% 左右。 這是,我假設,由於相同的類,這意味着 y_6 包含所有類的測試數據(見上文),以及相同的大小。 所以,這個節目我必須考慮哪些數據集是合適的,並嘗試在各種條件下驗證 LSTM 模型,這非常重要。

另一方面,CHG,減少神經元(80 到 10 或 5)和批次,根本沒有提高性能。

如果訓練准確率繼續上升但測試准確率下降,那么你就是過擬合了。 嘗試運行更少的 epochs 或使用較低的學習率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM