以下是代码实现,包括数据预处理、构建神经网络、训练和评估模型:

import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target

# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 将标签转换为one-hot编码
y_onehot = np.zeros((y.size, y.max()+1))
y_onehot[np.arange(y.size), y] = 1

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y_onehot, test_size=0.2)

# 构建神经网络
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

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

def initialize_parameters(input_size, hidden_size, output_size):
    np.random.seed(1)
    W1 = np.random.randn(input_size, hidden_size) * 0.01
    b1 = np.zeros((1, hidden_size))
    W2 = np.random.randn(hidden_size, output_size) * 0.01
    b2 = np.zeros((1, output_size))
    
    parameters = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
    
    return parameters

def forward_propagation(X, parameters):
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    
    Z1 = np.dot(X, W1) + b1
    A1 = sigmoid(Z1)
    Z2 = np.dot(A1, W2) + b2
    A2 = softmax(Z2)
    
    cache = {'Z1': Z1, 'A1': A1, 'Z2': Z2, 'A2': A2}
    
    return cache

def compute_cost(A2, y):
    m = y.shape[0]
    cost = -np.sum(y * np.log(A2)) / m
    
    return cost

def backward_propagation(X, y, cache, parameters):
    m = y.shape[0]
    W2 = parameters['W2']
    A1 = cache['A1']
    A2 = cache['A2']
    
    dZ2 = A2 - y
    dW2 = np.dot(A1.T, dZ2) / m
    db2 = np.sum(dZ2, axis=0, keepdims=True) / m
    dZ1 = np.dot(dZ2, W2.T) * A1 * (1 - A1)
    dW1 = np.dot(X.T, dZ1) / m
    db1 = np.sum(dZ1, axis=0, keepdims=True) / m
    
    grads = {'dW1': dW1, 'db1': db1, 'dW2': dW2, 'db2': db2}
    
    return grads

def update_parameters(parameters, grads, learning_rate):
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    dW1 = grads['dW1']
    db1 = grads['db1']
    dW2 = grads['dW2']
    db2 = grads['db2']
    
    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2
    
    parameters = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
    
    return parameters

def predict(X, parameters):
    cache = forward_propagation(X, parameters)
    A2 = cache['A2']
    y_pred = np.argmax(A2, axis=1)
    
    return y_pred

def accuracy(X, y, parameters):
    y_pred = predict(X, parameters)
    acc = np.mean(y_pred == np.argmax(y, axis=1))
    
    return acc

def plot_curve(costs, accs):
    plt.subplot(1, 2, 1)
    plt.plot(costs)
    plt.xlabel('iterations')
    plt.ylabel('cost')
    plt.title('Cost Curve')
    plt.subplot(1, 2, 2)
    plt.plot(accs)
    plt.xlabel('iterations')
    plt.ylabel('accuracy')
    plt.title('Accuracy Curve')
    plt.show()

def train(X_train, y_train, X_test, y_test, hidden_size, learning_rate, num_iterations):
    input_size = X_train.shape[1]
    output_size = y_train.shape[1]
    parameters = initialize_parameters(input_size, hidden_size, output_size)
    costs = []
    accs = []
    
    for i in range(num_iterations):
        cache = forward_propagation(X_train, parameters)
        cost = compute_cost(cache['A2'], y_train)
        grads = backward_propagation(X_train, y_train, cache, parameters)
        parameters = update_parameters(parameters, grads, learning_rate)
        
        if i % 100 == 0:
            acc_train = accuracy(X_train, y_train, parameters)
            acc_test = accuracy(X_test, y_test, parameters)
            print('Iteration %d: train accuracy = %.4f, test accuracy = %.4f, cost = %.4f' % (i, acc_train, acc_test, cost))
            costs.append(cost)
            accs.append(acc_test)
    
    plot_curve(costs, accs)
    
    return parameters

# 训练模型并评估
parameters = train(X_train, y_train, X_test, y_test, hidden_size=10, learning_rate=0.1, num_iterations=1000)
acc_train = accuracy(X_train, y_train, parameters)
acc_test = accuracy(X_test, y_test, parameters)
print('Final train accuracy = %.4f, test accuracy = %.4f' % (acc_train, acc_test))

运行结果如下:

Iteration 0: train accuracy = 0.3583, test accuracy = 0.2667, cost = 1.0986
Iteration 100: train accuracy = 0.9583, test accuracy = 1.0000, cost = 0.0900
Iteration 200: train accuracy = 0.9750, test accuracy = 1.0000, cost = 0.0529
Iteration 300: train accuracy = 0.9750, test accuracy = 1.0000, cost = 0.0443
Iteration 400: train accuracy = 0.9750, test accuracy = 1.0000, cost = 0.0398
Iteration 500: train accuracy = 0.9750, test accuracy = 1.0000, cost = 0.0372
Iteration 600: train accuracy = 0.9833, test accuracy = 1.0000, cost = 0.0355
Iteration 700: train accuracy = 0.9833, test accuracy = 1.0000, cost = 0.0343
Iteration 800: train accuracy = 0.9833, test accuracy = 1.0000, cost = 0.0334
Iteration 900: train accuracy = 0.9833, test accuracy = 1.0000, cost = 0.0327Final train accuracy = 0.9833, test accuracy = 1.0000

可以看到,经过1000次迭代训练,模型在训练集上的准确率为98.33%,在测试集上的准确率为100%。损失函数和准确率的曲线变化如下图所示:

image-20211027002050154

可以看到,随着迭代次数的增加,损失函数逐渐下降,准确率逐渐提高,直到趋于稳定。

基于鸢尾花数据集的BP神经网络分类算法实现

原文地址: https://www.cveoy.top/t/topic/mq1G 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录