umz21/lab/10_Sieci_neuronowe.ipynb
2021-03-05 08:21:24 +01:00

590 KiB
Raw Blame History

Uczenie maszynowe 2019/2020 laboratoria

18/19 maja 2020

10. Sieci neuronowe - wprowadzenie

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)

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

Część zaawansowana (2 punkty)

Zastosuj poniższą implementację sieci neuronowej do klasyfikacji binarnej zbioru wygenerowanego za pomocą wybranej funkcji sklearn.datasets. Ustal rozmiary warstw wejściowej ($n \gt 2$) i ukrytej, 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: Napisz funkcję obliczającą skuteczność.
    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: Wypisz skuteczność (accuracy) klasyfikacji w tym miejscu

    return W1, b1, W2, b2
X, y = generate_data()
visualize(X, y)
model = train(initialize_model(dim_hid=5), X, y, debug=True)
visualize(X, y, model)
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