——从有限元场中提取空间特征)
课程摘要本节承接神经网络基础学习卷积神经网络处理有限元场数据的基本方法。课程从局部感受野和权重共享出发讲解卷积核、通道、步长、填充、池化及残差连接并通过带圆孔板教学应力场演示CNN如何识别应力集中区域。学习者将掌握卷积输出尺寸和参数量的计算方法理解标量预测、全场预测与一维时序卷积的区别为后续CNN代理模型、LSTM和U-Net课程建立基础。一、承接第十四节为什么MLP不适合直接处理应力场第十四节使用多层感知机建立了映射\[ (F,L,b,h) \longrightarrow \sigma_{\max} \]它的输入只有四个参数使用MLP非常自然。如果现在要预测整个有限元应力场输出可能是\[ \boldsymbol{\sigma} \in \mathbb{R}^{64\times64} \]输入也可能包含几何、材料、载荷和边界条件组成的多通道场\[ \boldsymbol{X} \in \mathbb{R}^{C\times64\times64} \]一种直接方法是把二维场展开成一维向量\[ 64\times64 \longrightarrow 4096 \]然后送入全连接层。但这样会产生两个问题。第一展开操作削弱了空间邻接关系。模型不再直接知道两个数值来自相邻节点还是模型两端。第二参数量迅速增加。若将4096个输入连接到32个神经元需要\[ 4096\times3232 131104 \]个参数。CNN保留二维结构让同一个小卷积核在整个场上滑动从而识别局部模式。二、CNN观察有限元结果的方式工程师查看云图时通常会注意孔洞和缺口附近的应力集中裂纹尖端附近的高梯度区域载荷作用点附近的局部响应固定边界附近的约束效应场变量是否连续、对称或发生突变。CNN的思路与此类似使用较小的局部窗口观察场数据并在不同位置重复使用同一组权重。其核心可以概括为\[ \boxed{ \text{局部感受野} \text{权重共享} \text{分层特征提取} } \]三、卷积核如何工作3.1 二维卷积计算设输入场为 \(X\)卷积核为 \(K\)。输出特征图中第 \((i,j)\) 个位置为\[ Y_{i,j} \sum_{m0}^{k_h-1} \sum_{n0}^{k_w-1} K_{m,n} X_{im,jn} c \]其中\(k_h,k_w\) 为卷积核高度和宽度\(c\) 为偏置\(Y\) 为卷积得到的特征图。深度学习框架中的Conv2d通常执行互相关运算即不翻转卷积核但行业中仍习惯称其为卷积。3.2 一个可以手算的卷积示例输入场为\[ X \begin{bmatrix} 00000\\ 01110\\ 01310\\ 01110\\ 00000 \end{bmatrix} \]使用卷积核\[ K \begin{bmatrix} -1-1-1\\ -18-1\\ -1-1-1 \end{bmatrix} \]计算输出左上角时取输入左上方的 \(3\times3\) 窗口\[ X_{\mathrm{window}} \begin{bmatrix} 000\\ 011\\ 013 \end{bmatrix} \]逐元素相乘并求和\[ \begin{aligned} Y_{1,1} 0(-1)0(-1)0(-1)\\ \quad0(-1)1(8)1(-1)\\ \quad0(-1)1(-1)3(-1)\\ 3 \end{aligned} \]卷积核继续向右、向下滑动最终得到\[ Y \begin{bmatrix} 313\\ 1161\\ 313 \end{bmatrix} \]中心区域的输出值16明显较大说明该卷积核对局部突变较为敏感。【图1卷积核滑动与输出计算】四、使用NumPy实现二维卷积下面的代码不依赖PyTorch可直接运行并验证上述计算。import numpy as np from numpy.lib.stride_tricks import sliding_window_view def conv2d_single(field, kernel, padding0, stride1): if padding 0: field np.pad( field, padding, modeconstant ) windows sliding_window_view( field, kernel.shape )[::stride, ::stride] return np.einsum( ijkl,kl-ij, windows, kernel ) field np.array([ [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 3, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0] ], dtypefloat) kernel np.array([ [-1, -1, -1], [-1, 8, -1], [-1, -1, -1] ], dtypefloat) feature_map conv2d_single( field, kernel ) print(feature_map.astype(int)) print(输出形状, feature_map.shape)实际输出[[ 3 1 3] [ 1 16 1] [ 3 1 3]] 输出形状 (3, 3)五、卷积输出尺寸怎样计算设输入尺寸为 \(H\times W\)卷积核尺寸为 \(K_h\times K_w\)填充为 \(P\)步长为 \(S\)。忽略空洞卷积时输出高度为\[ H_{\mathrm{out}} \left\lfloor \frac{H2P-K_h}{S} \right\rfloor1 \]输出宽度为\[ W_{\mathrm{out}} \left\lfloor \frac{W2P-K_w}{S} \right\rfloor1 \]示例一不填充输入为 \(64\times64\)卷积核为 \(3\times3\)步长为1填充为0\[ H_{\mathrm{out}} \frac{64-3}{1}1 62 \]所以\[ 64\times64 \longrightarrow 62\times62 \]示例二保持尺寸不变设置\[ K3,\qquad P1,\qquad S1 \]则\[ H_{\mathrm{out}} \frac{642-3}{1}1 64 \]所以\[ 64\times64 \longrightarrow 64\times64 \]这种设置通常称为相同尺寸填充。示例三使用步长2降采样设置\[ K3,\qquad P1,\qquad S2 \]则\[ H_{\mathrm{out}} \left\lfloor \frac{642-3}{2} \right\rfloor1 32 \]所以\[ 64\times64 \longrightarrow 32\times32 \]六、步长、填充和边界效应6.1 步长Stride步长表示卷积核每次移动的距离。\(S1\)逐个位置扫描空间信息保留较多\(S2\)每次移动两个位置同时完成降采样步长越大输出尺寸通常越小。6.2 填充Padding填充是在输入边界外增加数值。零填充表示\[ X_{\mathrm{outside}}0 \]它可以保持输出尺寸但也可能在边界处产生人为的数值跳变。对于有限元问题零填充不一定具有正确物理意义。例如应力场边界外的零值并不代表真实材料或真实边界条件。因此边界附近的预测应单独检查。七、通道是什么普通灰度图像只有一个通道\[ X\in\mathbb{R}^{1\times H\times W} \]有限元代理模型可以把不同信息放入不同通道。例如通道可以表示的内容通道1几何区域掩码通道2材料弹性模量场通道3泊松比场通道4水平载荷场通道5竖直载荷场通道6水平位移约束通道7竖直位移约束于是输入可以写成\[ X\in\mathbb{R}^{7\times64\times64} \]输出同样可以有多个通道\[ Y \begin{bmatrix} U_1\\ U_2\\ S_{11}\\ S_{22}\\ S_{12}\\ S_{\mathrm{Mises}} \end{bmatrix} \]在PyTorch中二维场张量通常采用\[ (N,C,H,W) \]其中\(N\)批量中的样本数量\(C\)通道数量\(H\)场的高度\(W\)场的宽度。八、权重共享为什么能减少参数假设输入为单通道 \(64\times64\) 场需要得到32个输出特征。如果使用全连接层\[ 4096\longrightarrow32 \]参数量为\[ 4096\times3232 131104 \]如果使用32个 \(3\times3\) 卷积核参数量为\[ 3\times3\times1\times3232 320 \]参数量缩小倍数为\[ \frac{131104}{320} 409.7 \]【图2全连接层与卷积层参数量比较】卷积核在所有空间位置共享同一组参数所以参数数量与输入场的宽度、高度没有直接关系。需要区分“参数少”和“计算量小”。卷积核仍需在大量位置执行运算因此参数减少不代表计算量一定同比例下降。九、池化层压缩空间信息9.1 最大池化对于一个 \(2\times2\) 区域\[ \begin{bmatrix} 1.22.5\\ 1.81.4 \end{bmatrix} \]最大池化输出为\[ \max(1.2,2.5,1.8,1.4)2.5 \]最大池化倾向于保留局部最显著响应因此适合提取应力集中裂纹尖端高响应局部缺陷特征场变量突变区域。9.2 平均池化同一区域的平均池化为\[ \frac{1.22.51.81.4}{4} 1.725 \]平均池化更强调区域整体水平。对于高应力集中问题最大池化可能更容易保留峰值但它不能替代严格的峰值误差评价。9.3 NumPy池化代码def max_pool2d(field, pool_size2, stride2): windows sliding_window_view( field, (pool_size, pool_size) )[::stride, ::stride] return windows.max(axis(-2, -1)) field np.arange(64 * 64).reshape(64, 64) pooled max_pool2d( field, pool_size2, stride2 ) print(输入形状, field.shape) print(池化后形状, pooled.shape)实际输出输入形状 (64, 64) 池化后形状 (32, 32)十、有限元场特征提取示例下面构造一个带圆孔板的教学场用来演示局部应力集中。需要明确该场是根据解析形式人为构造的可视化数据不是有限元求解结果也不能替代Kirsch解或Abaqus计算。输入场尺寸为\[ 64\times64 \]使用Sobel卷积核提取水平方向变化\[ K_x \frac{1}{8} \begin{bmatrix} -101\\ -202\\ -101 \end{bmatrix} \]竖直方向卷积核为\[ K_yK_x^{\mathrm T} \]局部变化强度为\[ G \sqrt{ G_x^2G_y^2 } \]【图3应力场、卷积特征与池化结果】图中可以看到原始场在圆孔两侧形成集中区域Sobel卷积突出孔边界和场梯度较大的位置最大池化将尺寸从 \(64\times64\) 降至 \(32\times32\)池化后主要集中区域仍被保留但空间细节有所损失。真正训练CNN时卷积核不是预先指定的Sobel算子而是通过反向传播从训练数据中学习。十一、一个基础CNN的尺寸变化下面建立两层卷积特征提取器\[ 64\times64\times1 \]经过第一层卷积后\[ 64\times64\times8 \]第一次最大池化后\[ 32\times32\times8 \]第二层卷积后\[ 32\times32\times16 \]第二次最大池化后\[ 16\times16\times16 \]【图4CNN特征提取结构】尺寸变化可以理解为\[ \boxed{ \text{空间分辨率逐渐下降特征通道逐渐增加} } \]浅层卷积可能学习边界、梯度和局部集中深层卷积会组合这些基础特征形成更大范围的空间模式。十二、使用NumPy检查CNN张量尺寸以下代码使用8个随机卷积核完成第一层前向计算。随机卷积核没有经过训练代码目的只是验证通道和空间尺寸。rng np.random.default_rng(42) # 一个样本、一个通道、64×64场 input_tensor np.zeros( (1, 1, 64, 64) ) # 8个输出通道、1个输入通道、3×3卷积核 conv1_weights rng.normal( 0, 0.1, size(8, 1, 3, 3) ) conv1_bias np.zeros(8) feature_maps np.stack([ conv2d_single( input_tensor[0, 0], conv1_weights[channel, 0], padding1 ) conv1_bias[channel] for channel in range(8) ])[None, ...] # ReLU激活 feature_maps np.maximum( feature_maps, 0 ) pooled_maps np.stack([ max_pool2d(feature_maps[0, channel]) for channel in range(8) ])[None, ...] print(输入, input_tensor.shape) print(卷积核, conv1_weights.shape) print(卷积输出, feature_maps.shape) print(池化输出, pooled_maps.shape)实际输出输入 (1, 1, 64, 64) 卷积核 (8, 1, 3, 3) 卷积输出 (1, 8, 64, 64) 池化输出 (1, 8, 32, 32)卷积输出中的8表示网络使用8个不同卷积核产生8张特征图。十三、使用PyTorch定义基础CNN安装PyTorch后可以将同样的结构写成import torch import torch.nn as nn class StressCNN(nn.Module): def __init__(self): super().__init__() self.features nn.Sequential( nn.Conv2d( in_channels1, out_channels8, kernel_size3, padding1 ), nn.ReLU(), nn.MaxPool2d( kernel_size2, stride2 ), nn.Conv2d( in_channels8, out_channels16, kernel_size3, padding1 ), nn.ReLU(), nn.MaxPool2d( kernel_size2, stride2 ) ) self.pool nn.AdaptiveMaxPool2d((1, 1)) self.output nn.Linear(16, 1) def forward(self, x): x self.features(x) x self.pool(x) x torch.flatten(x, start_dim1) return self.output(x) model StressCNN() sample torch.zeros( 4, 1, 64, 64 ) prediction model(sample) print(输入形状, sample.shape) print(输出形状, prediction.shape)预期输出输入形状 torch.Size([4, 1, 64, 64]) 输出形状 torch.Size([4, 1])这里的4表示一个批次中有4个样本每个样本输出一个标量。Conv2d和MaxPool2d的参数定义可参考PyTorch Conv2d文档和PyTorch MaxPool2d文档。十四、CNN可以完成哪些力学任务14.1 标量回归输入几何和载荷场输出\[ \sigma_{\max} \]或者\[ U_{\max},\quad J,\quad K_I,\quad N_f \]这类任务的输出是一个或少量数值可以在卷积特征提取器后连接池化层和全连接层。14.2 缺陷分类输入应力场、位移场或检测图像输出\[ \text{无缺陷} \]\[ \text{孔隙} \]\[ \text{脱层} \]\[ \text{裂纹} \]分类任务通常在最后使用Softmax或Sigmoid并采用交叉熵损失。14.3 全场预测输入\[ \text{几何} \text{材料} \text{载荷} \text{边界条件} \]输出\[ \hat{\boldsymbol{\sigma}} \in \mathbb{R}^{64\times64} \]此时不能把全部空间信息压缩成一个标量。通常需要编码器—解码器结构\[ \text{输入场} \rightarrow \text{压缩特征} \rightarrow \text{上采样重建} \rightarrow \text{预测场} \]后续U-Net课程将专门讲解这种全场预测方法。十五、残差连接当CNN层数增加时网络可能出现训练困难。残差连接将输入直接加到变换结果上\[ \boldsymbol{y} \mathcal{F}(\boldsymbol{x}) \boldsymbol{x} \]如果当前层不需要改变输入网络只需让\[ \mathcal{F}(\boldsymbol{x})\approx0 \]便可以近似保留原始信息。一个基本残差块可以写为class ResidualBlock(nn.Module): def __init__(self, channels): super().__init__() self.layers nn.Sequential( nn.Conv2d( channels, channels, kernel_size3, padding1 ), nn.ReLU(), nn.Conv2d( channels, channels, kernel_size3, padding1 ) ) self.activation nn.ReLU() def forward(self, x): return self.activation( self.layers(x) x )直接相加要求两个张量尺寸一致\[ \operatorname{shape} \left( \mathcal{F}(\boldsymbol{x}) \right) \operatorname{shape} (\boldsymbol{x}) \]若通道数或空间尺寸不同需要使用 \(1\times1\) 卷积等方法调整尺寸。十六、一维卷积与时序力学数据卷积并不只用于二维云图。对于蠕变、疲劳和动力响应可以将数据写成\[ X\in\mathbb{R}^{N\times C\times T} \]其中 \(T\) 是时间步数量。一维卷积为\[ y_t \sum_{k0}^{K-1} w_kx_{tk} c \]它可以提取短时间振动模式局部峰值载荷突变响应上升或下降趋势周期性疲劳特征。【图5一维卷积提取时序局部变化】一维CNN擅长提取局部时序模式。若需要描述很长时间范围内的历史依赖可以进一步使用下一阶段将学习的LSTM或Transformer。十七、有限元数据进入CNN前的处理真实有限元数据通常位于非结构化网格上而普通二维CNN要求规则数组。因此常见处理流程为Abaqus ODB场输出 ↓ 节点或积分点数据提取 ↓ 统一坐标与单位 ↓ 插值到规则网格 ↓ 构造几何掩码与边界条件通道 ↓ 输入CNN插值过程中需要注意不要跨越孔洞或裂纹进行错误插值区分节点值和积分点值保留模型外部区域的掩码固定输入和输出坐标范围训练集与测试集使用相同的插值规则记录Pa、MPa、m和mm等单位网格插值误差与CNN预测误差应分别评估。如果模型使用非结构化网格并且不希望插值可以考虑图神经网络而不是强行将所有有限元网格转换为图像。十八、场预测的损失函数普通像素均方误差可以写为\[ \mathcal{L}_{\mathrm{field}} \frac{1}{N_{\mathrm{valid}}} \sum_{i,j} M_{i,j} \left( \hat{\sigma}_{i,j} - \sigma_{i,j} \right)^2 \]其中 \(M_{i,j}\) 是有效区域掩码\[ M_{i,j} \begin{cases} 1,\text{材料区域}\\ 0,\text{孔洞或模型外部} \end{cases} \]如果不使用掩码大量模型外部的零值可能使总体损失看起来很小而材料区域的应力预测仍然很差。应力集中区域还可以增加权重\[ \mathcal{L}_{\mathrm{weighted}} \frac{ \sum_{i,j} M_{i,j}w_{i,j} \left( \hat{\sigma}_{i,j}-\sigma_{i,j} \right)^2 }{ \sum_{i,j}M_{i,j}w_{i,j} } \]但权重设置必须提前确定不能根据测试集结果反复修改。十九、评价全场预测不能只看一个RMSE至少应同时检查以下指标全场均方根误差\[ \mathrm{RMSE} \sqrt{ \frac{1}{N_{\mathrm{valid}}} \sum M_{i,j} \left( \hat{\sigma}_{i,j}-\sigma_{i,j} \right)^2 } \]峰值相对误差\[ e_{\mathrm{peak}} \frac{ \left| \hat{\sigma}_{\max}-\sigma_{\max} \right| }{ \left|\sigma_{\max}\right|\epsilon } \times100\% \]高应力区域重合程度例如比较预测场和真实场中\[ \sigma\geq0.9\sigma_{\max} \]区域的位置是否一致。工程中全场平均误差很小并不意味着裂纹尖端或孔边的峰值预测准确。二十、常见错误错误一把云图截图直接作为训练数据截图可能带有图例、文字、坐标轴和不同色标。CNN可能学习颜色设置而不是实际场变量。更合适的方法是从ODB中提取数值场再统一映射到规则网格。错误二每张云图使用不同色标若必须使用图像应固定色标范围。否则相同颜色可能对应不同应力值。错误三把空白区域当成真实零应力应为孔洞和模型外部建立独立掩码。错误四忽略通道的单位和顺序模型训练时使用[几何掩码, 载荷X, 载荷Y, 约束X, 约束Y]预测时也必须保持完全相同的顺序和单位。错误五使用随机节点划分数据同一有限元模型中的相邻节点高度相关。训练集和测试集应按照完整几何、完整工况或完整模型划分。错误六认为CNN自动满足力学规律普通CNN不会自动满足平衡方程、边界条件和本构关系。这些约束需要通过数据设计、结构设计、物理损失或后处理检查引入。二十一、课后练习练习一改变卷积核将示例卷积核改为\[ K \begin{bmatrix} -101\\ -202\\ -101 \end{bmatrix} \]观察它对水平方向变化的响应。练习二改变步长和填充分别计算conv2d_single( field, kernel, padding0, stride1 )conv2d_single( field, kernel, padding1, stride1 )conv2d_single( field, kernel, padding1, stride2 )记录三种输出尺寸。练习三比较池化方法对同一应力场分别进行最大池化和平均池化比较孔边高应力区域的保留程度。练习四设计有限元输入通道针对“带中心孔板的应力场预测”设计至少五个输入通道并说明每个通道的单位和物理含义。练习五物理合理性检查对于相同几何和材料逐渐增加载荷。如果问题处于线弹性阶段应检查CNN预测是否近似满足\[ \boldsymbol{\sigma}(\lambda F) \approx \lambda\boldsymbol{\sigma}(F) \]二十二、本节小结CNN相较MLP的关键变化是保留空间结构。\[ \boxed{ \text{卷积层} \text{局部连接} \text{权重共享} } \]卷积负责提取局部模式激活函数提供非线性表达能力池化压缩空间尺寸残差连接帮助较深网络传递信息。在有限元代理建模中CNN特别适合规则网格上的应力场、位移场、温度场和损伤场。但模型能否可靠应用还取决于数据通道设计、网格映射、区域掩码、损失函数和物理验证。课程附件本节完整程序只依赖NumPy和Matplotlib已经实际运行。建议将其放在正文之后的“附录完整可运行代码”中。[第十五节完整可运行代码][完整运行结果][教学场数据]【零基础学智能仿真-15】卷积神经网络CNN-从有限元场中提取空间特征资源-CSDN下载