云计算百科
云计算领域专业知识百科平台

【零基础学智能仿真-14】神经网络基础——从集成学习走向深度学习

课程摘要

上一节通过Stacking组合多个机器学习模型,本节进一步学习能够自动构造非线性特征的神经网络。课程以悬臂梁最大弯曲应力预测为案例,讲解神经元、权重、偏置、激活函数、网络层、前向传播、损失函数和反向传播,并完成数据标准化、MLP训练、验证集早停和独立测试。学习者将理解神经网络“如何预测、怎样学习、如何判断可靠”,为后续CNN、LSTM、Transformer和PINN课程建立基础。


一、承接第十三节:为什么继续学习神经网络?

第十三节使用Ridge、随机森林、梯度提升和RBF-SVR构建了Stacking模型,其基本思想是:

\\[ \\text{多个基模型的预测} \\longrightarrow \\text{元学习器} \\longrightarrow \\text{最终预测} \\]

Stacking的优势是综合已有模型,但每个基模型仍需人工选择。面对应力场、位移场、裂纹图像和瞬态响应等高维问题,传统模型会遇到三个困难:

  • 输入可能包含成千上万个网格节点或像素;
  • 几何、载荷和材料之间存在复杂非线性耦合;
  • 很难完全依靠人工设计特征。
  • 神经网络可以在训练过程中自动构造中间特征:

    \\[ \\text{原始输入} \\longrightarrow \\text{多层特征变换} \\longrightarrow \\text{力学响应} \\]

    本节先从最基本的多层感知机开始。后续的CNN、LSTM、Transformer和PINN,本质上都建立在神经元、激活函数、前向传播与反向传播之上。


    二、本节学习目标

    完成本节后,学习者应能够:

    • 解释神经元中权重和偏置的作用;
    • 理解激活函数为什么能够引入非线性;
    • 区分输入层、隐藏层和输出层;
    • 说清楚前向传播、损失计算和反向传播的关系;
    • 使用MLP预测悬臂梁最大弯曲应力;
    • 正确划分训练集、验证集和测试集;
    • 查看训练曲线、预测散点图和残差图;
    • 认识神经网络在力学预测中的能力边界。

    三、从一个神经元开始

    3.1 神经元的计算过程

    设神经元接收四个标准化后的力学参数:

    \\[ \\tilde{\\boldsymbol{x}} = \\begin{bmatrix} \\tilde{F}\\\\ \\tilde{L}\\\\ \\tilde{b}\\\\ \\tilde{h} \\end{bmatrix} \\]

    其中:

    • \\(F\\):载荷;
    • \\(L\\):梁长;
    • \\(b\\):截面宽度;
    • \\(h\\):截面高度。

    神经元首先进行加权求和:

    \\[ z= w_1\\tilde{F} +w_2\\tilde{L} +w_3\\tilde{b} +w_4\\tilde{h} +c \\]

    式中:

    • \\(w_1,w_2,w_3,w_4\\) 为权重;
    • \\(c\\) 为偏置;
    • \\(z\\) 为神经元的线性输入。

    这里用 \\(c\\) 表示偏置,避免与截面宽度 \\(b\\) 混淆。

    随后,神经元通过激活函数得到输出:

    \\[ a=\\phi(z) \\]

    因此,一个神经元包含两个步骤:

    \\[ \\boxed{ \\text{加权求和} \\longrightarrow \\text{激活函数} } \\]


    3.2 一个可以手算的例子

    假设输入为:

    \\[ \\tilde{\\boldsymbol{x}} = \\begin{bmatrix} 1&0&-1&0.5 \\end{bmatrix}^{\\mathrm T} \\]

    权重和偏置为:

    \\[ \\boldsymbol{w} = \\begin{bmatrix} 0.4&0.2&-0.3&-0.6 \\end{bmatrix}^{\\mathrm T} \\]\\[ c=0.1 \\]

    则加权求和结果为:

    \\[ \\begin{aligned} z &=0.4\\times1 +0.2\\times0 +(-0.3)\\times(-1)\\\\ &\\quad+(-0.6)\\times0.5 +0.1\\\\ &=0.5 \\end{aligned} \\]

    如果使用Tanh激活函数:

    \\[ a=\\tanh(0.5)\\approx0.4621 \\]

    这里的 \\(0.4621\\) 是神经元产生的中间特征值,不直接代表应力或位移。


    四、为什么必须使用激活函数?

    假设一个两层网络没有激活函数:

    \\[ \\boldsymbol{a}^{(1)} = \\boldsymbol{W}^{(1)}\\boldsymbol{x} +\\boldsymbol{c}^{(1)} \\]\\[ \\hat{\\boldsymbol{y}} = \\boldsymbol{W}^{(2)}\\boldsymbol{a}^{(1)} +\\boldsymbol{c}^{(2)} \\]

    将第一式代入第二式:

    \\[ \\hat{\\boldsymbol{y}} = \\boldsymbol{W}^{(2)} \\boldsymbol{W}^{(1)} \\boldsymbol{x} + \\boldsymbol{W}^{(2)} \\boldsymbol{c}^{(1)} + \\boldsymbol{c}^{(2)} \\]

    无论叠加多少层,最终仍然是关于输入的线性函数。

    激活函数可以打破这种线性关系,使网络能够学习:

    • 应力与梁高之间的平方反比关系;
    • 材料进入塑性后的非线性响应;
    • 裂纹扩展的突变趋势;
    • 接触状态改变产生的分段响应;
    • 多种材料参数和边界条件的耦合关系。

    五、常用激活函数

    5.1 ReLU函数

    \\[ \\operatorname{ReLU}(z)=\\max(0,z) \\]

    当 \\(z<0\\) 时:

    \\[ \\operatorname{ReLU}(z)=0 \\]

    当 \\(z\\geq0\\) 时:

    \\[ \\operatorname{ReLU}(z)=z \\]

    ReLU计算简单,在深层网络和CNN中使用非常广泛。


    5.2 Tanh函数

    \\[ \\tanh(z) = \\frac{e^z-e^{-z}}{e^z+e^{-z}} \\]

    输出范围为:

    \\[ -1<\\tanh(z)<1 \\]

    Tanh连续、平滑,在某些平滑力学响应和物理信息神经网络中较常见。

    【正文插图1:ReLU与Tanh激活函数】

    需要注意,隐藏层使用Tanh,并不意味着最终预测应力只能在 \\(-1\\) 到 \\(1\\) MPa之间。回归网络的输出层通常使用线性函数,标准化后的结果还会被恢复为原来的应力单位。


    六、从神经元组成多层感知机

    多个神经元可以组成一层,多层神经元连接后形成多层感知机,即MLP。

    本节采用的网络结构为:

    \\[ 4 \\longrightarrow 32 \\longrightarrow 32 \\longrightarrow 1 \\]

    它表示:

    网络层神经元数量作用
    输入层 4 接收 \\(F,L,b,h\\)
    第一隐藏层 32 提取初级非线性特征
    第二隐藏层 32 组合更复杂的特征
    输出层 1 预测最大弯曲应力

    需要强调的是,普通神经网络的隐藏神经元通常没有明确的物理名称。不能直接断言某个神经元代表弯矩,另一个神经元代表惯性矩。


    6.1 网络参数量

    输入层到第一隐藏层:

    \\[ 4\\times32+32=160 \\]

    第一隐藏层到第二隐藏层:

    \\[ 32\\times32+32=1056 \\]

    第二隐藏层到输出层:

    \\[ 32\\times1+1=33 \\]

    总参数量为:

    \\[ 160+1056+33=1249 \\]

    也就是说,这个看起来并不大的网络,已经包含1249个需要从数据中学习的参数。


    七、神经网络如何完成预测?

    对于一个样本,第一隐藏层计算:

    \\[ \\boldsymbol{a}^{(1)} = \\tanh \\left( \\boldsymbol{W}^{(1)} \\tilde{\\boldsymbol{x}} + \\boldsymbol{c}^{(1)} \\right) \\]

    第二隐藏层计算:

    \\[ \\boldsymbol{a}^{(2)} = \\tanh \\left( \\boldsymbol{W}^{(2)} \\boldsymbol{a}^{(1)} + \\boldsymbol{c}^{(2)} \\right) \\]

    输出层计算:

    \\[ \\hat{\\tilde{\\sigma}} = \\boldsymbol{W}^{(3)} \\boldsymbol{a}^{(2)} +c^{(3)} \\]

    这一过程称为前向传播:

    \\[ \\boxed{ \\text{输入} \\longrightarrow \\text{隐藏层1} \\longrightarrow \\text{隐藏层2} \\longrightarrow \\text{预测结果} } \\]

    前向传播只负责使用当前参数完成预测,还没有修改网络参数。


    八、神经网络如何学习?

    8.1 计算损失

    对于回归问题,可以使用均方误差:

    \\[ \\mathcal{L}_{\\mathrm{data}} = \\frac{1}{N} \\sum_{i=1}^{N} \\left( \\hat{\\tilde{\\sigma}}_i – \\tilde{\\sigma}_i \\right)^2 \\]

    损失越小,说明预测值整体越接近目标值。

    为了抑制过大的权重,还可以加入L2正则化:

    \\[ \\mathcal{L} = \\mathcal{L}_{\\mathrm{data}} + \\alpha \\sum_l \\left\\| \\boldsymbol{W}^{(l)} \\right\\|_2^2 \\]

    其中 \\(\\alpha\\) 控制正则化强度。


    8.2 反向传播

    反向传播利用链式法则计算:

    \\[ \\frac{\\partial\\mathcal{L}} {\\partial\\boldsymbol{W}^{(l)}} \\]

    以及:

    \\[ \\frac{\\partial\\mathcal{L}} {\\partial\\boldsymbol{c}^{(l)}} \\]

    它回答的问题是:

    某个权重发生微小变化时,预测误差将怎样变化?


    8.3 参数更新

    得到梯度后,优化器更新参数:

    \\[ \\boldsymbol{W}_{t+1} = \\boldsymbol{W}_t – \\eta \\frac{\\partial\\mathcal{L}} {\\partial\\boldsymbol{W}_t} \\]

    其中 \\(\\eta\\) 是学习率。

    完整训练循环为:

    \\[ \\boxed{ \\text{前向预测} \\rightarrow \\text{计算损失} \\rightarrow \\text{反向传播} \\rightarrow \\text{更新参数} } \\]

    反向传播负责计算梯度,Adam等优化器负责根据梯度更新参数,两者不是同一个概念。


    九、实战项目:悬臂梁最大应力预测

    9.1 力学模型

    矩形截面悬臂梁自由端承受集中载荷 \\(F\\)。

    固定端弯矩为:

    \\[ M=FL \\]

    截面惯性矩为:

    \\[ I=\\frac{bh^3}{12} \\]

    截面最外缘距离中性轴:

    \\[ c=\\frac{h}{2} \\]

    最大弯曲正应力为:

    \\[ \\sigma_{\\max} = \\frac{Mc}{I} = \\frac{6FL}{bh^2} \\]

    当载荷使用N、尺寸使用mm时:

    \\[ 1\\ \\mathrm{N/mm^2}=1\\ \\mathrm{MPa} \\]


    9.2 数据范围

    生成1000组教学数据:

    参数范围
    载荷 \\(F\\) 10~50 N
    梁长 \\(L\\) 300~600 mm
    梁宽 \\(b\\) 15~30 mm
    梁高 \\(h\\) 10~20 mm

    目标数据为:

    \\[ \\sigma_{\\mathrm{target}} = \\frac{6FL}{bh^2} +\\varepsilon \\]

    其中:

    \\[ \\varepsilon \\sim \\mathcal{N}(0,0.40^2) \\]

    这里加入小幅可重复扰动,用于模拟含噪声数据的训练过程。本节数据来自解析公式,并非真实有限元计算结果。


    十、准备数据

    from copy import deepcopy

    import numpy as np
    import pandas as pd

    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.neural_network import MLPRegressor
    from sklearn.linear_model import Ridge
    from sklearn.metrics import (
    mean_squared_error,
    mean_absolute_error,
    r2_score
    )

    def rmse(y_true, y_pred):
    return float(
    np.sqrt(mean_squared_error(y_true, y_pred))
    )

    rng = np.random.default_rng(42)
    n_samples = 1000

    F = rng.uniform(10.0, 50.0, n_samples)
    L = rng.uniform(300.0, 600.0, n_samples)
    b = rng.uniform(15.0, 30.0, n_samples)
    h = rng.uniform(10.0, 20.0, n_samples)

    sigma_theory = 6.0 * F * L / (b * h**2)

    sigma_target = (
    sigma_theory
    + rng.normal(0.0, 0.40, n_samples)
    )

    features = [
    "load_N",
    "length_mm",
    "width_mm",
    "height_mm"
    ]

    X = pd.DataFrame({
    "load_N": F,
    "length_mm": L,
    "width_mm": b,
    "height_mm": h
    })


    十一、划分训练集、验证集和测试集

    X_dev, X_test, y_dev, y_test = train_test_split(
    X,
    sigma_target,
    test_size=0.20,
    random_state=42
    )

    X_train, X_val, y_train, y_val = train_test_split(
    X_dev,
    y_dev,
    test_size=0.20,
    random_state=42
    )

    print("训练集:", len(X_train))
    print("验证集:", len(X_val))
    print("测试集:", len(X_test))

    实际输出:

    训练集: 640
    验证集: 160
    测试集: 200

    三类数据的职责不同:

    • 训练集用于更新网络参数;
    • 验证集用于选择最佳训练轮次;
    • 测试集只用于最终评价。

    测试集不能参与标准化器拟合、训练轮数选择和模型参数调整。


    十二、为什么神经网络需要标准化?

    四个输入特征的数值尺度明显不同:

    \\[ F\\approx10\\sim50 \\]\\[ L\\approx300\\sim600 \\]\\[ h\\approx10\\sim20 \\]

    如果直接输入网络,梁长的数值可能在梯度计算中占据过大影响。

    标准化公式为:

    \\[ \\tilde{x}_j = \\frac{x_j-\\mu_{j,\\mathrm{train}}} {s_{j,\\mathrm{train}}} \\]

    代码如下:

    input_scaler = StandardScaler()
    target_scaler = StandardScaler()

    X_train_scaled = input_scaler.fit_transform(X_train)
    X_val_scaled = input_scaler.transform(X_val)
    X_test_scaled = input_scaler.transform(X_test)

    y_train_scaled = target_scaler.fit_transform(
    y_train.reshape(-1, 1)
    ).ravel()

    print(X_train_scaled.shape)
    print(y_train_scaled.shape)

    实际输出:

    (640, 4)
    (640,)

    标准化器只能在训练集上调用fit。验证集、测试集和后续新工况只能调用transform。


    十三、建立MLP网络

    model = MLPRegressor(
    hidden_layer_sizes=(32, 32),
    activation="tanh",
    solver="adam",
    learning_rate_init=0.001,
    alpha=0.0001,
    batch_size=64,
    random_state=42,
    early_stopping=False
    )

    主要参数含义:

    参数本节设置作用
    hidden_layer_sizes (32, 32) 两个隐藏层,每层32个神经元
    activation tanh 隐藏层激活函数
    solver adam 参数优化方法
    learning_rate_init 0.001 初始学习率
    alpha 0.0001 L2正则化强度
    batch_size 64 每批训练样本数
    random_state 42 保证结果可重复

    定义预测函数,将标准化结果恢复为MPa:

    def predict_mpa(network, X_scaled):
    pred_scaled = network.predict(X_scaled)

    return target_scaler.inverse_transform(
    pred_scaled.reshape(-1, 1)
    ).ravel()


    十四、逐轮训练并保存最佳模型

    history = []

    best_val_rmse = np.inf
    best_epoch = 0
    best_model = None

    max_epochs = 1500
    patience = 120

    for epoch in range(1, max_epochs + 1):
    model.partial_fit(
    X_train_scaled,
    y_train_scaled
    )

    train_pred = predict_mpa(
    model,
    X_train_scaled
    )

    val_pred = predict_mpa(
    model,
    X_val_scaled
    )

    train_error = rmse(
    y_train,
    train_pred
    )

    val_error = rmse(
    y_val,
    val_pred
    )

    history.append([
    epoch,
    train_error,
    val_error
    ])

    if val_error < best_val_rmse:
    best_val_rmse = val_error
    best_epoch = epoch
    best_model = deepcopy(model)

    if epoch – best_epoch >= patience:
    break

    model = best_model

    print("实际训练轮数:", len(history))
    print("最佳模型轮数:", best_epoch)
    print(
    f"最佳验证RMSE:"
    f"{best_val_rmse:.6f} MPa"
    )

    实际运行输出:

    实际训练轮数: 1374
    最佳模型轮数: 1254
    最佳验证RMSE:0.427851 MPa

    deepcopy用于保存当时的模型参数副本。如果只写:

    best_model = model

    两个变量会指向同一个持续更新的对象,无法真正保留最佳轮次。


    十五、分析训练曲线

    import matplotlib.pyplot as plt

    plt.rcParams["font.sans-serif"] = [
    "Microsoft YaHei",
    "SimHei",
    "DejaVu Sans"
    ]
    plt.rcParams["axes.unicode_minus"] = False

    history_array = np.asarray(history)

    plt.figure(figsize=(9, 4.5))

    plt.plot(
    history_array[:, 0],
    history_array[:, 1],
    label="训练集"
    )

    plt.plot(
    history_array[:, 0],
    history_array[:, 2],
    label="验证集"
    )

    plt.axvline(
    best_epoch,
    linestyle="–",
    color="gray",
    label=f"保留第{best_epoch}轮"
    )

    plt.yscale("log")
    plt.xlabel("训练轮数 Epoch")
    plt.ylabel("RMSE(MPa,对数刻度)")
    plt.legend()
    plt.grid(alpha=0.2)
    plt.tight_layout()
    plt.show()

    【正文插图2:神经网络训练曲线】

    从曲线可以看到:

  • 训练初期,误差迅速下降;
  • 约200轮后,网络已经学到主要非线性趋势;
  • 后期误差仍在缓慢下降;
  • 第1254轮取得最低验证误差;
  • 此后连续120轮没有刷新最佳值,训练停止。
  • 本例后期验证曲线基本趋于平稳,并未出现明显的大幅上升。因此,更准确的判断是模型已经接近收敛,而不是严重过拟合。


    十六、独立测试与线性基线比较

    为了判断神经网络是否真正学到了非线性关系,使用相同训练数据建立Ridge基线。

    mlp_pred = predict_mpa(
    model,
    X_test_scaled
    )

    ridge = Ridge(alpha=1.0)
    ridge.fit(
    X_train_scaled,
    y_train
    )

    ridge_pred = ridge.predict(
    X_test_scaled
    )

    print(
    f"Ridge测试RMSE:"
    f"{rmse(y_test, ridge_pred):.6f} MPa"
    )

    print(
    f"MLP测试RMSE:"
    f"{rmse(y_test, mlp_pred):.6f} MPa"
    )

    print(
    f"MLP测试MAE:"
    f"{mean_absolute_error(y_test, mlp_pred):.6f} MPa"
    )

    print(
    f"MLP测试R²:"
    f"{r2_score(y_test, mlp_pred):.6f}"
    )

    实际运行输出:

    Ridge测试RMSE:4.696376 MPa
    MLP测试RMSE:0.470548 MPa
    MLP测试MAE:0.367447 MPa
    MLP测试R²:0.998709

    结果说明,在只输入 \\(F,L,b,h\\) 四个原始特征的条件下,MLP比线性模型更好地学习了:

    \\[ \\sigma_{\\max} = \\frac{6FL}{bh^2} \\]

    中的乘法、除法和平方关系。

    这个实验不表示神经网络比解析公式更合适。已知准确公式时,直接计算更快速、更透明。本例使用解析问题,是为了核验神经网络是否学到了正确的输入输出关系。


    十七、查看预测结果与残差

    【正文插图3:测试集预测和残差】

    左图中,散点整体接近理想预测线:

    \\[ \\hat{\\sigma}=\\sigma \\]

    右图展示残差:

    \\[ e_i= \\hat{\\sigma}_i-\\sigma_i \\]

    残差图可以帮助发现:

    • 模型是否整体偏高或偏低;
    • 高应力区域是否误差更大;
    • 是否存在少量异常工况;
    • 误差是否随目标值发生系统变化。

    虽然测试集 \\(R^2\\) 达到0.9987,但高应力区域仍出现较大的个别残差。因此,不能只看一个综合指标。

    对于工程应用,还应检查:

    \\[ e_{\\max} = \\max_i \\left| \\hat{\\sigma}_i-\\sigma_i \\right| \\]

    以及相对误差:

    \\[ e_{\\mathrm{relative},i} = \\frac{ \\left| \\hat{\\sigma}_i-\\sigma_i \\right| }{ \\left| \\sigma_i \\right|+\\epsilon } \\times100\\% \\]


    十八、预测一个新工况

    设新工况为:

    \\[ F=30\\ \\mathrm{N} \\]\\[ L=450\\ \\mathrm{mm} \\]\\[ b=22\\ \\mathrm{mm} \\]\\[ h=15\\ \\mathrm{mm} \\]

    理论应力为:

    \\[ \\begin{aligned} \\sigma_{\\max} &= \\frac{6\\times30\\times450} {22\\times15^2}\\\\ &= 16.363636\\ \\mathrm{MPa} \\end{aligned} \\]

    网络预测代码:

    new_case = pd.DataFrame(
    [[30.0, 450.0, 22.0, 15.0]],
    columns=features
    )

    new_case_scaled = input_scaler.transform(
    new_case
    )

    new_prediction = predict_mpa(
    model,
    new_case_scaled
    )[0]

    theory_value = (
    6.0 * 30.0 * 450.0
    / (22.0 * 15.0**2)
    )

    print(
    f"理论应力:"
    f"{theory_value:.6f} MPa"
    )

    print(
    f"网络预测:"
    f"{new_prediction:.6f} MPa"
    )

    print(
    f"绝对误差:"
    f"{abs(new_prediction-theory_value):.6f} MPa"
    )

    实际运行输出:

    理论应力:16.363636 MPa
    网络预测:16.391931 MPa
    绝对误差:0.028295 MPa

    新工况位于训练参数范围之内,因此属于插值预测。若输入:

    \\[ F=100\\ \\mathrm{N} \\]

    或者:

    \\[ h=5\\ \\mathrm{mm} \\]

    就可能进入训练范围之外。此时即使程序能够给出数值,也不能直接认为预测可靠。


    十九、与第十三节结果应该怎样比较?

    第十三节中,RBF-SVR和Stacking也取得了很高精度;本节MLP的测试RMSE为:

    \\[ 0.470548\\ \\mathrm{MPa} \\]

    它与上一节的优秀模型处于接近水平。不过两节的训练方案存在差异:

    • 第十三节使用800条开发数据进行基模型拟合;
    • 第十四节从开发集中划出160条验证数据;
    • 本节只有640条样本直接参与网络参数更新;
    • 模型选择和训练过程也不完全相同。

    因此,这些结果适合帮助理解算法特点,不应作为严格的排行榜。

    若要正式比较,应使用相同的数据划分、相同的评价流程和重复交叉验证。


    二十、如何迁移到真实有限元项目?

    真实项目可以将输入扩展为:

    \\[ \\boldsymbol{x} = \\begin{bmatrix} \\text{几何参数}\\\\ \\text{材料参数}\\\\ \\text{载荷参数}\\\\ \\text{边界条件编码}\\\\ \\text{网格参数} \\end{bmatrix} \\]

    输出可以是:

    \\[ \\boldsymbol{y} = \\begin{bmatrix} U_{\\max}\\\\ \\sigma_{\\mathrm{Mises,max}}\\\\ J\\\\ K_I\\\\ N_f \\end{bmatrix} \\]

    一个实际工作流可以写成:

    Abaqus参数化建模

    多工况批量计算

    ODB结果提取

    工况级数据划分

    输入与目标标准化

    神经网络训练

    验证集选择模型

    独立工况测试

    物理合理性检查

    这里有三个必须保持的习惯。

    第一,模型与标准化器应同时保存。只有网络参数而没有训练时的均值、标准差和特征顺序,模型不能可靠部署。

    第二,输出量的定义必须统一。例如“固定位置的名义应力”和“全模型最大积分点应力”不是同一个目标。

    第三,普通MLP只从数据误差中学习。本节损失函数没有加入平衡方程、本构方程或边界条件,因此它属于数据驱动网络,不属于PINN。


    二十一、常见问题

    1. 隐藏层越多越好吗?

    不一定。网络加深会增加参数量和训练难度。对于本节这种四输入、单输出的小问题,两层隐藏层已经具有足够的表达能力。

    2. 神经元越多越准确吗?

    不一定。神经元过少可能欠拟合,过多则可能增加过拟合风险和计算成本,应根据验证集结果选择。

    3. 损失下降就表示模型可靠了吗?

    只能说明优化过程取得进展。最终还需要独立测试、残差分析、物理趋势检查和适用范围检查。

    4. 为什么同一代码可能得到略有不同的结果?

    网络权重初始化和批次训练包含随机过程。固定random_state可以提高可重复性,但不同软件版本或计算环境仍可能导致最后几位存在差异。

    5. 神经网络会自动学会力学定律吗?

    不保证。它可能在训练范围内很好地拟合数据,却在外推区域违反单调性、对称性、平衡关系或边界条件。


    二十二、课后练习

    练习一:改变网络规模

    将:

    hidden_layer_sizes=(32, 32)

    改为:

    hidden_layer_sizes=(16, 16)

    计算新网络的参数量,并比较验证集与测试集误差。

    其参数量应为:

    \\[ 4\\times16+16 + 16\\times16+16 + 16\\times1+1 = 369 \\]


    练习二:比较激活函数

    分别设置:

    activation="tanh"

    和:

    activation="relu"

    比较:

    • 最佳验证RMSE;
    • 达到最佳结果所需的训练轮数;
    • 高应力区域的最大残差。

    练习三:加入物理特征

    构造新特征:

    \\[ q=\\frac{FL}{bh^2} \\]

    根据力学公式:

    \\[ \\sigma_{\\max}=6q \\]

    使用单变量线性回归预测应力,并与MLP比较。

    这个练习可以说明:

    合理的物理特征能够显著降低模型学习难度。


    练习四:检查物理单调性

    固定 \\(F,L,b\\),让梁高 \\(h\\) 从10 mm增加到20 mm,绘制网络预测曲线。

    理论上应满足:

    \\[ \\frac{\\partial\\sigma_{\\max}}{\\partial h} = -\\frac{12FL}{bh^3}<0 \\]

    也就是说,梁高增大时,应力应单调下降。检查神经网络是否遵守这一趋势。


    二十三、本节小结

    本节从第十三节的集成学习过渡到神经网络,建立了后续深度学习课程需要的基本概念:

    \\[ \\boxed{ \\text{神经元} = \\text{加权求和} + \\text{激活函数} } \\]\\[ \\boxed{ \\text{网络预测} = \\text{多层前向传播} } \\]\\[ \\boxed{ \\text{网络训练} = \\text{损失计算} + \\text{反向传播} + \\text{参数更新} } \\]

    神经网络能够学习复杂的力学映射,但模型的可靠性仍依赖于数据覆盖、验证方法、物理检查和适用范围。


    完整课程附件

    完整代码建议放在本节末尾的“附录:完整可运行代码”中。正文保留分段代码,便于学习者跟随讲解逐步运行。

    • [完整可运行代码]
    • [悬臂梁教学数据]
    • [逐轮训练记录]
    • [实际运行结果]
    • [模型与标准化器文件]

    附件地址:

    【零基础学智能仿真-14】神经网络基础-从集成学习走向深度学习资源-CSDN下载

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【零基础学智能仿真-14】神经网络基础——从集成学习走向深度学习
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!