Python 3.x 定制的神经网络为iris数据集提供0精度

Python 3.x 定制的神经网络为iris数据集提供0精度,python-3.x,numpy,neural-network,one-hot-encoding,Python 3.x,Numpy,Neural Network,One Hot Encoding,我用以下代码构建了虹膜分类的神经网络: from sklearn import datasets from scipy.optimize import minimize import numpy as np def train_test_split(X, y): idx = np.arange(len(X)) train_size = int(len(X) * 0.2) np.random.shuffle(idx) X = X[idx] y = y[id

我用以下代码构建了虹膜分类的神经网络:

from sklearn import datasets
from scipy.optimize import minimize
import numpy as np

def train_test_split(X, y):
    idx = np.arange(len(X))
    train_size = int(len(X) * 0.2)
    np.random.shuffle(idx)
    X = X[idx]
    y = y[idx]
    X_train, X_test = X[:train_size], X[train_size:]
    y_train, y_test = y[:train_size], y[train_size:]
    
    return X_train, X_test, y_train, y_test

iris = datasets.load_iris()
X = iris.data
y = iris.target

nb_classes = 3
targets = np.array([y]).reshape(-1)
Y = np.eye(nb_classes)[targets]

# randomize = np.arange(len(X))
# np.random.shuffle(randomize)
# X = X[randomize]
# Y = Y[randomize]

X_train, X_test, Y_train, Y_test = train_test_split(X, Y)
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train)

def optimize(X_train, Y_train, X_val=None, Y_val=None, epochs=10, nodes=[], lr=0.15):
    hidden_layers = len(nodes) - 1
    weights = init_weights(nodes)

    for epoch in range(1, epochs+1):
        weights = train(X_train, Y_train, lr, weights)

        if(epoch % 20 == 0):
            print("Epoch {}".format(epoch))
            print("Training accuracy:{}".format(acc(X_train, Y_train, weights)))
            if X_val.any():
                print("Validation Accuracy:{}".format(acc(X_val, Y_val, weights)))
            
    return weights

def init_weights(nodes):
    """Initialize weights with random values in [-1, 1] (including bias)"""
    layers, weights = len(nodes), []
    
    for i in range(1, layers):
        w = [[np.random.uniform(-1, 1) for k in range(nodes[i-1] + 1)]
              for j in range(nodes[i])]
        weights.append(np.matrix(w))
    
    return weights

def forward(x, weights, layers):
    activations, layer_input = [x], x
    for j in range(layers):
        activation = sigmoid(np.dot(layer_input, weights[j].T))
        activations.append(activation)
        layer_input = np.append(1, activation) # Augment with bias
    
    return activations

def back(y, activations, weights, layers):
    outputFinal = activations[-1]
    error = np.matrix(y - outputFinal) # Error at output
    
    for j in range(layers, 0, -1):
        currActivation = activations[j]
        
        if(j > 1):
            # Augment previous activation
            prevActivation = np.append(1, activations[j-1])
        else:
            # First hidden layer, prevActivation is input (without bias)
            prevActivation = activations[0]
        
        delta = np.multiply(error, sigmoid_gradient(currActivation))
        weights[j-1] += lr * np.multiply(delta.T, prevActivation)

        w = np.delete(weights[j-1], [0], axis=1) # Remove bias from weights
        error = np.dot(delta, w) # Calculate error for current layer
    
    return weights

def train(X, Y, lr, weights):
    layers = len(weights)
    for i in range(len(X)):
        x, y = X[i], Y[i]
        x = np.matrix(np.append(1, x)) # Augment feature vector
        
        activations = forward(x, weights, layers)
        weights = back(y, activations, weights, layers)

    return weights

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_gradient(x):
    return np.multiply(x, 1-x)

def predict(item, weights):
    layers = len(weights)
    item = np.append(1, item) # Augment feature vector
    
    ##_Forward Propagation_##
    activations = forward(item, weights, layers)
    
    outputFinal = activations[-1].A1
    index = FindMaxActivation(outputFinal)

    # Initialize prediction vector to zeros
    y = [0 for i in range(len(outputFinal))]
    y[index] = 1  # Set guessed class to 1

    return y # Return prediction vector

def FindMaxActivation(output):
    """Find max activation in output"""
    m, index = output[0], 0
    for i in range(1, len(output)):
        if(output[i] > m):
            m, index = output[i], i
    return index

def acc(X, Y, weights):
    """Run set through network, find overall accuracy"""
    correct = 0

    for i in range(len(X)):
#         x, y = X[i], list(Y[i])
        x, y = X[i], Y[i].tolist()
        guess = predict(x, weights)

        if(y == guess):
            # Guessed correctly
            correct += 1

    return correct / len(X)

f = len(X[0]) # Number of features
o = len(Y[0]) # Number of outputs / classes

layers = [f, 5, 10, o] # Number of nodes in layers
lr, epochs = 0.15, 100

weights = optimize(X_train, Y_train, X_val, Y_val, epochs=epochs, nodes=layers, lr=lr);
print("Testing Accuracy: {}".format(acc(X_test, Y_test, weights)))
但它给出的结果精度为
0
s:

Epoch 20
Training accuracy:0.0
Validation Accuracy:0.0
Epoch 40
Training accuracy:0.0
Validation Accuracy:0.0
Epoch 60
Training accuracy:0.0
Validation Accuracy:0.0
Epoch 80
Training accuracy:0.0
Validation Accuracy:0.0
Epoch 100
Training accuracy:0.0
Validation Accuracy:0.0
Testing Accuracy: 0.0
但是,如果我使用从下载的csv格式的数据集

输出:

Epoch 20
Training accuracy:0.9385964912280702
Validation Accuracy:0.9230769230769231
Epoch 40
Training accuracy:0.9912280701754386
Validation Accuracy:0.9230769230769231
Epoch 60
Training accuracy:0.9736842105263158
Validation Accuracy:0.9230769230769231
Epoch 80
Training accuracy:0.9736842105263158
Validation Accuracy:0.9230769230769231
Epoch 100
Training accuracy:0.9824561403508771
Validation Accuracy:0.9230769230769231
Testing Accuracy: 0.9565217391304348

为什么会有这种差异?

您使用自己的自定义函数进行训练/测试拆分和数据洗牌,从而使已经很大的代码不必要地变大(并修剪到bug)?我只需要使用scipy和numpy库。是的,但出于调试目的,不应该有用(首先,对您自己)尝试sklearn的可用功能?这是否有助于隔离问题?是的,我尝试过,在问题的最后部分使用
X\u-train,X\u-val,Y\u-train,Y\u-val
,效果很好。可能问题来自于
one\u hot\u编码器.fit\u变换(np.array(Y).restrape(-1,1))
,即
fit\u变换
,我需要从头开始编写。要查看问题是什么,请在检查
acc()
函数中的值是否相等之前,打印
Y
guess
的值。
Epoch 20
Training accuracy:0.9385964912280702
Validation Accuracy:0.9230769230769231
Epoch 40
Training accuracy:0.9912280701754386
Validation Accuracy:0.9230769230769231
Epoch 60
Training accuracy:0.9736842105263158
Validation Accuracy:0.9230769230769231
Epoch 80
Training accuracy:0.9736842105263158
Validation Accuracy:0.9230769230769231
Epoch 100
Training accuracy:0.9824561403508771
Validation Accuracy:0.9230769230769231
Testing Accuracy: 0.9565217391304348