Aquí está mi código:

# Library Imports
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
plt.style.use("ggplot")

from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout

# Loading/Reading in the Data
df = pd.read_csv("BTC-USD.csv")


# Data Preprocessing
### Setting the datetime index as the date, only selecting the 'Close' column, then only the last 1000 closing prices.
df = df.set_index("Date")[['Close']].tail(3000)
df = df.set_index(pd.to_datetime(df.index))

# Normalizing/Scaling the Data
scaler = MinMaxScaler()
df = pd.DataFrame(scaler.fit_transform(df), columns=df.columns, index=df.index)


def visualize_training_results(results):
    """
    Plots the loss and accuracy for the training and testing data
    """
    history = results.history
    plt.figure(figsize=(12,4))
    plt.plot(history['val_loss'])
    plt.plot(history['loss'])
    plt.legend(['val_loss', 'loss'])
    plt.title('Loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.show()
    
    plt.figure(figsize=(12,4))
    plt.plot(history['val_accuracy'])
    plt.plot(history['accuracy'])
    plt.legend(['val_accuracy', 'accuracy'])
    plt.title('Accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.show()
    
    
def split_sequence(seq, n_steps_in, n_steps_out):
    """
    Splits the univariate time sequence
    """
    X, y = [], []
    
    for i in range(len(seq)):
        end = i + n_steps_in
        out_end = end + n_steps_out
        
        if out_end > len(seq):
            break
        
        seq_x, seq_y = seq[i:end], seq[end:out_end]
        
        X.append(seq_x)
        y.append(seq_y)
    
    return np.array(X), np.array(y)


def layer_maker(n_layers, n_nodes, activation, drop=None, d_rate=.5):
    """
    Create a specified number of hidden layers for an RNN
    Optional: Adds regularization option, dropout layer to prevent potential overfitting if necessary
    """
    
    # Creating the specified number of hidden layers with the specified number of nodes
    for x in range(1,n_layers+1):
        model.add(LSTM(n_nodes, activation=activation, return_sequences=True))

        # Adds a Dropout layer after every Nth hidden layer (the 'drop' variable)
        try:
            if x % drop == 0:
                model.add(Dropout(d_rate))
        except:
            pass

# How many periods looking back to train
n_per_in  = 30

# How many periods ahead to predict
n_per_out = 10

# Features (in this case it's 1 because there is only one feature: price)
n_features = 1

# Splitting the data into appropriate sequences
X, y = split_sequence(list(df.Close), n_per_in, n_per_out)

# Reshaping the X variable from 2D to 3D
X = X.reshape((X.shape[0], X.shape[1], n_features))

# Instantiating the model
model = Sequential()

# Activation
activ = "softsign"

# Input layer
model.add(LSTM(30, activation=activ, return_sequences=True, input_shape=(n_per_in, n_features)))

# Hidden layers
layer_maker(n_layers=6, n_nodes=12, activation=activ)

# Final Hidden layer
model.add(LSTM(10, activation=activ))

# Output layer
model.add(Dense(n_per_out))

# Model summary
model.summary()

plt.figure(figsize=(12,5))


#Im compiling the code here before training
model.compile()
#visualize_training_results(res)
res = model.fit(X, y, epochs=800, batch_size=32, validation_split=0.1)
#visualize_training_results(res)

¿Qué debo hacer exactamente aquí para poder comenzar a entrenar mi modelo?

También probé este código para compilar:

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=[
        metrics.MeanSquaredError(),
        metrics.AUC(),
    ]
)

Pero cuando ejecuto esto, obtengo un error de métricas no definidas. ¿Aunque lo defino allí mismo en la función de compilación?

Y yo también lo hice

model.compile(loss='categorical_crossentropy', optimizer='adam')

Que inicia el entrenamiento pero obtengo este resultado

Epoch 6/800
10/10 [==============================] - 1s 53ms/step - loss: nan - val_loss: nan
Epoch 7/800
10/10 [==============================] - 0s 43ms/step - loss: nan - val_loss: nan

Y cuando hago esto:

model.compile(loss='categorical_crossentropy',
              optimizer='sgd',
              metrics=['accuracy'])

Me sale esta salida

0/10 [==============================] - 0s 49ms/step - loss: nan - accuracy: 0.1128 - val_loss: nan - val_accuracy: 0.0606
Epoch 121/800
10/10 [==============================] - 0s 48ms/step - loss: nan - accuracy: 0.1086 - val_loss: nan - val_accuracy: 0.0606

Se entrena y la precisión funciona, pero todavía obtengo nan por pérdida y val_loss

No importa qué parámetros de función de compilación use, esto no está calculando la pérdida

Ahora probé esto

model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=["accuracy"],
)

Y esto es lo que obtengo

10/10 [==============================] - 1s 74ms/step - loss: nan - accuracy: 0.0953 - val_loss: nan - val_accuracy: 0.0606
Epoch 5/800
10/10 [==============================] - 1s 74ms/step - loss: nan - accuracy: 0.1097 - val_loss: nan - val_accuracy: 0.0606
Epoch 6/800
10/10 [==============================] - 1s 72ms/step - loss: nan - accuracy: 0.0929 - val_loss: nan - val_accuracy: 0.0606
-1
joe blow 14 mar. 2021 a las 23:28

1 respuesta

La mejor respuesta

Hay muchas razones por las que puede obtener NaN al entrenar su modelo.

  • los datos
  • función de pérdida que devuelve mayor / menor que + infinito / -infinito

Intente tomar 20 filas, asegúrese de mirar cada línea con sus propios ojos y luego ejecute el código para ver si todavía obtiene NAN. Si no lo hace, puede haber 1-2 entradas dañadas. De lo contrario, mire lo que devuelve split_sequence cuando usa solo esas 20 columnas.

Luego está el problema del infinito, que conduce a las NAN. Intente utilizar funciones de pérdida que estén limitadas.

Aquí hay una lista de funciones de pérdida de Keras

Si bien la desviación de la raíz cuadrada media devuelve un valor que "representa el error de forma natural en comparación con los datos de entrada" i.e. RMSE 30'000 <=> error in estimating house price by 30'000$, aún calcula el cuadrado, que definitivamente puede llegar al infinito demasiado rápido, por lo que no es una solución si ese es el problema aquí. Puede usar el MAE para mantenerlo bajo.

Actualizar:

Funcionó para mí. Usé lo siguiente, junto con un conjunto de datos similar para otra moneda cryptoboy en los EE. UU.:

# The good old SGD and MAE. 
model.compile(optimizer="sgd", loss="mae") # optional: metrics=['accuracy']

Tenga cuidado al usar Adams / Huber u otros optimizadores / funciones de pérdida. Debe comprender cómo funcionan, al menos saber cómo y por qué los usamos. Ahora, usar el SGD no es lo mejor, pero a partir de ahí tiene una base saludable para comenzar.

¡Buena suerte con tu esfuerzo! No sobreajuste, haga un modelo pequeño con pequeños conjuntos de datos para entrenar rápidamente y crear prototipos antes de ejecutar 800 épocas solo para descubrir que un parámetro no era viable. PROTOTIPO ! ¡Futuro te lo agradecerás! :)

1
Florian Fasmeyer 14 mar. 2021 a las 23:59