Нейронная сеть и plot_decision_regions?

#python #neural-network

#python #нейронная сеть

Вопрос:

Я создал нейронную сеть, следуя инструкциям на этом веб-сайте:

https://machinelearningmastery.com/implement-backpropagation-algorithm-scratch-python/

И моя нейронная сеть — это одна:

 from random import seed
from random import randrange
from random import random
from csv import reader
from math import exp


# Attivazione del neurone
def activate(pesi, inputs):
    activation = pesi[-1]
    for i in range(len(pesi)-1):
        activation  = pesi[i] * inputs[i]
    return activation
 
# Transfer function scelta
def transfer(activation):
    return 1.0 / (1.0   exp(-activation))
 
# Propagazione forward
def forward_propagate(network, row):
    inputs = row
    for layer in network:
        nuovi = []
        for neuron in layer:
            activation = activate(neuron['pesi'], inputs)
            neuron['output'] = transfer(activation)
            nuovi.append(neuron['output'])
        inputs = nuovi
    return inputs
 
# Derivata
def transfer_derivative(output):
    return output * (1.0 - output)
 
# Back Propagation
def backward_propagate_error(network, valore):
    for i in reversed(range(len(network))):
        layer = network[i]
        errorF = list()
        if i != len(network)-1:
            for j in range(len(layer)):
                errore = 0.0
                for neuron in network[i   1]:
                    errore  = (neuron['pesi'][j] * neuron['delta'])
                errorF.append(errore)
        else:
            for j in range(len(layer)):
                neuron = layer[j]
                errorF.append(valore[j] - neuron['output'])
        for j in range(len(layer)):
            neuron = layer[j]
            neuron['delta'] = errorF[j] * transfer_derivative(neuron['output'])

#aggiornamento pesi
def update_weights(network, row, Coeff):
    for i in range(len(network)):
        inputs = row[:-1]
        if i != 0:
            inputs = [neuron['output'] for neuron in network[i - 1]]
        for neuron in network[i]:
            for j in range(len(inputs)):
                neuron['pesi'][j]  = Coeff * neuron['delta'] * inputs[j]
            neuron['pesi'][-1]  = Coeff * neuron['delta']

#training della rete
def train_network(network, train, Coeff, NumEpoc, n_outputs):
    for epoch in range(NumEpoc):
        for row in train:
            outputs = forward_propagate(network, row)
            expected = [0 for i in range(n_outputs)]
            expected[int(row[-1])] = 1
            backward_propagate_error(network, expected)
            update_weights(network, row, Coeff)

#inizializzazione
def initialize_network(n_inputs, n_hidden, n_outputs):
    network = list()
    hidden_layer = [{'pesi':[random() for i in range(n_inputs   1)]} for i in range(n_hidden)]
    network.append(hidden_layer)
    output_layer = [{'pesi':[random() for i in range(n_hidden   1)]} for i in range(n_outputs)]
    network.append(output_layer)
    return network
 
# Predict
def predict( row):
    outputs = forward_propagate(network, row)
    return outputs.index(max(outputs))
 

Все идет очень хорошо, я тренирую его с:

 seed(1)


dataset = np.insert(XL,2,yL,axis=1)
n_inputs = len(dataset[0]) - 1

n_outputs = len(set([int(row[-1]) for row in dataset]))
network = initialize_network(n_inputs, 3, n_outputs)
train_network(network, dataset, 0.2, 2000, n_outputs)
 

И я могу предсказать с

 x=predict(network, XT[i])
 

Мой набор данных — это:

введите описание изображения здесь

и я создаю его с помощью:

 %matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mlxtend.plotting import plot_decision_regions
import matplotlib
matplotlib.rcParams['figure.figsize'] = [10, 10]

# data
def donut_data(N,noise=0.8):
    X = np.random.randn(N, 2)
    X_r = X   np.random.uniform(-noise,noise,X.shape)
    Y = np.logical_or(X_r[:, 0]*X_r[:, 0]   X_r[:, 1]*X_r[:, 1] < 0.3, X_r[:, 0]*X_r[:, 0]   X_r[:, 1]*X_r[:, 1]> 2)
    Y = np.where(Y, 1, -1)
    return X, Y

def plot_data(X,Y,c1='b',c2='r', toplot=True):
    plt.scatter(X[Y==1, 0], X[Y==1, 1],c=c1, marker='x', label='1')
    plt.scatter(X[Y==-1, 0], X[Y==-1, 1],c=c2, marker='s', label='-1')
    if toplot:
        plt.ylim(-3.0)
        plt.legend()
        plt.show()


N = 1000
noise = 0.5
XL, yL = donut_data(N, noise)
XT, yT = donut_data(N, noise)
plot_data(XL,yL,'b','r',True)
plot_data(XT,yT,'k','m', True)
 

Я хотел бы использовать plot_decision_regions (XT, yT, network) для построения регионов, но у меня проблема с этой программой.

Сеть — это простой список, а не объект класса, как ожидается в plot_decision_regions . Как я могу это преодолеть? Должен ли я переписать программу, используя network в качестве объекта класса?

Ответ №1:

Я думаю, что plot_decision_regions() действительно нуждается в сети (или любом классификаторе) в качестве объекта. Это потому, что внутри кода он применяет метод .predict() ко всей сетке, чтобы знать, как нейронная сеть классифицирует ее.

Посмотрите на код аналогичной функции:

 def plot_decision_regions(network, X, y, points=200):
    markers = ('o', '^')
    colors = ('red', 'blue')
    cmap = ListedColormap(colors)

    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max()   1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max()   1

    resolution = max(x1_max - x1_min, x2_max - x2_min) / float(points)

    xx1, xx2 = numpy.meshgrid(numpy.arange(x1_min,
                                           x1_max,
                                           resolution),
                              numpy.arange(x2_min, x2_max, resolution))
    input = numpy.array([xx1.ravel(), xx2.ravel()]).T
    Z = numpy.empty(0)

  #### In this loop, it applies .predict() #######
    for i in range(input.shape[0]):
        val = network.predict(numpy.array(input[i]))
        if val < 0.5:
            val = 0
        if val >= 0.5:
            val = 1
        Z = numpy.append(Z, val)

    Z = Z.reshape(xx1.shape)

    plt.pcolormesh(xx1, xx2, Z, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())
    # plot all samples

    classes = ["False", "True"]

    for idx, cl in enumerate(numpy.unique(y)):
        plt.scatter(x=X[y == cl, 0],
                    y=X[y == cl, 1],
                    alpha=1.0,
                    c=colors[idx],
                    edgecolors='black',
                    marker=markers[idx],
                    s=80,
                    label=classes[idx])

    plt.xlabel('x-axis')
    plt.ylabel('y-axis')
    plt.legend(loc='upper left')
    plt.show()