LSTM w TensorFlow

Sieci Neuronowe z Pamięcią

Long Short-Term Memory - praktycznie

 

Plan Prezentacji

  1. Czym jest LSTM i dlaczego jest potrzebne?
  2. Architektura LSTM - bramy i komórki pamięci
  3. Instalacja i przygotowanie środowiska
  4. Przygotowanie danych dla LSTM
  5. Budowanie modelu w TensorFlow/Keras
  6. Parametry i konfiguracja warstw
  7. Trening modelu krok po kroku
  8. Ewaluacja i predykcja
  9. Praktyczne przykłady zastosowań
  10. Rozwiązywanie problemów i optymalizacja

1. Czym jest LSTM? (powtórka)

LSTM (Long Short-Term Memory) to specjalny typ rekurencyjnej sieci neuronowej (RNN).

Problem tradycyjnych RNN:

  • Vanishing gradient - zanikający gradient
  • Trudności w uczeniu się długoterminowych zależności
  • Pamięć działa tylko na krótkich sekwencjach

Rozwiązanie LSTM:

  • Komórki pamięci (memory cells)
  • Bramki kontrolujące przepływ informacji
  • Możliwość zapamiętywania na bardzo długi czas
  • Selektywne zapominanie nieważnych informacji

Zastosowania LSTM

LSTM doskonale sprawdza się w problemach sekwencyjnych:

  • NLP (Natural Language Processing):
    • Tłumaczenie maszynowe
    • Generowanie tekstu
    • Analiza sentymentu
    • Chatboty i asystenci głosowi
  • Szeregi czasowe:
    • Prognozowanie cen akcji
    • Przewidywanie pogody
    • Analiza danych sensorycznych
  • Inne:
    • Rozpoznawanie mowy
    • Generowanie muzyki
    • Analiza wideo
    • Wykrywanie anomalii

2. Architektura LSTM

LSTM składa się z komórki pamięci i trzech bramek:

  • Forget Gate (bramka zapominania)
    • Decyduje co usunąć z pamięci komórki
    • Wartości 0-1: 0 = usuń wszystko, 1 = zachowaj wszystko
  • Input Gate (bramka wejściowa)
    • Decyduje jakie nowe informacje zapisać
    • Filtruje dane wejściowe
  • Output Gate (bramka wyjściowa)
    • Decyduje co wypuścić na wyjście
    • Kontroluje hidden state

Stan komórki (Cell State): główna pamięć, przepływa przez całą sekwencję z minimalnymi zmianami.

3. Instalacja i Przygotowanie

Instalacja TensorFlow i bibliotek

# Utwórz środowisko wirtualne
python -m venv lstm_env

# Aktywuj (Linux/Mac)
source lstm_env/bin/activate

# Aktywuj (Windows)
lstm_env\Scripts\activate

# Zainstaluj TensorFlow
pip install tensorflow

# Biblioteki pomocnicze
pip install numpy pandas matplotlib scikit-learn

# Sprawdź wersję TensorFlow
python -c "import tensorflow as tf; print(tf.__version__)"

# Opcjonalnie: Jupyter Notebook
pip install jupyter

Import Podstawowych Bibliotek

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# TensorFlow i Keras
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

# Preprocessing
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

# Sprawdź dostępność GPU
print("GPU dostępne:", tf.config.list_physical_devices('GPU'))
print("TensorFlow version:", tf.__version__)

# Ustaw seed dla powtarzalności
np.random.seed(42)
tf.random.set_seed(42)

4. Przygotowanie Danych

Format Danych dla LSTM

LSTM wymaga danych w formacie 3D:

(samples, timesteps, features)

  • samples - liczba próbek (przykładów)
  • timesteps - długość sekwencji (np. 30 dni)
  • features - liczba cech (np. temperatura, wilgotność)

Przykład:

Jeśli mamy 1000 sekwencji, każda po 50 kroków czasowych, z 3 cechami:

shape = (1000, 50, 3)

Tworzenie Sekwencji - Przykład

Funkcja do tworzenia sekwencji z szeregu czasowego:

def create_sequences(data, seq_length):
    """
    Tworzy sekwencje dla LSTM

    data: array 1D lub 2D z danymi
    seq_length: długość sekwencji (timesteps)

    Returns: X (sequences), y (targets)
    """
    X, y = [], []

    for i in range(len(data) - seq_length):
        # Sekwencja wejściowa
        X.append(data[i:i + seq_length])
        # Wartość docelowa (następny krok)
        y.append(data[i + seq_length])

    return np.array(X), np.array(y)

# Przykład użycia
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
X, y = create_sequences(data, seq_length=3)

print("X shape:", X.shape)  # (7, 3)
print("y shape:", y.shape)  # (7,)
print("Pierwsza sekwencja X:", X[0])  # [1, 2, 3]
print("Pierwszy target y:", y[0])      # 4

Normalizacja Danych

LSTM działa najlepiej z danymi znormalizowanymi do zakresu [0, 1] lub [-1, 1].

from sklearn.preprocessing import MinMaxScaler

# Przykładowe dane - ceny akcji
data = np.array([100, 102, 105, 103, 107, 110, 108]).reshape(-1, 1)

# Inicjalizacja skalera
scaler = MinMaxScaler(feature_range=(0, 1))

# Dopasuj i transformuj dane treningowe
data_scaled = scaler.fit_transform(data)

print("Oryginalne:", data.flatten())
print("Znormalizowane:", data_scaled.flatten())

# WAŻNE: Zapisz scaler do późniejszego odwrócenia transformacji
# Po predykcji musisz użyć: scaler.inverse_transform()

# Tworzenie sekwencji z znormalizowanych danych
X, y = create_sequences(data_scaled, seq_length=3)

# Reshape dla LSTM: dodaj wymiar features
X = X.reshape(X.shape[0], X.shape[1], 1)
print("X shape dla LSTM:", X.shape)  # (4, 3, 1)

Podział na Zbiory Treningowy i Testowy

# Dla szeregów czasowych: NIE mieszamy danych!
# Podział chronologiczny

train_size = int(len(X) * 0.8)

X_train = X[:train_size]
y_train = y[:train_size]

X_test = X[train_size:]
y_test = y[train_size:]

print(f"Dane treningowe: {X_train.shape}")
print(f"Dane testowe: {X_test.shape}")

# BŁĄD: Nie używaj train_test_split z shuffle=True!
# from sklearn.model_selection import train_test_split
# X_train, X_test, y_train, y_test = train_test_split(
#     X, y, test_size=0.2, shuffle=True  # ZŁE dla szeregów!
# )

# Opcjonalnie: walidacja
val_size = int(len(X_train) * 0.2)
X_val = X_train[-val_size:]
y_val = y_train[-val_size:]
X_train = X_train[:-val_size]
y_train = y_train[:-val_size]

5. Budowanie Modelu LSTM

Prosty Model LSTM

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

# Inicjalizacja modelu
model = Sequential()

# Warstwa LSTM
# units=50 - liczba jednostek LSTM (neuronów)
# input_shape=(timesteps, features)
model.add(LSTM(units=50, input_shape=(X_train.shape[1], X_train.shape[2])))

# Warstwa wyjściowa Dense
# 1 neuron - predykcja pojedynczej wartości
model.add(Dense(units=1))

# Podsumowanie modelu
model.summary()

# Kompilacja modelu
model.compile(
    optimizer='adam',
    loss='mean_squared_error',
    metrics=['mae']
)

6. Parametry Warstwy LSTM

Najważniejsze parametry LSTM:

  • units (wymagany)
    • Liczba jednostek LSTM (neuronów w warstwie)
    • Typowe wartości: 32, 50, 64, 128, 256
    • Więcej = większa pojemność, ale wolniejsze
  • return_sequences (default: False)
    • True: zwraca pełną sekwencję (dla kolejnych warstw LSTM)
    • False: zwraca tylko ostatnie wyjście
  • return_state (default: False)
    • True: dodatkowo zwraca hidden state i cell state
  • dropout (0.0 - 1.0)
    • Regularyzacja: losowo wyłącza neurony
    • Typowe: 0.2 (20%)

Dodatkowe Parametry LSTM

Pozostałe ważne parametry:

  • recurrent_dropout (0.0 - 1.0)
    • Dropout dla połączeń rekurencyjnych
  • activation (default: 'tanh')
    • Funkcja aktywacji dla bramek
    • Najczęściej: 'tanh' (domyślna)
  • recurrent_activation (default: 'sigmoid')
    • Aktywacja dla bramek forget/input/output
  • stateful (default: False)
    • True: zachowuje stany między batches
    • Wymaga stałego batch_size
  • go_backwards (default: False)
    • True: przetwarza sekwencję od końca

Model Wielowarstwowy (Stacked LSTM)

Używaj return_sequences=True dla wszystkich warstw LSTM oprócz ostatniej:

from tensorflow.keras.layers import LSTM, Dense, Dropout

model = Sequential()

# Pierwsza warstwa LSTM
# return_sequences=True - zwraca pełną sekwencję dla następnej warstwy
model.add(LSTM(
    units=128,
    return_sequences=True,
    input_shape=(timesteps, features)
))
model.add(Dropout(0.2))

# Druga warstwa LSTM
model.add(LSTM(units=64, return_sequences=True))
model.add(Dropout(0.2))

# Trzecia warstwa LSTM
# return_sequences=False - ostatnia warstwa, zwraca tylko końcowe wyjście
model.add(LSTM(units=32))
model.add(Dropout(0.2))

# Warstwy Dense
model.add(Dense(units=16, activation='relu'))
model.add(Dense(units=1))  # Wyjście

model.compile(optimizer='adam', loss='mse', metrics=['mae'])

Bidirectional LSTM

Bidirectional LSTM przetwarza sekwencję w obu kierunkach (od początku i od końca).

Kiedy używać:

  • Gdy kontekst z przyszłości jest dostępny (np. analiza tekstu)
  • NIE dla predykcji szeregów czasowych (nie mamy przyszłości!)

from tensorflow.keras.layers import Bidirectional, LSTM, Dense

model = Sequential()

# Bidirectional LSTM
# Podwaja liczbę parametrów (forward + backward)
model.add(Bidirectional(
    LSTM(units=64, return_sequences=True),
    input_shape=(timesteps, features)
))

model.add(Bidirectional(LSTM(units=32)))

model.add(Dense(units=1))

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

# Output shape po Bidirectional(LSTM(64)):
# (batch_size, 128) - 64*2 jednostek

Kompilacja Modelu - Optimizer i Loss

# Dla regresji (przewidywanie wartości ciągłych)
model.compile(
    optimizer='adam',
    loss='mean_squared_error',  # lub 'mse'
    metrics=['mae', 'mse']
)

# Dla klasyfikacji binarnej
model.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['accuracy']
)

# Dla klasyfikacji wieloklasowej
model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

# Dostosowany learning rate
from tensorflow.keras.optimizers import Adam

optimizer = Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='mse', metrics=['mae'])

7. Trening Modelu

Podstawowy Trening

# Trening modelu
history = model.fit(
    X_train, y_train,
    epochs=50,              # Liczba epok
    batch_size=32,          # Rozmiar batcha
    validation_data=(X_val, y_val),  # Dane walidacyjne
    verbose=1               # 1=progress bar, 0=cichy, 2=jedna linia na epokę
)

# Parametry:
# - epochs: ile razy przejść przez cały zbiór treningowy
# - batch_size: ile próbek w jednym batchu (32, 64, 128)
# - validation_data: opcjonalnie dane do walidacji
# - validation_split: alternatywnie % danych treningowych (np. 0.2)

# Historia treningu
print("Loss treningowy:", history.history['loss'])
print("Loss walidacyjny:", history.history['val_loss'])

Callbacks - EarlyStopping i ModelCheckpoint

from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

# EarlyStopping - zatrzymaj gdy nie ma poprawy
early_stop = EarlyStopping(
    monitor='val_loss',     # Monitoruj loss walidacyjny
    patience=10,            # Czekaj 10 epok bez poprawy
    restore_best_weights=True,  # Przywróć najlepsze wagi
    verbose=1
)

# ModelCheckpoint - zapisz najlepszy model
checkpoint = ModelCheckpoint(
    'best_model.h5',        # Nazwa pliku
    monitor='val_loss',
    save_best_only=True,    # Zapisz tylko najlepszy
    verbose=1
)

# Trening z callbacks
history = model.fit(
    X_train, y_train,
    epochs=100,
    batch_size=32,
    validation_data=(X_val, y_val),
    callbacks=[early_stop, checkpoint],
    verbose=1
)

print(f"Trening zatrzymany po {len(history.history['loss'])} epokach")

Wizualizacja Procesu Treningu

import matplotlib.pyplot as plt

# Wykres loss
plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)

# Wykres MAE
plt.subplot(1, 2, 2)
plt.plot(history.history['mae'], label='Train MAE')
plt.plot(history.history['val_mae'], label='Validation MAE')
plt.title('Model MAE')
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()

# Diagnoza: jeśli val_loss rośnie a train_loss maleje = overfitting!

8. Ewaluacja i Predykcja

Ewaluacja Modelu

# Ewaluacja na zbiorze testowym
test_loss, test_mae = model.evaluate(X_test, y_test, verbose=0)
print(f"Test Loss: {test_loss:.4f}")
print(f"Test MAE: {test_mae:.4f}")

# Predykcja
predictions = model.predict(X_test)

# Odwrócenie normalizacji
predictions = scaler.inverse_transform(predictions)
y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))

# Metryki
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

mse = mean_squared_error(y_test_actual, predictions)
mae = mean_absolute_error(y_test_actual, predictions)
rmse = np.sqrt(mse)
r2 = r2_score(y_test_actual, predictions)

print(f"MSE: {mse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"R²: {r2:.4f}")

Wizualizacja Predykcji

import matplotlib.pyplot as plt

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

# Wykres porównania
plt.plot(y_test_actual, label='Rzeczywiste wartości', marker='o')
plt.plot(predictions, label='Predykcje', marker='x')
plt.title('LSTM - Predykcje vs Rzeczywiste wartości')
plt.xlabel('Próbka')
plt.ylabel('Wartość')
plt.legend()
plt.grid(True)
plt.show()

# Scatter plot
plt.figure(figsize=(8, 8))
plt.scatter(y_test_actual, predictions, alpha=0.5)
plt.plot([y_test_actual.min(), y_test_actual.max()],
         [y_test_actual.min(), y_test_actual.max()],
         'r--', lw=2)
plt.xlabel('Rzeczywiste wartości')
plt.ylabel('Predykcje')
plt.title('Predykcje vs Rzeczywiste')
plt.grid(True)
plt.show()

Predykcja Przyszłych Wartości

def predict_future(model, last_sequence, n_steps, scaler):
    """
    Predykcja n kroków w przyszłość

    model: wytrenowany model LSTM
    last_sequence: ostatnia znana sekwencja (znormalizowana)
    n_steps: ile kroków przewidzieć
    scaler: do odwrócenia normalizacji
    """
    predictions = []
    current_sequence = last_sequence.copy()

    for _ in range(n_steps):
        # Reshape do formatu (1, timesteps, features)
        input_seq = current_sequence.reshape(1, timesteps, features)

        # Predykcja następnej wartości
        next_pred = model.predict(input_seq, verbose=0)
        predictions.append(next_pred[0, 0])

        # Aktualizuj sekwencję: usuń pierwszy element, dodaj predykcję
        current_sequence = np.append(current_sequence[1:], next_pred)

    # Odwróć normalizację
    predictions = scaler.inverse_transform(np.array(predictions).reshape(-1, 1))
    return predictions

# Użycie
future_predictions = predict_future(model, X_test[-1], n_steps=10, scaler=scaler)
print("Predykcje na 10 kroków:", future_predictions.flatten())

9. Praktyczne Przykłady

Przykład 1: Prognozowanie Cen Akcji

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

# 1. Wczytaj dane
df = pd.read_csv('stock_prices.csv')
data = df['Close'].values.reshape(-1, 1)

# 2. Normalizacja
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data)

# 3. Tworzenie sekwencji (60 dni -> przewiduj następny)
seq_length = 60
X, y = create_sequences(data_scaled, seq_length)
X = X.reshape(X.shape[0], X.shape[1], 1)

# 4. Podział danych
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

Przykład 1: Model LSTM dla Akcji

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dropout, Dense
from tensorflow.keras.callbacks import EarlyStopping

# 5. Budowa modelu
model = Sequential([
    LSTM(128, return_sequences=True, input_shape=(60, 1)),
    Dropout(0.3),
    LSTM(64, return_sequences=True),
    Dropout(0.3),
    LSTM(32),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer='adam', loss='mse', metrics=['mae'])

# 6. Trening
early_stop = EarlyStopping(monitor='val_loss', patience=15,
                          restore_best_weights=True)

history = model.fit(
    X_train, y_train,
    epochs=100,
    batch_size=32,
    validation_split=0.1,
    callbacks=[early_stop],
    verbose=1
)

# 7. Predykcja i odwrócenie normalizacji
predictions = model.predict(X_test)
predictions = scaler.inverse_transform(predictions)
y_test_actual = scaler.inverse_transform(y_test)

Przykład 2: Analiza Sentymentu Tekstu

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, LSTM, Dense

# 1. Przykładowe dane
texts = ["Film był świetny!", "Okropny film", "Nieźle", "Fantastyczny!"]
labels = [1, 0, 1, 1]  # 1=pozytywny, 0=negatywny

# 2. Tokenizacja
tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)

# 3. Padding - wyrównaj długości
max_length = 20
X = pad_sequences(sequences, maxlen=max_length, padding='post')
y = np.array(labels)

# 4. Model z Embedding
vocab_size = 5000
embedding_dim = 128

model = Sequential([
    Embedding(vocab_size, embedding_dim, input_length=max_length),
    LSTM(64, dropout=0.2),
    Dense(1, activation='sigmoid')
])

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

model.fit(X, y, epochs=10, batch_size=32)

Przykład 3: Przewidywanie Temperatury

import pandas as pd

# 1. Dane pogodowe (wiele cech)
df = pd.read_csv('weather.csv')
features = ['temperature', 'humidity', 'pressure', 'wind_speed']
data = df[features].values

# 2. Normalizacja dla każdej cechy
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 3. Sekwencje (7 dni -> przewiduj temperaturę)
seq_length = 7
X, y = [], []
for i in range(len(data_scaled) - seq_length):
    X.append(data_scaled[i:i+seq_length])
    y.append(data_scaled[i+seq_length, 0])  # Tylko temperatura

X = np.array(X)  # shape: (samples, 7, 4)
y = np.array(y)  # shape: (samples,)

# 4. Model wielocechowy
model = Sequential([
    LSTM(64, return_sequences=True, input_shape=(7, 4)),
    LSTM(32),
    Dense(16, activation='relu'),
    Dense(1)
])

model.compile(optimizer='adam', loss='mse')
model.fit(X, y, epochs=50, batch_size=32, validation_split=0.2)

10. Rozwiązywanie Problemów

Problem: Overfitting (Przeuczenie)

Objawy:

  • Train loss maleje, val_loss rośnie
  • Doskonałe wyniki na treningu, słabe na teście

Rozwiązania:

  • Dropout - dodaj warstwy Dropout(0.2-0.5)
  • Regularizacja L1/L2 - kara za duże wagi
  • Więcej danych - zbierz więcej przykładów treningowych
  • Mniej jednostek - zmniejsz units w LSTM
  • Early Stopping - zatrzymaj gdy val_loss przestaje maleć
  • Data Augmentation - generuj więcej danych

Problem: Underfitting (Niedouczenie)

Objawy:

  • Train loss i val_loss wysokie
  • Model nie uczy się wzorców

Rozwiązania:

  • Więcej jednostek - zwiększ units w LSTM (64→128→256)
  • Więcej warstw - dodaj kolejne warstwy LSTM
  • Dłuższy trening - zwiększ epochs
  • Lepsze cechy - dodaj więcej informacji do danych
  • Zmniejsz regularizację - mniejszy dropout
  • Inny learning rate - dostosuj optimizer

# Przykład: zwiększenie pojemności modelu
model = Sequential([
    LSTM(256, return_sequences=True, input_shape=(timesteps, features)),
    LSTM(128, return_sequences=True),
    LSTM(64),
    Dense(32, activation='relu'),
    Dense(1)
])

Problem: Wolne Uczenie / Vanishing Gradient

Objawy:

  • Loss nie maleje lub maleje bardzo wolno
  • Model "stoi w miejscu"

Rozwiązania:

# 1. Gradient Clipping
from tensorflow.keras.optimizers import Adam

optimizer = Adam(learning_rate=0.001, clipnorm=1.0)
model.compile(optimizer=optimizer, loss='mse')

# 2. Batch Normalization
from tensorflow.keras.layers import BatchNormalization

model = Sequential([
    LSTM(64, return_sequences=True, input_shape=(timesteps, features)),
    BatchNormalization(),
    LSTM(32),
    BatchNormalization(),
    Dense(1)
])

# 3. Zmiana learning rate
optimizer = Adam(learning_rate=0.01)  # Większy LR

# 4. Learning Rate Schedule
from tensorflow.keras.callbacks import ReduceLROnPlateau

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5,
                             patience=5, min_lr=1e-7)
model.fit(X_train, y_train, callbacks=[reduce_lr])

Optymalizacja Hiperparametrów

Kluczowe hiperparametry do dostrojenia:

  • Liczba jednostek LSTM: 32, 64, 128, 256
  • Liczba warstw: 1, 2, 3
  • Dropout rate: 0.0, 0.2, 0.3, 0.5
  • Learning rate: 0.0001, 0.001, 0.01
  • Batch size: 16, 32, 64, 128
  • Sequence length: 10, 30, 60, 100

Metody optymalizacji:

  • Grid Search - przeszukiwanie siatki
  • Random Search - losowe próbkowanie
  • Bayesian Optimization - inteligentne przeszukiwanie

Zapisywanie i Ładowanie Modelu

# Zapisz cały model (architektura + wagi + optimizer)
model.save('lstm_model.h5')
# lub w nowym formacie:
model.save('lstm_model.keras')

# Zapisz tylko wagi
model.save_weights('lstm_weights.h5')

# Zapisz jako SavedModel (TensorFlow format)
model.save('saved_model/')

# Załaduj model
from tensorflow.keras.models import load_model
model = load_model('lstm_model.h5')

# Załaduj tylko wagi (wymaga wcześniejszego zbudowania modelu)
model.load_weights('lstm_weights.h5')

# Zapisz scaler (ważne!)
import pickle
with open('scaler.pkl', 'wb') as f:
    pickle.dump(scaler, f)

# Załaduj scaler
with open('scaler.pkl', 'rb') as f:
    scaler = pickle.load(f)

# Predykcja załadowanym modelem
predictions = model.predict(X_test)

Przyspieszenie z GPU

LSTM jest bardzo wymagający obliczeniowo - GPU może przyspieszyć trening 10-50x!

import tensorflow as tf

# Sprawdź dostępność GPU
print("GPU dostępne:", len(tf.config.list_physical_devices('GPU')) > 0)
print("Urządzenia:", tf.config.list_physical_devices())

# Wymuś użycie CPU (do testów)
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

# Wymuś użycie GPU 0
os.environ['CUDA_VISIBLE_DEVICES'] = '0'

# Ogranicz pamięć GPU
gpus = tf.config.list_physical_devices('GPU')
if gpus:
    try:
        tf.config.set_logical_device_configuration(
            gpus[0],
            [tf.config.LogicalDeviceConfiguration(memory_limit=4096)]
        )
    except RuntimeError as e:
        print(e)

# Mixed Precision - szybsze obliczenia na GPU
from tensorflow.keras import mixed_precision
policy = mixed_precision.Policy('mixed_float16')
mixed_precision.set_global_policy(policy)

Best Practices - Dobre Praktyki

1. Przygotowanie danych:

  • Zawsze normalizuj dane (MinMaxScaler lub StandardScaler)
  • Zachowaj kolejność chronologiczną (nie shuffle!)
  • Użyj odpowiedniej długości sekwencji

2. Architektura modelu:

  • Zacznij od prostego modelu, potem komplikuj
  • Użyj Dropout dla regularyzacji (0.2-0.3)
  • return_sequences=True dla warstw pośrednich

3. Trening:

  • Użyj EarlyStopping i ModelCheckpoint
  • Monitoruj val_loss, nie train_loss
  • Zapisz scaler razem z modelem!

4. Ewaluacja:

  • Testuj na danych spoza okresu treningowego
  • Wizualizuj predykcje
  • Używaj wielu metryk (MAE, RMSE, R²)

Zasoby i Dalsze Kroki

Dokumentacja:

  • TensorFlow/Keras: tensorflow.org/api_docs
  • LSTM Layer: keras.io/api/layers/recurrent_layers/lstm

Dalsze tematy do nauki:

  • GRU - prostszy wariant LSTM
  • Attention Mechanism - mechanizm uwagi
  • Transformer - nowoczesna architektura (BERT, GPT)
  • Seq2Seq - encoder-decoder
  • Time Series Cross-Validation - walidacja krzyżowa dla szeregów

Praktyka:

  • Kaggle - konkursy i datasety
  • Papers with Code - implementacje artykułów
  • TensorFlow Tutorials - oficjalne tutoriale

Kompletny Przykład - Kod od A do Z

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping

# 1. Dane
data = np.sin(np.linspace(0, 100, 1000)).reshape(-1, 1)

# 2. Normalizacja
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data)

# 3. Sekwencje
def create_sequences(data, seq_length):
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length])
    return np.array(X), np.array(y)

X, y = create_sequences(data_scaled, 50)
X = X.reshape(X.shape[0], X.shape[1], 1)

Kompletny Przykład - Model i Trening

# 4. Podział
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

# 5. Model
model = Sequential([
    LSTM(64, return_sequences=True, input_shape=(50, 1)),
    Dropout(0.2),
    LSTM(32),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer='adam', loss='mse', metrics=['mae'])

# 6. Trening
early_stop = EarlyStopping(monitor='val_loss', patience=10,
                          restore_best_weights=True)

history = model.fit(X_train, y_train, epochs=100, batch_size=32,
                   validation_split=0.1, callbacks=[early_stop])

# 7. Ewaluacja
predictions = model.predict(X_test)
predictions = scaler.inverse_transform(predictions)
y_test_actual = scaler.inverse_transform(y_test)

# 8. Zapisz
model.save('lstm_sine.h5')
print("Model gotowy!")

Podsumowanie

Co się nauczyliśmy:

  • Czym jest LSTM i jak działa (bramki, cell state)
  • Instalacja TensorFlow i przygotowanie środowiska
  • Przygotowanie danych w formacie 3D (samples, timesteps, features)
  • Normalizacja i tworzenie sekwencji
  • Budowanie modeli: jednowarstwowych i stackowanych
  • Kluczowe parametry: units, return_sequences, dropout
  • Trening z callbacks (EarlyStopping, ModelCheckpoint)
  • Ewaluacja i wizualizacja wyników
  • Praktyczne przykłady: akcje, sentiment, pogoda
  • Rozwiązywanie problemów: overfitting, underfitting
  • Best practices i częste błędy

Kluczowe Wskazówki na Zakończenie

 

Pamiętaj:

  • Start Simple - zacznij od prostego modelu (1-2 warstwy LSTM)
  • Normalizuj zawsze - LSTM wymaga znormalizowanych danych
  • Format 3D - (samples, timesteps, features) dla LSTM
  • Chronologia - nie shuffle'uj szeregów czasowych!
  • Zapisz scaler - potrzebny do odwrócenia predykcji
  • Early Stopping - oszczędza czas i zapobiega overfitting
  • GPU - dla dużych modeli przyspiesza 10-50x
  • Eksperymentuj - testuj różne architektury i hiperparametry

Następny krok: Wybierz problem i zacznij praktykę!

 

Dziękuję za Uwagę!

Pytania?

"The future depends on what you do today" - Przyszłość zależy od tego, co robisz dzisiaj

Powodzenia w budowaniu modeli LSTM! 

LSTM w TensorFlow - Sieci Neuronowe z Pamięcią

By noinputsignal

Private

LSTM w TensorFlow - Sieci Neuronowe z Pamięcią