目录

一、学习算法的整体步骤

1. Mini-batch选择

2. 梯度计算

3. 参数更新

4. 重复迭代

二、两层神经网络的类实现

1. 类的初始化

2. 类的核心方法

(1)前向传播预测

(2)损失函数计算

(3)识别精度计算

(4)数值梯度计算

三、Mini-batch训练的实现

1. 学习过程代码框架

四、基于测试数据的模型评价

1. 过拟合与泛化能力

2. Epoch概念与应用

3. 模型性能分析

总结


一、学习算法的整体步骤

        神经网络的学习过程可以概括为以下四个核心步骤:

1. Mini-batch选择

        从训练数据中随机选择小批量数据作为本次学习的样本。这种随机选择的方式使得每次学习都能接触到数据的不同部分,有助于避免陷入局部最优解。

2. 梯度计算

        计算损失函数关于各个权重参数的梯度。梯度指示了损失函数下降最快的方向,为参数更新提供指导。

3. 参数更新

        沿着梯度的反方向对权重参数进行微小调整,逐步减小损失函数的值。

4. 重复迭代

        不断重复上述三个步骤,直到模型性能达到满意程度或达到预设的迭代次数。

重要概念:随机梯度下降法(SGD)
        使用随机选择的小批量数据进行梯度下降法。

二、两层神经网络的类实现

AI学习日记——神经网络的训练算法实现_神经网络

AI学习日记——神经网络的训练算法实现_人工智能_02

1. 类的初始化

TwoLayerNet类封装了一个完整的两层神经网络:

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 初始化网络参数字典
        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)

参数说明:

  • input_size:输入层神经元数量(MNIST中为784)
  • hidden_size:隐藏层神经元数量
  • output_size:输出层神经元数量(MNIST中为10)
  • weight_init_std:权重初始化标准差

2. 类的核心方法

(1)前向传播预测

def predict(self, x):
    W1, W2 = self.params['W1'], self.params['W2']
    b1, b2 = self.params['b1'], self.params['b2']
    
    a1 = np.dot(x, W1) + b1              # 第一层加权和
    z1 = sigmoid(a1)                         # 第一层激活函数
    a2 = np.dot(z1, W2) + b2            # 第二层加权和
    y = softmax(a2)                           # 输出层softmax
    return y

(2)损失函数计算

def loss(x,t):

    y=self.predict(x)

    return cross_entropy_error(y,t)                #交叉熵误差

(3)识别精度计算

def accuracy(self, x, t):
    y = self.predict(x)
    y = np.argmax(y, axis=1)              # 获取预测标签
    t = np.argmax(t, axis=1)               # 获取真实标签
    accuracy = np.sum(y == t) / float(x.shape[0])                  # 计算准确率
    return accuracy

(4)数值梯度计算

def numerical_gradient_a(self, x, t):
    loss_W = lambda W: self.loss(x, t)          # 定义损失函数
    grads = {}
    # 计算各参数的梯度
    grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
    grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
    grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
    grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
    return grads

  后文会介绍误差反向传播法,替代这里的数值微分计算各参数的梯度。

三、Mini-batch训练的实现

1. 学习过程代码框架

# 超参数设置(人为设置的参数)
iters_num = 10000      # 迭代次数
batch_size = 100       # 批大小
learning_rate = 0.1    # 学习率

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)
train_loss_list = []   # 记录损失变化


for i in range(iters_num):
    # 随机选择mini-batch
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    # 计算梯度
    grad = network.numerical_gradient(x_batch, t_batch)
    
    # 更新参数
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] = network.params[key] - learning_rate * grad[key]     #梯度下降法
    
    # 记录损失
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)

学习过程监控:
        通过记录train_loss_list可以观察损失函数随迭代次数的变化趋势,这是判断学习是否正常进行的重要指标。

四、基于测试数据的模型评价

1. 过拟合与泛化能力

        核心问题:过拟合风险,要通过测试数据保证模型的泛化能力。

2. Epoch概念与应用

Epoch定义: 所有训练数据都被使用一次(?)所需的更新次数。

        请注意,假如mini-batch批大小为100,总共1000个样本,当进行10批训练后我们也认为是一个epoch。因为每个mini-batch都是随机选择的,所以不一定每个数据都会被看到。

计算方法:

iter_per_epoch = max(train_size / batch_size, 1)                #计算几批次为一epoch

周期性评价实现:

# 每经过一个epoch评价一次模型
if i % iter_per_epoch == 0:
    train_acc = network.accuracy(x_train, t_train)  # 训练集精度
    test_acc = network.accuracy(x_test, t_test)    # 测试集精度
    train_acc_list.append(train_acc)
    test_acc_list.append(test_acc)

3. 模型性能分析

        通过比较训练精度和测试精度的变化趋势,可以判断:

  • 正常学习: 两者同步提升且差距不大
  • 过拟合: 训练精度持续提升但测试精度停滞或下降
  • 欠拟合: 两者都提升缓慢

总结

        本文介绍了神经网络学习过程包括四个核心步骤:随机选择mini-batch、计算梯度、更新参数和重复迭代。通过实现TwoLayerNet类,封装了两层神经网络的功能,包括前向传播、损失计算和梯度计算。使用mini-batch训练时,通过监控损失函数和定期评估模型在测试集上的表现来检测过拟合。关键指标包括训练和测试精度,正常学习表现为两者同步提升,过拟合则表现为训练精度持续提高而测试精度停滞。