File size: 2,823 Bytes
cc50161
 
 
 
 
 
89c4568
cc50161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89c4568
cc50161
 
 
 
 
 
 
 
 
 
 
 
 
 
89c4568
cc50161
 
 
 
 
89c4568
cc50161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import tensorflow.keras as tf
import numpy as np
from sklearn.preprocessing import StandardScaler

verbose = 0

# TODO: Refactor this module

def predict_series(values, r1_nodes=5, r2_nodes=0, fc1_nodes=0, steps=20, use_lstm=True, *args, **kwargs):
    
    train = np.array(values)
    
    train_last_value = train[-1]
    train = train[1:] - train[:-1]
    sc = StandardScaler()
    train = sc.fit_transform(train.reshape(-1, 1))

    T = 25
    X = []
    Y = []
    for t in range(len(train) - T):
        x = train[t:t + T]
        X.append(x)
        Y.append(train[t + T])

    X = np.array(X).reshape(-1, T, 1)
    Y = np.array(Y)

    i = tf.layers.Input(shape=(T, 1))
    if use_lstm:
        rnn_layer = tf.layers.LSTM
    else:
        rnn_layer = tf.layers.GRU
    if r2_nodes:
        x = rnn_layer(r1_nodes, return_sequences=True)(i)
        x = rnn_layer(r2_nodes)(x)
    else:
        x = rnn_layer(r1_nodes)(i)
    if fc1_nodes:
        x = tf.layers.Dense(fc1_nodes, activation='relu')(x)
    x = tf.layers.Dense(1)(x)
    model = tf.models.Model(i, x)
    
    # TODO: optimize execution time
    """lr_schedule = tf.optimizers.schedules.ExponentialDecay(
        initial_learning_rate=0.2,
        decay_steps=10,
        decay_rate=0.8)
    optimizer = tf.optimizers.Ftrl(learning_rate=0.001, learning_rate_power=-0.1)"""

    model.compile(
        loss='mse', #tf.losses.LogCosh(),
        optimizer=tf.optimizers.Adamax(lr=0.1) #LogCosh()'sgd'
    )

    callbacks = [tf.callbacks.EarlyStopping(patience=150, monitor='loss', restore_best_weights=True)]

    r = model.fit(
        X, Y,
        epochs=500,
        callbacks=callbacks,
        verbose=verbose,
        validation_split=0.0
    )
    pred = np.array([])
    last_x = X[-1]


    for _ in range(steps):
        p = model.predict(last_x.reshape(1, -1, 1))[0, 0]
        pred = np.append(pred, p)
        last_x = np.roll(last_x, -1)
        last_x[-1] = p

    pred = sc.inverse_transform(pred.reshape(-1, 1))
    
    pred.reshape(-1)
    pred[0] = train_last_value + pred[0]
    
    for i in range(1, len(pred)):
        pred[i] += pred[i-1]
    

    result = {'result': list(pred.reshape(-1)), 'epochs': r.epoch[-1] + 1, 'loss': min(r.history['loss']), 'loss_last': r.history['loss'][-1]}
    return result


if __name__ == "__main__":
    from time import time
    t1 = time()
    verbose = 2
    data = np.sin(np.arange(0.0, 28.0, 0.35)*2)
    result = predict_series(data, steps=66, r1_nodes=14, r2_nodes=14, fc1_nodes=20)
    print('exec time: {:8.3f}'.format(time()-t1))
    #print(result['result'][:2])
    print(print(result['epochs'], result['loss']))
    import seaborn as sns
    sns.lineplot(x=range(30), y=data[-30:], color='r')
    sns.lineplot(x=range(30, 30+len(result['result'])), y=result['result'], color='b')