目录

1. 神经元模型与激活函数

神经元模型

常见激活函数

2. 使用 Python 和 NumPy 搭建单隐层神经网络(二分类)

详细步骤

步骤 1:初始化参数

步骤 2:前向传播

步骤 3:计算损失

步骤 4:反向传播

步骤 5:迭代训练

代码实现

3. 场景示例


1. 神经元模型与激活函数

神经元模型

神经元是神经网络的基本计算单元,它接收多个输入信号,对这些信号进行加权求和,再加上一个偏置项,最后通过激活函数进行非线性变换得到输出。

假设一个神经元有n个输入x_1, x_2, \cdots, x_n​,对应的权重为 w_1, w_2, \cdots, w_n,偏置为b。则加权输入z 为:
z = \sum_{i = 1}^{n}w_ix_i + b=\mathbf{w}^T\mathbf{x}+b
其中 \mathbf{w}=[w_1, w_2, \cdots, w_n]^T\mathbf{x}=[x_1, x_2, \cdots, x_n]^T

经过激活函数\sigma处理后,输出y为:
y = \sigma(z)

常见激活函数
  • Sigmoid 函数\sigma(z)=\frac{1}{1 + e^{-z}},其值域为(0, 1),常用于二分类问题的输出层,可将输出解释为概率。
  • ReLU 函数\text{ReLU}(z)=\max(0, z),计算简单,能有效缓解梯度消失问题,常用于隐藏层。

2. 使用 Python 和 NumPy 搭建单隐层神经网络(二分类)

详细步骤
步骤 1:初始化参数

初始化权重和偏置,通常使用随机初始化的方法。

步骤 2:前向传播

计算输入数据在神经网络中的输出,包括隐藏层和输出层的计算。

步骤 3:计算损失

使用损失函数(如交叉熵损失)计算预测值与真实值之间的差异。

步骤 4:反向传播

根据损失函数的梯度,更新权重和偏置。

步骤 5:迭代训练

重复步骤 2 - 4,直到损失收敛或达到最大迭代次数。

代码实现
import numpy as np

# 定义 Sigmoid 激活函数及其导数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def sigmoid_derivative(z):
    return sigmoid(z) * (1 - sigmoid(z))

# 定义单隐层神经网络类
class SingleHiddenLayerNN:
    def __init__(self, input_size, hidden_size, output_size):
        # 初始化权重和偏置
        self.W1 = np.random.randn(input_size, hidden_size) * 0.01
        self.b1 = np.zeros((1, hidden_size))
        self.W2 = np.random.randn(hidden_size, output_size) * 0.01
        self.b2 = np.zeros((1, output_size))

    def forward_propagation(self, X):
        # 前向传播
        self.Z1 = np.dot(X, self.W1) + self.b1
        self.A1 = sigmoid(self.Z1)
        self.Z2 = np.dot(self.A1, self.W2) + self.b2
        self.A2 = sigmoid(self.Z2)
        return self.A2

    def compute_loss(self, Y):
        # 计算交叉熵损失
        m = Y.shape[0]
        loss = -np.sum(Y * np.log(self.A2) + (1 - Y) * np.log(1 - self.A2)) / m
        return loss

    def backward_propagation(self, X, Y):
        # 反向传播
        m = X.shape[0]

        dZ2 = self.A2 - Y
        dW2 = np.dot(self.A1.T, dZ2) / m
        db2 = np.sum(dZ2, axis=0, keepdims=True) / m

        dZ1 = np.dot(dZ2, self.W2.T) * sigmoid_derivative(self.Z1)
        dW1 = np.dot(X.T, dZ1) / m
        db1 = np.sum(dZ1, axis=0, keepdims=True) / m

        return dW1, db1, dW2, db2

    def update_parameters(self, dW1, db1, dW2, db2, learning_rate):
        # 更新参数
        self.W1 -= learning_rate * dW1
        self.b1 -= learning_rate * db1
        self.W2 -= learning_rate * dW2
        self.b2 -= learning_rate * db2

    def train(self, X, Y, learning_rate, num_iterations):
        # 训练模型
        for i in range(num_iterations):
            # 前向传播
            self.forward_propagation(X)
            # 计算损失
            loss = self.compute_loss(Y)
            # 反向传播
            dW1, db1, dW2, db2 = self.backward_propagation(X, Y)
            # 更新参数
            self.update_parameters(dW1, db1, dW2, db2, learning_rate)

            if i % 100 == 0:
                print(f"迭代次数 {i}, 损失: {loss}")

    def predict(self, X):
        # 预测
        A2 = self.forward_propagation(X)
        predictions = (A2 > 0.5).astype(int)
        return predictions


# 生成示例数据
np.random.seed(42)
X = np.random.randn(100, 2)
Y = (np.sum(X, axis=1) > 0).astype(int).reshape(-1, 1)

# 创建单隐层神经网络模型
input_size = 2
hidden_size = 4
output_size = 1
model = SingleHiddenLayerNN(input_size, hidden_size, output_size)

# 训练模型
learning_rate = 0.1
num_iterations = 1000
model.train(X, Y, learning_rate, num_iterations)

# 进行预测
predictions = model.predict(X)
accuracy = np.mean(predictions == Y)
print(f"训练集准确率: {accuracy}")

3. 场景示例

假设我们有一个简单的二分类问题,例如根据两个特征判断一个样本属于正类还是负类。上述代码中的示例数据是随机生成的,在实际应用中,可以使用真实的数据集,如乳腺癌数据集,根据患者的各项特征判断肿瘤是良性还是恶性。

通过上述代码,我们实现了一个单隐层神经网络,用于二分类任务。在训练过程中,不断更新权重和偏置,使得损失函数逐渐减小,最终得到一个能够对新样本进行分类的模型。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐