uczenie-maszynowe/lab/10_Sieci_neuronowe.ipynb
2023-05-25 11:00:24 +02:00

104 KiB
Raw Blame History

Uczenie maszynowe zastosowania

Zajęcia laboratoryjne

10. Wprowadzenie do sieci neuronowych

Poniżej znajduje się implementacja prostej sieci neuronowej dla problemu klasyfikacji binarnej na przykładzie losowo wygenerowanego zestawu danych.

W sieciach jednokierunkowych (ang. _feedforward) wartości neuronów w $i$-tej warstwie są obliczane na podstawie wartości neuronów warstwy $i-1$. Mając daną $n$-warstwową sieć neuronową oraz jej parametry $\Theta^{(1)}, \ldots, \Theta^{(n)} $ oraz $\beta^{(1)}, \ldots, \beta^{(n)}$ liczymy: $$a^{(i)} = g^{(i)}\left( a^{(i-1)} \Theta^{(i)} + \beta^{(i)} \right) ; , $$ gdzie $g^{(i)}$ to tzw. funkcje aktywacji

Zadanie 10

Część podstawowa (4 punkty)

  1. Zaimplementuj funkcję accuracy() liczącą skuteczność klasyfikacji we wskazanym miejscu.
  2. Za jej pomocą oblicz i wypisz końcową skuteczność klasyfikatora.
  3. Wypisuj również wartość accuracy podczas uczenia (przy okazji wypisywania wartości funkcji kosztu).
  4. Zbuduj sieci neuronowe dla różnych wielkości warstwy ukrytej (dim_hid = 1, 2, 5, 10, 25). Porównaj skuteczność tych modeli.

Część zaawansowana (3 punkty)

Zastosuj poniższą implementację sieci neuronowej do klasyfikacji binarnej zbioru wygenerowanego za pomocą wybranej funkcji sklearn.datasets. Ustal rozmiary warstw wejściowej i wyjściowej, dobierz odpowiednie parametry sieci (parametr $\alpha$, liczba epok, wielkość warstwy ukrytej). Podaj skuteczność klasyfikacji.

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt


def generate_data():
    # Keep results deterministic
    np.random.seed(1234)
    X, y = datasets.make_moons(200, noise=0.25)
    # X, y = datasets.make_classification(200, 2, 2, 0)
    return X, y

def visualize(X, y, model=None):
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    h = 0.01
    xx, yy = np.meshgrid(
        np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    if model:
        Z = predict(model, np.c_[xx.ravel(), yy.ravel()])
        Z = Z.reshape(xx.shape)
        plt.contourf(xx, yy, Z, cmap=plt.cm.viridis)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.viridis)
    plt.show()

def initialize_model(dim_in=2, dim_hid=3, dim_out=2):
    # Keep results deterministic
    np.random.seed(1234)
    W1 = np.random.randn(dim_in, dim_hid) / np.sqrt(dim_in)
    b1 = np.zeros((1, dim_hid))
    W2 = np.random.randn(dim_hid, dim_out) / np.sqrt(dim_hid)
    b2 = np.zeros((1, dim_out))
    return W1, b1, W2, b2

def softmax(X):
    e = np.exp(X)
    return e / np.sum(e, axis=1, keepdims=True)

def predict(model, X):
    W1, b1, W2, b2 = model
    z1 = X.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    probs = softmax(z2)
    return np.argmax(probs, axis=1)

def calculate_cost(model, X, y):
    W1, b1, W2, b2 = model
    z1 = X.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    probs = softmax(z2)
    preds = probs[:, 1]
    return -1. / len(y) * np.sum(
        np.multiply(y, np.log(preds)) + np.multiply(1 - y, np.log(1 - preds)),
        axis=0)

def accuracy(model, X, y):
    # TODO: 1. Napisz funkcję obliczającą skuteczność (accuracy).
    # Skorzystaj z funkcji `predict`.
    pass

def train(model, X, y, alpha=0.01, epochs=10000, debug=False):
    W1, b1, W2, b2 = model
    m = len(X)

    for i in range(epochs):
        # Forward propagation
        z1 = X.dot(W1) + b1
        a1 = np.tanh(z1)
        z2 = a1.dot(W2) + b2
        probs = softmax(z2)

        # Backpropagation
        delta3 = probs
        delta3[range(m), y] -= 1
        dW2 = (a1.T).dot(delta3)
        db2 = np.sum(delta3, axis=0, keepdims=True)
        delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
        dW1 = np.dot(X.T, delta2)
        db1 = np.sum(delta2, axis=0)

        # Parameter update
        W1 -= alpha * dW1
        b1 -= alpha * db1
        W2 -= alpha * dW2
        b2 -= alpha * db2

        # Print loss
        if debug and i % 1000 == 0:
            model = (W1, b1, W2, b2)
            print("Cost after iteration {}: {:.4f}".format(i, calculate_cost(
                model, X, y)))
            # TODO: 3. Wypisz skuteczność (accuracy) klasyfikacji w tym miejscu.
            
    # TODO: 2. Wypisz końcową skuteczność (accuracy) klasyfikacji w tym miejscu.
    return W1, b1, W2, b2
X, y = generate_data()
visualize(X, y)
model1 = train(initialize_model(dim_hid=5), X, y, debug=True)
visualize(X, y, model1)
Cost after iteration 0: 0.4692
Cost after iteration 1000: 0.1527
Cost after iteration 2000: 0.1494
Cost after iteration 3000: 0.1478
Cost after iteration 4000: 0.1458
Cost after iteration 5000: 0.1444
Cost after iteration 6000: 0.1433
Cost after iteration 7000: 0.1423
Cost after iteration 8000: 0.1415
Cost after iteration 9000: 0.1407
model2 = train(initialize_model(dim_hid=1), X, y, debug=True)
visualize(X, y, model2)
Cost after iteration 0: 0.6739
Cost after iteration 1000: 0.3618
Cost after iteration 2000: 0.3618
Cost after iteration 3000: 0.3618
Cost after iteration 4000: 0.3618
Cost after iteration 5000: 0.3618
Cost after iteration 6000: 0.3618
Cost after iteration 7000: 0.3618
Cost after iteration 8000: 0.3618
Cost after iteration 9000: 0.3618