1

在二元分類中的損耗值沒有改變我試圖用一個深層神經網絡結構對二進制標籤值分類 - 0和+1。這是我的代碼來做tensorflow。也這個問題帶入從討論中previous question更改精度值,並使用Tensorflow

import tensorflow as tf 
import numpy as np 
from preprocess import create_feature_sets_and_labels 

train_x,train_y,test_x,test_y = create_feature_sets_and_labels() 

x = tf.placeholder('float', [None, 5]) 
y = tf.placeholder('float') 

n_nodes_hl1 = 500 
n_nodes_hl2 = 500 
# n_nodes_hl3 = 500 

n_classes = 1 
batch_size = 100 

def neural_network_model(data): 

    hidden_1_layer = {'weights':tf.Variable(tf.random_normal([5, n_nodes_hl1])), 
         'biases':tf.Variable(tf.random_normal([n_nodes_hl1]))} 

    hidden_2_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])), 
         'biases':tf.Variable(tf.random_normal([n_nodes_hl2]))} 

    # hidden_3_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])), 
    #     'biases':tf.Variable(tf.random_normal([n_nodes_hl3]))} 

    # output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl3, n_classes])), 
    #     'biases':tf.Variable(tf.random_normal([n_classes]))} 

    output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_classes])), 
        'biases':tf.Variable(tf.random_normal([n_classes]))} 


    l1 = tf.add(tf.matmul(data, hidden_1_layer['weights']), hidden_1_layer['biases']) 
    l1 = tf.nn.relu(l1) 

    l2 = tf.add(tf.matmul(l1, hidden_2_layer['weights']), hidden_2_layer['biases']) 
    l2 = tf.nn.relu(l2) 

    # l3 = tf.add(tf.matmul(l2, hidden_3_layer['weights']), hidden_3_layer['biases']) 
    # l3 = tf.nn.relu(l3) 

    # output = tf.transpose(tf.add(tf.matmul(l3, output_layer['weights']), output_layer['biases'])) 
    output = tf.add(tf.matmul(l2, output_layer['weights']), output_layer['biases']) 
    return output 



def train_neural_network(x): 
    prediction = tf.sigmoid(neural_network_model(x)) 
    cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(prediction, y)) 
    optimizer = tf.train.AdamOptimizer().minimize(cost) 

    hm_epochs = 10 

    with tf.Session() as sess: 
     sess.run(tf.initialize_all_variables()) 

     for epoch in range(hm_epochs): 
      epoch_loss = 0 
      i = 0 
      while i < len(train_x): 
       start = i 
       end = i + batch_size 
       batch_x = np.array(train_x[start:end]) 
     batch_y = np.array(train_y[start:end]) 

     _, c = sess.run([optimizer, cost], feed_dict={x: batch_x, 
               y: batch_y}) 
     epoch_loss += c 
     i+=batch_size 

      print('Epoch', epoch, 'completed out of', hm_epochs, 'loss:', epoch_loss) 

     # correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1)) 
     # accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 
     predicted_class = tf.greater(prediction,0.5) 
     correct = tf.equal(predicted_class, tf.equal(y,1.0)) 
     accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 

     # print (test_x.shape) 
     # accuracy = tf.nn.l2_loss(prediction-y,name="squared_error_test_cost")/test_x.shape[0] 
     print('Accuracy:', accuracy.eval({x: test_x, y: test_y})) 

train_neural_network(x) 

具體而言,(結轉討論從前面的問題)我刪除一個層 - hidden_3_layer。改變

prediction = neural_network_model(x)

prediction = tf.sigmoid(neural_network_model(x)) 

,並添加根據Neil的回答predicted_class, correct, accuracy部分。我也在我的csv中將所有-1s更改爲0。

這是我的跟蹤:

('Epoch', 0, 'completed out of', 10, 'loss:', 37.312037646770477) 
('Epoch', 1, 'completed out of', 10, 'loss:', 37.073578298091888) 
('Epoch', 2, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 3, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 4, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 5, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 6, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 7, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 8, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Epoch', 9, 'completed out of', 10, 'loss:', 37.035196363925934) 
('Accuracy:', 0.42608696) 

正如你所看到的,損失也不會降低。因此我不知道它是否仍然正常工作。

下面是多次再運行的結果。結果搖曳似地:

('Epoch', 0, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 1, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 2, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 3, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 4, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 5, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 6, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 7, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 8, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Epoch', 9, 'completed out of', 10, 'loss:', 26.513012945652008) 
('Accuracy:', 0.60124224) 

另一:

('Epoch', 0, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 1, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 2, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 3, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 4, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 5, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 6, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 7, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 8, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 9, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Accuracy:', 1.0) 

和另一:0.0 -_-

('Epoch', 0, 'completed out of', 10, 'loss:', 23.163824260234833) 
('Epoch', 1, 'completed out of', 10, 'loss:', 22.88000351190567) 
('Epoch', 2, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 3, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 4, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 5, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 6, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 7, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 8, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Epoch', 9, 'completed out of', 10, 'loss:', 22.873702049255371) 
('Accuracy:', 0.99627328) 

我還看到的精度值--- ------------編輯---------------

有關數據和數據處理的一些細節。我正在使用來自Yahoo!的IBM每日股票數據。融資20年(幾乎)。這相當於大約5200行條目。

這是我如何處理我吧:

import numpy as np 
import pandas as pd 
from sklearn.preprocessing import MinMaxScaler 
import csv 
import pickle 

def create_feature_sets_and_labels(test_size = 0.2): 
    df = pd.read_csv("ibm.csv") 
    df = df.iloc[::-1] 
    features = df.values 
    testing_size = int(test_size*len(features)) 
    train_x = list(features[1:,1:6][:-testing_size]) 
    train_y = list(features[1:,7][:-testing_size]) 
    test_x = list(features[1:,1:6][-testing_size:]) 
    test_y = list(features[1:,7][-testing_size:]) 
    scaler = MinMaxScaler(feature_range=(-5,5)) 
    train_x = scaler.fit_transform(train_x) 
    train_y = scaler.fit_transform(train_y) 
    test_x = scaler.fit_transform(test_x) 
    test_y = scaler.fit_transform(test_y) 

    return train_x, train_y, test_x, test_y 

if __name__ == "__main__": 
    train_x, train_y, test_x, test_y = create_feature_sets_and_labels() 
    with open('stockdata.pickle', 'wb') as f: 
     pickle.dump([train_x, train_y, test_x, test_y], f) 

列0是日期。所以這不被用作一個功能。我也沒有列7.我使用sklearnMinMaxScaler()在-5到5的範圍內對數據進行歸一化。

-------------編輯2 ------- ------------

我注意到,當數據在非規範化的形式呈現在系統不改變其準確性。

+0

好的,我再次改變了代碼。精度仍在65-100之間擺動。我也試圖改變自己的時代價值,以找到損失開始穩定的地方,但即使在100個時代,它們也在不斷下降。 –

+0

準確性波動似乎有點奇怪。也許我錯過了什麼。你能否添加一些關於輸入數據的細節以及你如何預處理它?訓練集和測試集有多大(您所描述的行爲我期望從非常小的數據集中得到)?這是來自公共來源的標準數據嗎?是否有強烈的傾向於主要是積極的或主要是負面的課程? –

+0

另外,讓我們來檢查你的真實班級數據的形狀。如果將'y = tf.placeholder('float')'更改爲'y = tf.placeholder('float',[None,1]),會發生什麼? –

回答

4

一旦你預先處理您的數據引入錯誤的形狀或範圍在ML的訓練任務,數據流的其餘部分將出問題。您在問題的代碼中以不同的方式多次執行此操作。

走一步,以使發生的處理。第一個問題是預處理。在這裏你的目標應該是:

  • X以表格形式值(輸入功能),每一行就是一個例子,每一列是一個特徵。值應該是數字和縮放以用於神經網絡。測試和訓練數據需要按相同的比例縮放 - 這並不意味着使用相同的.fit_transform,因爲它適合縮放器。

  • 以表格形式表示的Y值(輸出標籤),每行都是示例匹配X的同一行,每列是輸出的真值。對於分類問題,值通常爲0和1,,因爲它們代表類成員資格,所以不應重新縮放

create_feature_sets_and_labels功能的這種重新寫做的事情正確:

  • 使用類型轉換np.array,不list(微小的差別)

    def create_feature_sets_and_labels(test_size = 0.2): 
        df = pd.read_csv("ibm.csv") 
        df = df.iloc[::-1] 
        features = df.values 
        testing_size = int(test_size*len(features)) 
    
        train_x = np.array(features[1:,1:6][:-testing_size]).astype(np.float32) 
        train_y = np.array(features[1:,7][:-testing_size]).reshape(-1, 1).astype(np.float32) 
    
        test_x = np.array(features[1:,1:6][-testing_size:]).astype(np.float32) 
        test_y = np.array(features[1:,7][-testing_size:]).reshape(-1, 1).astype(np.float32) 
    
        scaler = MinMaxScaler(feature_range=(-5,5)) 
    
        scaler.fit(train_x) 
    
        train_x = scaler.transform(train_x) 
        test_x = scaler.transform(test_x) 
    
        return train_x, train_y, test_x, test_y 
    

    從版本的重要差異

  • y valu (主要區別,你的行矢量形狀是後來很多問題的原因)

  • 定標器適合一次然後應用於功能(主要區別,如果您單獨調整訓練和測試數據,你不預測任何東西有意義的)

  • 倍線器是應用於輸出(用於分類的主要區別,你想要的訓練和測試值是0,1有意義的培訓和報告的準確性)

也有一些問題這個數據您的訓練碼:

  • y = tf.placeholder('float')應該y = tf.placeholder('float', [None, 1])。這對處理沒有任何影響,但是當y是錯誤的形狀時正確地拋出錯誤。這個錯誤早在事情出錯的時候就已經成爲線索了。

  • n_nodes_hl1 = 500n_nodes_hl2 = 500可以低得多,並且網絡實際上可以更好地工作, n_nodes_hl1 = 10n_nodes_hl2 = 10 - 這主要是因爲您使用較大的初始值來衡量權重,您可以選擇向下縮放權重,也可以使用更復雜的數據來代替。在這種情況下,減少隱藏的神經元數量會更簡單。

  • 正如我們在討論的意見,你的train_neural_network功能的啓動應該是這樣的:

    output = neural_network_model(x) 
    prediction = tf.sigmoid(output) 
    cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(output, y)) 
    optimizer = tf.train.AdamOptimizer().minimize(cost) 
    

    。 。 。這是一個主要的區別。通過使用sigmoid_cross_entropy_with_logits,您已經承諾將輸出圖層的預轉換值用於訓練。但是您仍然希望預測值能夠衡量準確性(或者您想要讀取預測值的網絡的任何其他用途)。

  • 損失的一致的措施,你想擁有每例平均損失,所以你需要給你劃分的總和平均每批次分批數量:'loss:', epoch_loss/(len(train_x)/batch_size)

如果我做所有這些修正,並運行這個幾個新紀元 - 例如50,那麼我得到0.7的典型損失和0.5的準確性測量 - 這合理可靠地發生,但是由於起始權重的變化確實會發生一些變化。準確性不是很穩定,可能會出現過度擬合,這是您根本不允許的(您應該閱讀技術來幫助衡量和管理過度擬合,這是可靠地訓練NN的重要部分)

0.5的值可能看起來很糟糕。通過修改網絡體系結構或元參數可以改進它。我可以得到0.43訓練損失和0.83測試精度,例如通過在隱藏層交換tf.nn.relutf.tanh並運行500個時期。

要了解有關神經網絡的更多信息,在訓練時測量什麼以及什麼值得在模型中改變,您將需要更深入地研究該主題。

+0

這是非常好的!非常感謝! –

+0

更多關於穩定精度的指針?我的準確度值仍然不盡相同。我試圖在兩個月的數據上運行我的模型。大約60行。 –

+0

@VineetKaushik:你的模型的代碼是非常基本的神經網絡,並且你可以做出很多改變,包括交叉驗證,正則化,加入監控等等。可能精度問題是由過度擬合引起的,因爲沒有在你的代碼中防止這種情況。我認爲你需要停止使用這個模型,並且做一些更直接的學習,比如關於神經網絡的「MOOC」課程,這樣你就可以瞭解這些東西。 –