从头开始,给出不好的结果

时间:2018-05-31 14:05:26

标签: python tensorflow lstm rnn

这是我的代码,但输出非常糟糕。

并且我的意思是这些值远远超出它们的预期,测试误差非常高。如果我对值进行去标准化并比较差异,那就太大了。

我有两个问题:

1)任何人都可以告诉我为什么会这样,以及我能做些什么来使它表现更好? 2)当值经过如此多的函数时,如何将输出恢复为原始格式。

我是新手,并立即跳进了一个复杂的主题,所以我知道我的代码不是最好的,如果你能告诉我如何改进那也会很棒!无论如何,请耐心等待!

我使用的数据是两个的倍数列表。

ps:当我使用像dynamic_rnn()这样的张量流模型时,我得到的输出是准确的,而且我只需要对输出进行非规范化以获得原始格式的数字(正确的大小),如何将其非规范化得到输出,我不明白! 谢谢!

# LSTM [ Many to One ]

# START

# imports
import csv
import numpy as np
import tensorflow as tf
import sys
import os
import json
from random import shuffle
from tensorflow.python import debug as tf_debug

# CALCULATE ALL POSSIBLE BATCH SIZES
def calculate_batch_sizes(n_train):
    batch_sizes = []
    for i in range(2, int(n_train/2)):  
        if n_train % i == 0 and n_train / i > 1: 
            batch_sizes.append(i)
    return batch_sizes
def de_normalize(value, m1, m2):
    return (value*(m1-m2)) + m2

class lstm_network():
    name = "lstm_"

    # initialization function
    def __init__(self, config_params):
        self.sequence_length = config_params["sequence_length"]
        self.batch_size = config_params["batch_size"]
        self.hidden_layers_size = config_params["hidden_layers_size"]
        self.data_path = config_params["data_path"]
        self.n_epochs = config_params["no_of_epochs"]
        self.learning_rate = config_params["learning_rate"]
        self.w_igate, self.w_fgate, self.w_ogate, self.w_cgate = tf.get_variable('w_igate', shape = [self.sequence_length, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('w_fgate', shape = [self.sequence_length, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('w_ogate', shape = [self.sequence_length, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('w_cgate', shape = [self.sequence_length, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer())
        self.u_igate, self.u_fgate, self.u_ogate, self.u_cgate = tf.get_variable('u_igate', shape = [self.hidden_layers_size, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('u_fgate', shape = [self.hidden_layers_size, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('u_ogate', shape = [self.hidden_layers_size, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer()), tf.get_variable('u_cgate', shape = [self.hidden_layers_size, self.hidden_layers_size], initializer = tf.contrib.layers.xavier_initializer())
        self.outputs = [0.0] * self.batch_size
        self.testing_loss = float(0)
        self.training_loss = float(0)
        self.ft, self.ct, self._ct, self.it = [0.0]*(self.hidden_layers_size), [0.0]*(self.hidden_layers_size), [0.0]*(self.hidden_layers_size), [0.0]*(self.hidden_layers_size)
        self.ot, self.ht, self.ct_prev, self.ht_prev = [0.0]*(self.hidden_layers_size), [0.0]*(self.hidden_layers_size), np.array([0.0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size), np.array([0.0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size)
        self.w_output_layer = tf.get_variable('w_output_layer', shape = [self.hidden_layers_size, 1], initializer = tf.contrib.layers.xavier_initializer())
        print("\n Object of class lstm_network initialized with the given configuration")

    # print values function
    def print_model_info(self):
        print("\n\n\n\t\t MODEL INFORMATION\n\n")
        print("\n Weights of the LSTM layer: ")
        print("\n\n   input Gate Weights: \n    w: ", self.w_igate,"\n    u: ", self.u_igate)
        print("\n\n   Forget Gate Weights: \n    w: ", self.w_fgate,"\n    u: ", self.u_fgate)
        print("\n\n   Context Gate Weights: \n    w: ", self.w_cgate,"\n    u: ", self.u_cgate)
        print("\n\n   Output Gate Weights: \n    w: ", self.w_ogate,"\n    u: ", self.u_ogate)
        print("\n\n Average loss while training: ", self.training_loss)
        print("\n\n Average loss while testing: ", self.testing_loss)

    # loading function
    def load_data(self):
        with open(self.data_path, 'r') as data_file:
            data_reader = csv.reader(data_file, delimiter = ',')
            self.data = [float(row[1]) for row in data_reader]
        self.data_max, self.data_min, self.n_data = float(max(self.data)), float(min(self.data)), len(self.data)
        for i in range(len(self.data)):
            self.data[i] = float( (self.data[i]-self.data_min)/(self.data_max-self.data_min) )
        self.data_x = [ self.data[i:i+self.sequence_length] for i in range(self.n_data - self.sequence_length-1)]
        self.data_y = [ self.data[i] for i in range(self.sequence_length+1, self.n_data)]
        self.n_data = len(self.data_x)
        temp = list(zip(self.data_x,self.data_y))
        shuffle(temp)
        test_size = 0.25
        self.data_x, self.data_y = zip(*temp)
        self.trainx, self.trainy, self.testx, self.testy = self.data_x[:-int(test_size*self.n_data)], self.data_y[:-int(test_size*self.n_data)], self.data_x[-int(test_size*self.n_data):], self.data_y[-int(test_size*self.n_data):] 
        self.n_train, self.n_test = len(self.trainx), len(self.testx)
        batch_sizes = []
        batch_sizes.extend(calculate_batch_sizes(self.n_train))
        while self.batch_size not in batch_sizes:
            print("\n batch size provided in the initial configuration cannot be used, please select one from the following batch sizes:\n",batch_sizes)
            self.batch_size = int(input("\n enter a batch size: "))
        self.n_train_batches = int( self.n_train/self.batch_size ) 
        self.trainx, self.trainy, self.testx, self.testy = np.float32(self.trainx), np.float32(self.trainy), np.float32(self.testx), np.float32(self.testy)
        self.trainx_batches, self.trainy_batches = self.trainx.reshape(self.n_train_batches, self.batch_size, self.sequence_length), self.trainy.reshape(self.n_train_batches,self.batch_size, 1)
        print("\n data loaded succesfully")

    # graph building and training function
    def build_graph_train(self):
        outputs = [0.0]*self.batch_size#tf.placeholder(tf.float32, shape = [1, self.batch_size])
        x = self.trainx_batches
        ht_prev = tf.reshape(np.float32([0]*(self.hidden_layers_size)), [1, self.hidden_layers_size]) #[tf.placeholder(tf.float32, shape = [1, self.hidden_layers_size], name = 'ht_prev')
        ct_prev = tf.reshape(np.float32([0]*(self.hidden_layers_size)), [1, self.hidden_layers_size]) #tf.placeholder(tf.float32, shape = [1, self.hidden_layers_size], name = 'ct_prev')
        self.ht_prev = np.array([0.0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size)
        self.ct_prev = np.array([0.0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size)
        for i1 in range(self.n_train_batches):
            for i2 in range(self.batch_size):
                #self.ht_prev = [self.ht_prev[i:i+9] for i in range(0, self.hidden_layers_size, 9)]
                self.ft = tf.sigmoid( tf.matmul(tf.reshape(x[i1][i2], [1, self.sequence_length]), self.w_fgate) + tf.matmul(ht_prev, self.u_fgate) )
                self.it = tf.sigmoid( tf.matmul(tf.reshape(x[i1][i2], [1, self.sequence_length]), self.w_igate) + tf.matmul(ht_prev, self.u_igate) )
                self.ot = tf.sigmoid( tf.matmul(tf.reshape(x[i1][i2], [1, self.sequence_length]), self.w_ogate) + tf.matmul(ht_prev, self.u_ogate) )
                self._ct = tf.sigmoid( tf.matmul(tf.reshape(x[i1][i2], [1, self.sequence_length]), self.w_cgate) + tf.matmul(ht_prev, self.u_cgate) )
                self.ct = tf.tanh(tf.multiply(self.ft, ct_prev) + tf.multiply(self.it, self._ct))
                self.ht = tf.multiply(self.ot, self.ct)
                ht_prev = self.ht
                ct_prev = self.ct
                outputs[i2] = tf.nn.relu( tf.matmul(self.ht, self.w_output_layer) )
            loss = tf.reduce_mean(tf.square(tf.subtract(outputs, self.trainy_batches[i1])))
            self.ht_prev = ht_prev
            self.ct_prev = ct_prev
            self.train_op = tf.train.AdamOptimizer(learning_rate=self.learning_rate).minimize(loss)
        print("\n Graph built \n\n Now training begins...\n")

        #training 
        i = 0
        avg_loss = float(0)
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            #sess = tf_debug.LocalCLIDebugWrapperSession(sess)
            for ep in range(self.n_epochs + 1):
                #ht_prev = np.float32([0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size)
                #ct_prev = np.float32([0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size)
                #loss.eval( feed_dict= { x: np.float32(self.trainx_batches).reshape(self.n_train_batches, self.batch_size, self.sequence_length) })
                sess.run(self.train_op)#, feed_dict= { x: np.float32(self.trainx_batches).reshape(self.n_train_batches, self.batch_size, self.sequence_length) } )#, ht_prev: np.float32([0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size), ct_prev: np.float32([0.0]*(self.hidden_layers_size)).reshape(1, self.hidden_layers_size) })
                if ep % 10 == 0:
                    i += 1
                    mse = loss.eval()# feed_dict= { x: np.float32(self.trainx_batches).reshape(self.n_train_batches, self.batch_size, self.sequence_length) })
                    avg_loss = float(avg_loss + mse)
                    print("\n Epoch: ", ep, "\t Loss: ", mse)
            avg_loss = float(avg_loss/i)
            self.training_loss = avg_loss
        print("\n Training Loss: ", avg_loss)

    # Predict function
    def predict(self):
        print("\n testing begins...")
        x_test_row = tf.placeholder(tf.float32, shape = [1, self.sequence_length])
        avg_error = float(0)
        input_row = []
        output_row = 0.0
        predictions = []
        #ht_prev = tf.placeholder(tf.float32, shape = [1, self.hidden_layers_size]) # ht_prev = tf.varaible(self.ht_prev)
        #ct_prev = tf.placeholder(tf.float32, shape = [1, self.hidden_layers_size]) # ct_prev = tf.varaible(self.ct_prev)
        # one forward pass
        self.ft = tf.sigmoid( tf.matmul(x_test_row, self.w_fgate) + tf.matmul(self.ht_prev, self.u_fgate) )
        self.it = tf.sigmoid( tf.matmul(x_test_row, self.w_igate) + tf.matmul(self.ht_prev, self.u_igate ) )
        self.ot = tf.sigmoid( tf.matmul(x_test_row, self.w_ogate) + tf.matmul(self.ht_prev, self.u_ogate) )
        self._ct = tf.sigmoid( tf.matmul(x_test_row, self.w_cgate) + tf.matmul(self.ht_prev, self.u_cgate) )
        self.ct = tf.tanh(tf.multiply(self.ft, self.ct_prev) + tf.multiply(self.it, self._ct))
        self.ht = tf.multiply(self.ot,self.ct)
        pred_output = tf.nn.relu( tf.matmul(self.ht, self.w_output_layer) )
        with tf.Session() as sess:
            sess.run([tf.global_variables_initializer(), tf.local_variables_initializer()])
            print("\n loaded the variables")
            for i1 in range(self.n_test):
                del input_row[:]
                output_row = float(self.testy[i1])
                for i2 in range(self.sequence_length):
                    input_row.append(self.testx[i1][i2])
                #sess.run(pred_output, feed_dict = { x_test_row: np.array(input_row).reshape(1, self.sequence_length), ht_prev:self.ht_prev, ct_prev: self.ct_prev })
                predictions.append([pred_output.eval(feed_dict = { x_test_row: np.float32(input_row).reshape(1, self.sequence_length) }), output_row])
                avg_error += abs(predictions[i1][0] - output_row)
            avg_error = float(avg_error/i1)
            self.testing_loss = avg_error
        print("\n testing Error: ", avg_error)
        return np.array(predictions)

    # save model function   
    def save_model(self):
        print("\n\n model's information saved in model_info.txt and weights stored in model.json\n\n")
        f = open("model.json", "w+")
        model_dict = { 'w_output_layer': self.w_output_layer, 'w_igate': self.w_igate, 'u_igate': self.u_igate, 'w_fgate': self.w_fgate, 'u_fgate': self.u_fgate, 'w_cgate': self.w_cgate, 'u_cgate': self.u_cgate, 'w_ogate': self.w_ogate, 'u_ogate': self.u_ogate }
        f.write(str(model_dict))
        f.close()

# main function()
def main():

    # parameters of the network
    config_params = dict()
    config_params["sequence_length"] = 3
    config_params["batch_size"] = 33
    config_params["hidden_layers_size"] = 9
    config_params["data_path"] = "data.csv"
    config_params["no_of_epochs"] = 2000
    config_params["learning_rate"] = 0.01

    # object of class lstm_network
    test_object = lstm_network(config_params)
    test_object.load_data()
    test_object.build_graph_train()
    predictions = test_object.predict()
    print("\n predictions are: \n", predictions)
    test_object.save_model()

# run
main()

用于此配置:

我得到的平均测试错误是:0.15911798179149628

我得到的平均训练错误是:0.10901389649110053

由于规范化值

,它们看起来很低

0 个答案:

没有答案