前馈神经网络详解

前馈神经网络(Feedforward Neural Network,FFNN)是一种最基本的神经网络模型,也被称为多层感知机(Multi-Layer Perceptron,MLP)。它由多个神经元组成,每个神经元接收来自上一层神经元的输出,并通过一定的权重和偏置进行加权和处理,最终得到本层神经元的输出,进而作为下一层神经元的输入。该网络的信息流是单向的,只能从输入层流向输出层,因此称为前馈神经网络。

前馈神经网络通常包括输入层、若干个隐藏层和输出层,其中输入层接收原始数据输入,隐藏层对输入进行一定的变换和特征提取,输出层根据隐藏层的结果输出模型预测值。每个层都由若干个神经元组成,神经元之间的连接带有权重,可以通过反向传播算法来学习优化。前馈神经网络是一种强大的模型,能够处理非线性分类和回归任务。

import numpy as np

class FeedForwardNN:
    def __init__(self, input_size, hidden_size, output_size):
        # 初始化神经网络的参数
        self.weights1 = np.random.randn(input_size, hidden_size)
        self.bias1 = np.zeros((1, hidden_size))
        self.weights2 = np.random.randn(hidden_size, output_size)
        self.bias2 = np.zeros((1, output_size))
    
    def forward(self, x):
        # 前向传播,计算输出值
        self.z1 = np.dot(x, self.weights1) + self.bias1
        self.a1 = np.tanh(self.z1)
        self.z2 = np.dot(self.a1, self.weights2) + self.bias2
        self.output = self.z2
    
    def backward(self, x, y):
        # 反向传播,计算参数的梯度
        m = x.shape[0]
        delta2 = self.output - y
        dweights2 = np.dot(self.a1.T, delta2) / m
        dbias2 = np.sum(delta2, axis=0, keepdims=True) / m
        delta1 = np.dot(delta2, self.weights2.T) * (1 - np.power(self.a1, 2))
        dweights1 = np.dot(x.T, delta1) / m
        dbias1 = np.sum(delta1, axis=0) / m
        
        # 更新参数
        self.weights1 -= 0.1 * dweights1
        self.bias1 -= 0.1 * dbias1
        self.weights2 -= 0.1 * dweights2
        self.bias2 -= 0.1 * dbias2
    
    def train(self, x, y, epochs):
        # 训练神经网络
        for i in range(epochs):
            self.forward(x)
            self.backward(x, y)
    
    def predict(self, x):
        self.forward(x)
        return self.output

在这个示例中,定义了一个名为FeedForwardNN的类,它有三个初始化参数:输入层神经元数量input_size,隐藏层神经元数量hidden_size,输出层神经元数量output_size。在初始化方法__init__中,根据这些参数随机初始化了权重和偏置。

该类有三个主要的方法:前向传播方法forward,反向传播方法backward和预测方法predict。在前向传播方法forward中,使用权重和偏置计算加权和,然后通过tanh函数计算激活值。在输出层,直接计算加权和和输出值。在反向传播方法backward中,首先计算误差,然后计算参数的梯度,并使用梯度下降法更新参数。在训练方法train中,进行前向传播和反向传播的交替训练。在预测方法predict中,使用训练好的模型进行预测,并返回预测值。

这个示例是一个简单的前馈神经网络,可以用来解决分类和回归问题。

一个前馈神经网络的具体实例是基于MNIST手写数字数据集的手写数字识别问题。该问题的目标是根据输入的手写数字图像,判断其代表的数字是什么。下面是一个简单的前馈神经网络的实现示例:

import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

# 加载MNIST手写数字数据集
mnist = fetch_openml('mnist_784')
X, y = mnist.data / 255., mnist.target.astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义前馈神经网络
class FeedForwardNN:
    def __init__(self, input_size, hidden_size, output_size):
        self.weights1 = np.random.randn(input_size, hidden_size) * 0.01
        self.bias1 = np.zeros((1, hidden_size))
        self.weights2 = np.random.randn(hidden_size, output_size) * 0.01
        self.bias2 = np.zeros((1, output_size))
        
    def forward(self, x):
        self.z1 = np.dot(x, self.weights1) + self.bias1
        self.a1 = np.tanh(self.z1)
        self.z2 = np.dot(self.a1, self.weights2) + self.bias2
        self.output = self.softmax(self.z2)
        
    def backward(self, x, y):
        m = x.shape[0]
        delta2 = self.output - y
        dweights2 = np.dot(self.a1.T, delta2) / m
        dbias2 = np.sum(delta2, axis=0, keepdims=True) / m
        delta1 = np.dot(delta2, self.weights2.T) * (1 - np.power(self.a1, 2))
        dweights1 = np.dot(x.T, delta1) / m
        dbias1 = np.sum(delta1, axis=0) / m
        
        self.weights1 -= 0.1 * dweights1
        self.bias1 -= 0.1 * dbias1
        self.weights2 -= 0.1 * dweights2
        self.bias2 -= 0.1 * dbias2
        
    def train(self, x, y, epochs):
        for i in range(epochs):
            self.forward(x)
            self.backward(x, y)
    
    def predict(self, x):
        self.forward(x)
        return np.argmax(self.output, axis=1)
    
    def softmax(self, z):
        e_z = np.exp(z - np.max(z, axis=1, keepdims=True))
        return e_z / np.sum(e_z, axis=1, keepdims=True)

# 初始化神经网络
input_size = X_train.shape[1]
hidden_size = 128
output_size = 10
nn = FeedForwardNN(input_size, hidden_size, output_size)

# 训练神经网络
nn.train(X_train, np.eye(output_size)[y_train], epochs=100)

# 测试神经网络
y_pred = nn.predict(X_test)
accuracy = np.mean(y_pred == y_test)
print("Accuracy: %.2f%%" % (accuracy * 100))

在上述代码中,我们首先加载了MNIST手写数字数据集,然后定义了一个名为FeedForwardNN的前馈神经网络类。在该类的初始化函数中,我们随机初始化了两个权重矩阵和两个偏置向量。其中,weights1和bias1是连接输入层和隐藏层的权重矩阵和偏置向量,weights2和bias2是连接隐藏层和输出层的权重矩阵和偏置向量。

在该类中,我们定义了三个主要的方法:forward、backward和train。在forward方法中,我们首先计算了隐藏层的加权输入z1,然后将其输入到tanh激活函数中,得到了隐藏层的激活输出a1。接下来,我们计算了输出层的加权输入z2,并将其输入到softmax函数中,得到了输出层的激活输出output。

在backward方法中,我们首先计算了输出误差delta2,然后使用delta2计算了连接隐藏层和输出层的权重矩阵weights2和偏置向量bias2的梯度。接着,我们使用delta2和weights2计算了连接输入层和隐藏层的权重矩阵weights1和偏置向量bias1的梯度。最后,我们使用梯度下降算法更新了四个参数。

在train方法中,我们使用前向传播和反向传播算法训练神经网络。在每个训练迭代中,我们使用当前的权重和偏置向量计算了网络的输出,并使用反向传播算法计算了参数的梯度。然后,我们使用梯度下降算法更新了参数。

在predict方法中,我们使用前向传播算法计算了网络的输出,并返回具有最大值的输出作为预测类别。

最后,我们使用训练后的神经网络进行预测,并计算了分类准确率。

以下是一个使用Python代码实现的前馈神经网络的具体实例,用于在二维空间中分类圆形和方形数据点。代码通过matplotlib库生成可视化结果,显示了训练后神经网络的分类决策边界。

import numpy as np
import matplotlib.pyplot as plt

# Generate random circular data
num_samples = 1000
theta = np.random.uniform(low=0.0, high=2*np.pi, size=num_samples)
r = np.random.uniform(low=0.0, high=1.0, size=num_samples)
x = r * np.cos(theta)
y = r * np.sin(theta)
circles = np.vstack((x, y)).T

# Generate random square data
num_samples = 1000
square_x = np.random.uniform(low=-1.0, high=1.0, size=num_samples)
square_y = np.random.uniform(low=-1.0, high=1.0, size=num_samples)
squares = np.vstack((square_x, square_y)).T

# Combine data and labels
X = np.vstack((circles, squares))
y = np.hstack((np.zeros(len(circles)), np.ones(len(squares))))

# Define the model
input_dim = 2
hidden_dim = 10
output_dim = 2

# Initialize the model parameters
W1 = np.random.randn(input_dim, hidden_dim)
b1 = np.zeros((1, hidden_dim))
W2 = np.random.randn(hidden_dim, output_dim)
b2 = np.zeros((1, output_dim))

# Define the forward propagation function
def forward_prop(model, X):
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    
    # Calculate the output of the hidden layer
    hidden_output = np.maximum(0, np.dot(X, W1) + b1)
    
    # Calculate the output of the output layer
    output = np.dot(hidden_output, W2) + b2
    
    # Return the model predictions
    return {'X': X, 'hidden_output': hidden_output, 'output': output}

# Define the predict function
def predict(model, X):
    forward_output = forward_prop(model, X)
    return np.argmax(forward_output['output'], axis=1)

# Define the calculate loss function
def calculate_loss(model, X, y):
    num_examples = X.shape[0]
    forward_output = forward_prop(model, X)
    exp_scores = np.exp(forward_output['output'])
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    loss = -np.sum(np.log(probs[range(num_examples), y]))
    return loss / num_examples

# Define the train function
def train(model, X, y, learning_rate, reg_lambda, num_epochs):
    np.random.seed(0)
    for i in range(num_epochs):
        # Forward propagation
        forward_output = forward_prop(model, X)
        X, hidden_output, output = forward_output['X'], forward_output['hidden_output'], forward_output['output']
        
        # Calculate the error at the output layer
        num_examples = X.shape[0]
        exp_scores = np.exp(output)
        probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
        delta3 = probs
        delta3[range(num_examples), y] -= 1
        
        # Backpropagation
            dW2 = np.dot(hidden_output.T, delta3)
    db2 = np.sum(delta3, axis=0, keepdims=True)
    delta2 = np.dot(delta3, W2.T) * (hidden_output > 0)
    dW1 = np.dot(X.T, delta2)
    db1 = np.sum(delta2, axis=0)
    
    # Regularization
    dW2 += reg_lambda * W2
    dW1 += reg_lambda * W1
    
    # Update the model parameters
    W1 += -learning_rate * dW1
    b1 += -learning_rate * db1
    W2 += -learning_rate * dW2
    b2 += -learning_rate * db2
    
    # Print the loss every 1000 epochs
    if i % 1000 == 0:
        loss = calculate_loss(model, X, y)
        print("Loss after epoch %i: %f" % (i, loss))

# Return the trained model
return {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}

#Train the model
model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
model = train(model, X, y, 0.01, 0.01, 10000)

#Visualize the classification boundary
h = 0.01
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = predict(model, np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(circles[:, 0], circles[:, 1], color='blue')
plt.scatter(squares[:, 0], squares[:, 1], color='red')
plt.show()


在这个例子中,我们使用numpy库生成了一些随机的圆形和方形数据点,并将它们组合成一个二维的特征矩阵X。我们定义了一个包含一个隐藏层的前馈神经网络,用于将输入数据点映射到输出类别标签。我们使用反向传播算法训练了这个神经网络,通过更新模型的参数来最小化损失函数。最后,我们使用matplotlib库可视化结果,显示了训练后神经网络的分类决策边界。
 

  • 5
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦_天明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值