当前位置: 首页 > news >正文

【Torch】nn.Conv1d、nn.Conv2d、nn.Conv3d算法详解

1. nn.Conv1d

1.1 输入(Input)和输出(Output)

  • 输入张量
    形状:(batch_size, in_channels, length)

    • batch_size:一次过网络的样本数
    • in_channels:每个样本的通道数(特征维度)
    • length:一维序列长度(时间步/采样点数)
  • 输出张量
    形状:(batch_size, out_channels, L_out)

    • out_channels:卷积核个数,也就是输出通道数
    • L_out:输出长度,由下面公式决定

1.2 输出长度计算公式

L_out = ⌊(length + 2·padding - dilation·(kernel_size−1) − 1) / stride⌋ + 1
  • ⌊·⌋ 表示向下取整
  • stride=1dilation=1 且想让 L_out = length 时,令
    padding = (kernel_size - 1) // 2
    
    kernel_size 应为奇数。

1.3 构造函数入参详解

nn.Conv1d(in_channels: int,out_channels: int,kernel_size: int or tuple,stride: int or tuple = 1,padding: int or tuple = 0,dilation: int or tuple = 1,groups: int = 1,bias: bool = True,padding_mode: str = 'zeros'
)
参数类型说明
in_channelsint输入通道数,必须与输入张量的第二维度匹配。
out_channelsint输出通道数,即卷积核数量,也决定了输出张量的通道数。
kernel_sizeint 或 1-tuple卷积核大小。单个整数表示每次跨越 kernel_size 个位置;也可写成 (k,)
strideint 或 1-tuple步幅:卷积核每次滑动的长度;默认为 1。
paddingint 或 1-tuple边界补零数;默认为 0。可用来控制输出长度或让特征对齐。
dilationint 或 1-tuple膨胀系数:在卷积核内部元素之间插入 (dilation−1) 个“空洞”。
groupsint分组卷积:
‒1(默认):标准卷积
‒ =in_channels:每通道独立卷积(Depthwise)
‒ 其它:将通道分为若干组,各组内部卷积
biasbool是否加偏置项;如果后面接 BatchNorm1d,常设为 False
padding_mode{‘zeros’,‘reflect’,‘replicate’,‘circular’}填充模式;默认 'zeros'。其余几种根据边界不同策略插值或循环。

1.4 各参数作用和典型场景

  1. in_channels & out_channels

    • 直接决定参数量:
      参数量 ≈ out_channels × in_channels × kernel_size
      
    • 设计网络时,通道数往往从少到多(如 1→16→32→64),提取越来越丰富的特征。
  2. kernel_size

    • 越大感受野越宽,但参数量和计算量增加。
    • 常用 3、5、7,小模型常选 3;序列任务也会用 [3,5,7] 多尺度并行。
  3. stride

    • 控制下采样率。stride>1 会缩短序列长度,类似池化的效果。
    • 如果不想丢信息,设为 1;想快速减少长度,可设为 2、4。
  4. padding

    • 保证边界信息,或让输出与输入对齐。
    • “same” 效果:padding = (kernel_size−1)//2,需 stride=1, dilation=1
  5. dilation

    • 增大感受野的同时保持参数量不变。
    • WaveNet、语音分割、序列建模中常用。
  6. groups

    • groups=in_channelsDepthwise 卷积,极大减少计算量(MobileNet 系列)。
    • groups>1 且不等于 in_channels → 分组卷积(ResNeXt 即用到)。
  7. bias & BatchNorm1d

    • 若后面加了 BN,可不加 bias;否则对非线性对齐、加偏效果更好。
  8. padding_mode

    • 对信号边界处理更灵活:
      • 'reflect':镜像填充
      • 'replicate':复制边界值
      • 'circular':循环填充

1.5 示例

import torch
import torch.nn as nn# 1. 定义 Conv1d 层
conv = nn.Conv1d(in_channels=2,out_channels=4,kernel_size=5,stride=2,padding=2,dilation=1,groups=1,bias=False,padding_mode='zeros'
)# 2. 输入:batch=8, channels=2, length=100
x = torch.randn(8, 2, 100)# 3. 前向
y = conv(x)print(f"输入 shape: {x.shape}")
print(f"输出 shape: {y.shape}")# 4. 手动验证输出长度
L_out = (100 + 2*2 - 1*(5-1) - 1) // 2 + 1
print(f"计算的输出长度: {L_out}")
assert y.shape[-1] == L_out

输出:

输入 shape: torch.Size([8, 2, 100])
输出 shape: torch.Size([8, 4, 50])
计算的输出长度: 50

1.6 使用注意事项

  • 维度顺序:务必保证输入是 (N, C, L),尤其对接入预处理或自定义 Dataset 时不要搞反通道和长度维度。
  • 长度保持:要 “同尺寸” 通常 stride=1, dilation=1, padding=(k−1)//2,且 k 为奇数。
  • 参数对齐groups 和通道数要整除匹配,否则初始化会报错。
  • 结合 BatchNorm/Activation:常见顺序是
    Conv1d → BatchNorm1d → ReLU
    
    Conv1d(bias=False) → BatchNorm1d → ReLU
    
  • Memory/Speed:大 kernel_size、大 out_channels、小 groups 都会显著增加计算和显存,实践中常做微调。

2. nn.Conv2d

2.1 输入(Input)和输出(Output)

  • 输入张量
    形状:(batch_size, in_channels, height, width)

    • batch_size:一次过网络的样本数
    • in_channels:输入通道数,例如 RGB 图像是 3
    • height, width:图像(或特征图)的高和宽
  • 输出张量
    形状:(batch_size, out_channels, H_out, W_out)

    • out_channels:卷积核个数,也是输出通道数
    • H_out, W_out:输出高宽,由下面的公式计算得出

2.2 输出尺寸计算公式

对于高(height)方向:

H_out = ⌊(height + 2·padding[0] - dilation[0]·(kernel_size[0]-1) - 1) / stride[0]⌋ + 1

对于宽(width)方向同理:

W_out = ⌊(width  + 2·padding[1] - dilation[1]·(kernel_size[1]-1) - 1) / stride[1]⌋ + 1
  • ⌊·⌋ 表示向下取整
  • 如果 stride=1, dilation=1 并希望 H_out=height, W_out=width,则令
    padding = ((kernel_size[0]-1)//2, (kernel_size[1]-1)//2)
    
    kernel_size 各维应为奇数。

2.3 构造函数入参详解

nn.Conv2d(in_channels: int,out_channels: int,kernel_size: int or tuple,stride: int or tuple = 1,padding: int or tuple = 0,dilation: int or tuple = 1,groups: int = 1,bias: bool = True,padding_mode: str = 'zeros'
)
参数类型说明
in_channelsint输入通道数,必须与输入张量第2维匹配。
out_channelsint输出通道数,决定卷积核数量以及输出张量第2维。
kernel_sizeint 或 2-tuple卷积核大小。
单个整数表示同高同宽;元组 (k_h,k_w) 可分别指定。
strideint 或 2-tuple步幅:控制卷积核滑动的步长。
默认为 1(不下采样)。
paddingint 或 2-tuple边界补零层数。
可为单值或 (pad_h,pad_w)
dilationint 或 2-tuple膨胀系数:在卷积核内元素之间插入 (dilation−1) 个间隔。
groupsint分组卷积:
‒ 1(默认):标准卷积
‒ =in_channels:Depthwise 卷积
‒ 其它:通道分组后各组内卷积
biasbool是否添加偏置项;若后接 BatchNorm2d,可设为 False
padding_mode{‘zeros’,‘reflect’,‘replicate’,‘circular’}填充模式;默认 'zeros'

2.4 参数作用与典型场景

  1. in_channels & out_channels

    • 参数量:out_channels × in_channels × k_h × k_w
    • 通道数一般从小到大设计(例如 3→16→32→64)以逐步提取更丰富特征。
  2. kernel_size

    • 大核:更大感受野但参数/计算增加。
    • 小核(如 3×3):常用,能堆叠模拟更大感受野且节省参数(VGG、ResNet 均用 3×3)。
  3. stride

    • >1 会下采样(缩小 H_out/W_out),等价于卷积 + 池化叠加。
    • 若希望保留所有空间信息,使用 stride=1
  4. padding

    • “same” 填充:padding = ((k_h−1)//2, (k_w−1)//2) 保持高宽不变(需 stride=1, dilation=1)。
    • 边界补零可缓和边缘效应。
  5. dilation

    • 可在不增大核尺寸的情况下扩展感受野。
    • 在语义分割(DeepLab)、序列建模、波形生成中常用。
  6. groups

    • groups=in_channelsDepthwise 卷积,极大减少乘加量(MobileNet)。
    • 1<groups<in_channels分组卷积,ResNeXt 等网络使用。
  7. bias & BN

    • 若后接 BatchNorm2d → 多余偏置,可设 bias=False;仅卷积 + ReLU 时通常保留偏置。
  8. padding_mode

    • zeros 外,reflect(镜像填充)、replicate(边界复制)、circular(循环填充)可根据图像边界特征选择。

2.5 示例

import torch
import torch.nn as nn# 定义一个 Conv2d 层
conv2d = nn.Conv2d(in_channels=3,        # 输入RGB通道out_channels=16,      # 输出特征图通道数kernel_size=(3, 3),   # 3×3 卷积stride=(1, 1),        # 步幅1,不下采样padding=(1, 1),       # same 填充,保持尺寸dilation=(1, 1),      # 不使用膨胀groups=1,             # 标准卷积bias=False,           # 后接 BatchNorm2d 时可以 Falsepadding_mode='zeros'  # 零填充
)# 输入:batch=8, C=3, H=64, W=64
x = torch.randn(8, 3, 64, 64)# 前向
y = conv2d(x)print("输入 shape:", x.shape)   # torch.Size([8,3,64,64])
print("输出 shape:", y.shape)   # torch.Size([8,16,64,64])# 验证输出尺寸
H_out = (64 + 2*1 - 1*(3-1) - 1) // 1 + 1
W_out = (64 + 2*1 - 1*(3-1) - 1) // 1 + 1
print("计算 H_out, W_out:", H_out, W_out)
assert y.shape[2:] == (H_out, W_out)

2.6 使用注意事项

  • 维度顺序:确保输入为 (N, C, H, W),预处理管道或自定义 Dataset 时不要弄反。
  • 同尺寸卷积stride=1, dilation=1, padding=(k−1)//2k 为奇数。
  • 分组/深度卷积groups 必须整除 in_channelsout_channels,否则会报错。
  • 性能权衡:大 kernel_size、大 out_channels、小 groups → 计算/显存开销大;小 groupsgroups=in_channels → 轻量但信息融合有限。
  • 典型组合
    Conv2d(bias=False) → BatchNorm2d → ReLU
    
    Conv2d → ReLU → MaxPool2d
    
  • 边界填充模式:对自然图像常用 reflectreplicate,可减少硬零填充带来的边缘伪影。

3.nn.Conv3d

3.1 输入(Input)和输出(Output)

  • 输入张量
    形状:(batch_size, in_channels, depth, height, width)

    • batch_size:一次过网络的样本数
    • in_channels:输入通道数,例如医学体数据常是 1(灰度)或多模态时>1
    • depth, height, width:体数据的深度、行高和列宽
  • 输出张量
    形状:(batch_size, out_channels, D_out, H_out, W_out)

    • out_channels:卷积核个数,也是输出通道数
    • D_out, H_out, W_out:输出的深度、高度和宽度,由下面公式计算得出

3.2 输出尺寸计算公式

对于深度(depth)方向:

D_out = ⌊(depth + 2·padding[0] - dilation[0]·(kernel_size[0]−1) − 1) / stride[0]⌋ + 1

对于高度(height)和宽度(width)方向同理:

H_out = ⌊(height + 2·padding[1] - dilation[1]·(kernel_size[1]−1) − 1) / stride[1]⌋ + 1
W_out = ⌊(width  + 2·padding[2] - dilation[2]·(kernel_size[2]−1) − 1) / stride[2]⌋ + 1
  • ⌊·⌋ 表示向下取整
  • 若希望 D_out=depth, H_out=height, W_out=width(保持尺寸不变),需 stride=1, dilation=1
    padding = ((kernel_size[0]-1)//2,(kernel_size[1]-1)//2,(kernel_size[2]-1)//2
    )
    
    且每个 kernel_size 维度为奇数。

3.3 构造函数参数详解

nn.Conv3d(in_channels: int,out_channels: int,kernel_size: int or tuple,stride: int or tuple = 1,padding: int or tuple = 0,dilation: int or tuple = 1,groups: int = 1,bias: bool = True,padding_mode: str = 'zeros'
)
参数类型说明
in_channelsint输入通道数,必须与输入张量的第2维匹配。
out_channelsint输出通道数,即卷积核数量,也决定输出张量的第2维。
kernel_sizeint 或 3-tuple卷积核大小。
单个整数表示 d×d×d,元组 (k_d,k_h,k_w) 可分别指定。
strideint 或 3-tuple步幅。控制卷积核在各维度滑动的步长。默认为 1(无下采样)。
paddingint 或 3-tuple边界补零数。可为单值或 (pad_d,pad_h,pad_w)。用于控制输出尺寸或保持边界信息。
dilationint 或 3-tuple膨胀系数:在卷积核内部元素之间插入 (dilation−1) 个间隔以增大感受野。
groupsint分组卷积:
‒ 1(默认):标准卷积
‒ =in_channels:每通道独立卷积(Depthwise 卷积)
‒ 其它:按组分通道,各组内部卷积
biasbool是否加偏置项;若后接 BatchNorm3d,可设为 False
padding_mode{‘zeros’,‘reflect’,‘replicate’,‘circular’}填充模式;默认 'zeros'。其他模式按镜像、复制或循环策略处理边界。

3.4 参数作用与典型场景

  1. in_channels & out_channels

    • 参数量≈out_channels × in_channels × k_d × k_h × k_w
    • 设计时常沿用“通道逐层增加”策略(如 1→8→16→32),逐级提取更丰富的空间-体素特征。
  2. kernel_size

    • 大核(如 5×5×5)感受野大,但参数和计算量显著增加。
    • 小核(3×3×3)常用,可叠加多层模拟更大感受野且更高效(如 3D-ResNet、C3D 网络)。
  3. stride

    • >1 会在相应维度下采样,减小数据尺寸,类似 3D 池化。
    • 若不想丢特征,使用 stride=1; 若要快速降采样,可设为 (2,2,2)
  4. padding

    • 保持边界信息、防止空间尺寸急剧缩小。
    • “same” 填充:设为 (k_i−1)//2 可在 stride=1,dilation=1 时保持尺寸。
  5. dilation

    • 扩张卷积,可在不增加核大小的情况下增大感受野,常用于分割任务(如 3D 医学图像分割)。
  6. groups

    • groups=in_channels → Depthwise 3D 卷积(MobileNet-3D 变体)。
    • 分组卷积可减小计算开销、启发出多路径特征提取(ResNeXt-3D 等)。
  7. bias & BN

    • 对于 “Conv3d → BatchNorm3d” 可关掉 bias,减少冗余;单纯卷积时保留更灵活。
  8. padding_mode

    • 自然场景体数据较少用非零填充,但在边缘伪影敏感的医学体数据上,可尝试 reflectreplicatecircular

3.5 示例

import torch
import torch.nn as nn# 1. 定义 Conv3d 层
conv3d = nn.Conv3d(in_channels=1,          # 单通道体数据out_channels=4,         # 输出4个特征通道kernel_size=(3, 3, 3),  # 3×3×3 卷积stride=(1, 2, 2),       # 深度不下采样,高宽各下采样2padding=(1, 1, 1),      # same 填充dilation=(1, 1, 1),     # 普通卷积groups=1,               # 标准bias=False,             # 后接 BNpadding_mode='zeros'    # 零填充
)# 2. 构造输入:batch=2, C=1, D=8, H=64, W=64
x = torch.randn(2, 1, 8, 64, 64)# 3. 前向计算
y = conv3d(x)print("输入 shape:", x.shape)   # torch.Size([2,1, 8,64,64])
print("输出 shape:", y.shape)   # torch.Size([2,4, 8,32,32])# 4. 验证输出尺寸
D_out = (8  + 2*1 - 1*(3-1) - 1) // 1 + 1   # =8
H_out = (64 + 2*1 - 1*(3-1) - 1) // 2 + 1   # =32
W_out = (64 + 2*1 - 1*(3-1) - 1) // 2 + 1   # =32
assert y.shape[2:] == (D_out, H_out, W_out)

3.6 使用注意事项

  • 维度顺序:务必保证输入为 (N, C, D, H, W),切忌把通道与其中任一空间维搞错。
  • 同尺寸卷积:要保持 D/H/W 不变,需 stride=1,dilation=1padding=(k_i−1)//2kernel_size 各维为奇数。
  • 分组/深度卷积groups 必须整除 in_channelsout_channels,否则报维度不匹配错误。
  • 性能考量:3D 卷积计算量和显存开销大,设计网络时多用小核叠加、合适下采样、或借助 groups 降低复杂度。
  • 典型配合
    Conv3d(bias=False) → BatchNorm3d → ReLU
    
    Conv3d → ReLU → MaxPool3d
    
  • 边界填充模式:对医学体数据可尝试 reflect/replicate,减少边缘假性纹理。

4.小结

4.1 输入输出

  • Conv1d:处理一维序列,输入 (N, C_in, L) → 输出 (N, C_out, L_out)
  • Conv2d:处理二维平面(图像、特征图),输入 (N, C_in, H, W) → 输出 (N, C_out, H_out, W_out)
  • Conv3d:处理体数据(视频帧序列、医学体素),输入 (N, C_in, D, H, W) → 输出 (N, C_out, D_out, H_out, W_out)

4.2 典型应用场景

  • Conv1d:时间序列预测、语音/音频特征提取、传感器信号处理。
  • Conv2d:图像分类、目标检测、语义分割、风格迁移等所有平面图像相关任务。
  • Conv3d:3D 医学图像分割(CT/MRI)、视频动作识别、三维点云特征学习。

4.3 参数通用性

所有三者均共享相同的设计思路和参数:

  • in_channels, out_channels(通道数)
  • kernel_size(卷积核大小,一维/二维/三维对应 1–3 元组)
  • stride(步幅)
  • padding(边界填充)
  • dilation(膨胀率)
  • groups(分组卷积/Depthwise)
  • bias(偏置项)
  • padding_mode(如 zeros, reflect 等)

4.4 输出尺寸公式

对每个空间/时间维度均可用:

L_out = ⌊(L_in + 2·pad − dilation·(k−1) −1) / stride⌋ + 1

其中 k, pad, stride, dilation 可为单值或对应维数的元组。

4.5 使用注意

  1. 维度顺序要对齐:始终是 (batch, channels, …dims…)
  2. 保持“same”尺寸stride=1, dilation=1padding=(k−1)//2k为奇数)。
  3. 分组卷积groups 必须能整除 in_channelsout_channelsgroups=in_channels 做 Depthwise 卷积。
  4. 结合 BatchNorm:若后面接 BatchNorm,可将 bias=False,减少冗余。
  5. 计算与内存:随着维度增加(1→2→3D)、kernel_sizeout_channels 增大,计算量和显存需求呈指数增长,注意合理下采样和分组。

5.Conv1D计算实例

  • 输入参数
    • 批大小 B = 1 B=1 B=1
    • 输入通道数 C i n = 4 C_{\rm in}=4 Cin=4,长度 L i n = 4 L_{\rm in}=4 Lin=4
    • 卷积核大小 K = 2 K=2 K=2,步幅 stride = 1 \text{stride}=1 stride=1,填充 padding = 0 \text{padding}=0 padding=0,膨胀 dilation = 1 \text{dilation}=1 dilation=1
    • 输出通道数 C o u t = 2 C_{\rm out}=2 Cout=2

5.1 输出维度计算

长度方向输出为
L o u t = ⌊ L i n + 2 p a d d i n g − d i l a t i o n ( K − 1 ) − 1 s t r i d e + 1 ⌋ = ⌊ 4 + 0 − 1 − 1 1 + 1 ⌋ = 3. L_{\rm out} = \Big\lfloor \frac{L_{\rm in} +2\,\mathrm{padding} -\mathrm{dilation}\,(K-1) -1 }{\mathrm{stride}} +1 \Big\rfloor = \Big\lfloor\frac{4 + 0 -1 -1}{1} +1\Big\rfloor =3. Lout=strideLin+2paddingdilation(K1)1+1=14+011+1=3.
所以输出张量形状为
( 1 , C o u t = 2 , L o u t = 3 ) . (1,\;C_{\rm out}=2,\;L_{\rm out}=3). (1,Cout=2,Lout=3).

5.2 具体数值例子

1 输入张量 X ∈ R 1 × 4 × 4 X\in\mathbb R^{1\times4\times4} XR1×4×4

我们取:
X [ 0 , 0 , : ] = [ 1 , 2 , 3 , 4 ] , X [ 0 , 1 , : ] = [ 5 , 6 , 7 , 8 ] , X [ 0 , 2 , : ] = [ 9 , 10 , 11 , 12 ] , X [ 0 , 3 , : ] = [ 13 , 14 , 15 , 16 ] . X[0,0,:]=[\,1,2,3,4\,],\quad X[0,1,:]=[\,5,6,7,8\,],\quad X[0,2,:]=[\,9,10,11,12\,],\quad X[0,3,:]=[\,13,14,15,16\,]. X[0,0,:]=[1,2,3,4],X[0,1,:]=[5,6,7,8],X[0,2,:]=[9,10,11,12],X[0,3,:]=[13,14,15,16].

2 卷积核权重 W ∈ R 2 × 4 × 2 W\in\mathbb R^{2\times4\times2} WR2×4×2,偏置 b = [ 0 , 0 ] b=[0,0] b=[0,0]

  • 第 0 号输出通道 ( W [ 0 , : , : ] ) \bigl(W[0,:,:]\bigr) (W[0,:,:]): 所有通道、所有位置权重都设为 1
    W [ 0 , : , : ] = [ 1 1 1 1 1 1 1 1 ] W[0,:,:] = \begin{bmatrix} 1 & 1\\ 1 & 1\\ 1 & 1\\ 1 & 1 \end{bmatrix} W[0,:,:]= 11111111
  • 第 1 号输出通道 只“看”通道 2 和 3
    W [ 1 , : , : ] = [ 0 0 0 0 1 1 1 1 ] W[1,:,:] =\begin{bmatrix} 0 & 0\\ 0 & 0\\ 1 & 1\\ 1 & 1 \end{bmatrix} W[1,:,:]= 00110011

3 滑窗展开(Unfold)

  • 每条通道从长度 4 上取 K = 2 K=2 K=2连续滑窗,步幅 1,共 L o u t = 3 L_{\rm out}=3 Lout=3个窗口。
  • C i n K = 4 × 2 = 8 C_{\rm in}K=4\times2=8 CinK=4×2=8行、 L o u t = 3 L_{\rm out}=3 Lout=3列堆成矩阵 M ∈ R 8 × 3 M\in\mathbb R^{8\times3} MR8×3
    M = [ 1 2 3 2 3 4 5 6 7 6 7 8 9 10 11 10 11 12 13 14 15 14 15 16 ] . M = \begin{bmatrix} % 通道0 1 & 2 & 3\\ 2 & 3 & 4\\[2pt] % 通道1 5 & 6 & 7\\ 6 & 7 & 8\\[2pt] % 通道2 9 & 10&11\\ 10&11&12\\[2pt] % 通道3 13&14&15\\ 14&15&16 \end{bmatrix}. M= 12569101314236710111415347811121516 .

4 权重拉平

  • W W W的每个输出通道的 ( 4 , 2 ) (4,2) (4,2)小核展平为 8 维向量:
    W f l a t = [ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ⏟ 第0通道 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ⏟ 第1通道 ] ∈ R 2 × 8 . W_{\rm flat} = \begin{bmatrix} \underbrace{1,1,1,1,1,1,1,1}_{\text{第0通道}}\\ \underbrace{0,0,0,0,1,1,1,1}_{\text{第1通道}} \end{bmatrix} \in\mathbb R^{2\times8}. Wflat= 0通道 1,1,1,1,1,1,1,11通道 0,0,0,0,1,1,1,1 R2×8.

5 矩阵乘 + 偏置

Y f l a t = W f l a t M + b [ 1 , 1 , 1 ⏟ L o u t ] = [ 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 ] [ 1 2 3 2 3 4 5 6 7 6 7 8 9 10 11 10 11 12 13 14 15 14 15 16 ] . Y_{\rm flat} = W_{\rm flat}\;M \;+\; b\;\bigl[\underbrace{1,\,1,\,1}_{L_{\rm out}}\bigr] = \begin{bmatrix}1&1&1&1&1&1&1&1\\0&0&0&0&1&1&1&1\end{bmatrix} \begin{bmatrix} 1 & 2 & 3\\ 2 & 3 & 4\\ 5 & 6 & 7\\ 6 & 7 & 8\\ 9 &10 &11\\ 10&11 &12\\ 13&14 &15\\ 14&15 &16 \end{bmatrix}. Yflat=WflatM+b[Lout 1,1,1]=[1010101011111111] 12569101314236710111415347811121516 .

  • 第 0 通道(全通道求和):
    [ 1 + 2 + 5 + 6 + 9 + 10 + 13 + 14 , 2 + 3 + 6 + 7 + 10 + 11 + 14 + 15 , 3 + 4 + 7 + 8 + 11 + 12 + 15 + 16 ] = [ 60 , 78 , 96 ] . [\,1+2+5+6+9+10+13+14,\; 2+3+6+7+10+11+14+15,\; 3+4+7+8+11+12+15+16\,] =[60,\;78,\;96]. [1+2+5+6+9+10+13+14,2+3+6+7+10+11+14+15,3+4+7+8+11+12+15+16]=[60,78,96].
  • 第 1 通道(只求通道 2、3):
    [ 9 + 10 + 13 + 14 , 10 + 11 + 14 + 15 , 11 + 12 + 15 + 16 ] = [ 46 , 50 , 54 ] . [\,9+10+13+14,\; 10+11+14+15,\; 11+12+15+16\,] =[46,\;50,\;54]. [9+10+13+14,10+11+14+15,11+12+15+16]=[46,50,54].

6 恢复输出张量形状

Y f l a t ∈ R 2 × 3 Y_{\rm flat}\in\mathbb R^{2\times3} YflatR2×3reshape 成 ( 1 , 2 , 3 ) (1,2,3) (1,2,3)

Y[0,0,:] = [60, 78, 96]
Y[0,1,:] = [46, 50, 54]

总结

  • 输出维度 ( 1 , 2 , 3 ) (1,\,2,\,3) (1,2,3)来自于 C o u t = 2 \;C_{\rm out}=2 Cout=2 L o u t = 3 L_{\rm out}=3 Lout=3
  • 底层是先 Unfold → 拼成 ( C i n K ) × L o u t (C_{\rm in}K)\times L_{\rm out} (CinK)×Lout的滑窗矩阵 → 用 ( C o u t × C i n K ) (C_{\rm out}\times C_{\rm in}K) (Cout×CinK)的权重做矩阵乘 → 加偏置 → reshape。

5.3 通俗理解

1个batch下,100维度7个时间步的数据,使用kernel_size=2,out_channels=变成=10,如何通俗解释一下?
在这里插入图片描述

  • 原始数据:每个样本是一条“7 天×100 维” 的时间序列,形状 ( 100 , 7 ) (100,7) (100,7)。横轴是时间(一周的 7 天),竖轴是每天的 100 个特征。

  • kernel_size=2:相当于你每次“看两天”——滑动窗口宽度是 2 天。

  • out_channels=10:相当于你准备了 10 台不同的“提炼机”(滤波器),每台机子专门学会从这两天里 100 维的原始特征中,提炼出一个新的“综合指标”(一个标量)。

  • 滑动过程

    1. 窗口 1–2 天:把第 1 天和第 2 天上各自的 100 维拼在一起,交给 10 台“提炼机”,每台机子输出一个分数 → 得到 10 维。
    2. 窗口 2–3 天:同样再看第 2、3 天的 100 维,10 台机子各产出一个分数 → 又是一组 10 维。
    3. …如此往后,直到看第 6、7 天。
  • 输出长度:由于一周 7 天,窗口宽 2 天、步幅默认为 1 天,就能滑出 7 − ( 2 − 1 ) = 6 7-(2-1)=6 7(21)=6 个位置(1–2、2–3、…、6–7)。

  • 输出形状:每个样本变成 ( 10 , 6 ) (10,6) (10,6) —— 10 条新特征,6 个时间点(每个点对应原来的两天窗口)。

打个比方

想象你是气象专家,每天记录 100 种气象指标(温度、湿度、风速……共 100 种)。现在你要学“2 天为期”的短期趋势分析:

  • 你设计了 10 种 短期趋势摘要方法(out_channels=10),
  • 每种方法每天都对“前两天的数据”做一次综合打分,
  • 然后滑过一周,就得到了 6 个连续两天的趋势分数,每个分数是 10 维。

这样,Conv1d 就把原来“一周×100 维”的原始数据,转换成了“6 个两天窗口×10 维”的高层特征,更利于后续捕捉短期模式和做预测。

相关文章:

【Torch】nn.Conv1d、nn.Conv2d、nn.Conv3d算法详解

1. nn.Conv1d 1.1 输入&#xff08;Input&#xff09;和输出&#xff08;Output&#xff09; 输入张量 形状&#xff1a;(batch_size, in_channels, length) batch_size&#xff1a;一次过网络的样本数in_channels&#xff1a;每个样本的通道数&#xff08;特征维度&#xff0…...

Android WebRTC回声消除

文章目录 安卓可用的回声消除手段各种回声消除技术优缺点WebRTC回声消除WebRTC回声消除回声消除处理流程WebRTC AECM APP 安卓可用的回声消除手段 硬件回声消除 使用 AudioRecord 的 VOICE_COMMUNICATION 模式&#xff1a;通过 AudioRecord 的 VOICE_COMMUNICATION 音频源可以…...

[Linux运维] [Ubuntu/Debian]在Lightsail Ubuntu服务器上安装Python环境的完整指南

在之前的教程中&#xff0c;我们已经讲过如何开通亚马逊Lightsail服务器并安装宝塔面板。今天&#xff0c;我们来进一步补充&#xff1a;如何在Lightsail上的Ubuntu/Debian系统中安装和配置Python开发环境。 本教程不仅适用于Lightsail服务器&#xff0c;也适用于所有使用Ubunt…...

2025医疗领域AI发展五大核心趋势与路线研究

引言 人工智能技术正在全球范围内深刻改变医疗服务的提供方式,推动全球医疗的普惠化、技术合作、产业升级以及公共卫生防控发生巨变[0]。医疗AI的浪潮奔涌向前,从2024年开始,生成式AI的爆发式发展更是将医疗AI推到了新的十字路口[1]。在这一背景下,本报告将深入探讨医疗领…...

【学习笔记】机器学习(Machine Learning) | 第六周|过拟合问题

机器学习&#xff08;Machine Learning&#xff09; 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习&#xff08;Machine Learning&#xff09;简要声明 摘要过拟合与欠拟合问题一、回归问题中的过拟合1. 欠拟合&#xff08;Underfit&#x…...

【MQ篇】RabbitMQ之惰性队列!

目录 引言&#xff1a;当“生产”大于“消费”&#xff0c;队列就“胖”了&#xff01;肥宅快乐队列&#xff1f;&#x1f914;队列界的“躺平”大师&#xff1a;惰性队列&#xff08;Lazy Queues&#xff09;驾到&#xff01;&#x1f634;如何“激活”你的队列的“惰性”属性…...

计算机视觉——通过 OWL-ViT 实现开放词汇对象检测

介绍 传统的对象检测模型大多是封闭词汇类型&#xff0c;只能识别有限的固定类别。增加新的类别需要大量的注释数据。然而&#xff0c;现实世界中的物体类别几乎无穷无尽&#xff0c;这就需要能够检测未知类别的开放式词汇类型。对比学习&#xff08;Contrastive Learning&…...

第二部分:网页的妆容 —— CSS(下)

目录 6 布局基础&#xff1a;Display 与 Position - 元素如何排列和定位6.1 小例子6.2 练习 7 Flexbox 弹性布局&#xff1a;一维布局利器7.1 小例子7.2 练习 8 Grid 网格布局&#xff1a;强大的二维布局系统8.1 小例子8.2 练习 9 响应式设计与媒体查询&#xff1a;适应不同设备…...

vite项目tailwindcss4的使用

1、安装taillandcss 前几天接手了一个项目&#xff0c;看到别人用tailwindcss节省了很多css代码的编写&#xff0c;所以自己也想在公司项目中接入tailwindcss。 官网教程如下&#xff1a; Installing Tailwind CSS with Vite - Tailwind CSS 然而&#xff0c;我在vite中按…...

css中:is和:where 伪函数

在 CSS 里&#xff0c;:is() 属于伪类函数&#xff0c;其作用是对一组选择器进行匹配&#xff0c;只要元素与其中任何一个选择器相匹配&#xff0c;就可以应用对应的样式规则。以下是详细介绍&#xff1a; 基本语法 :is() 函数的参数是一个或多个选择器&#xff0c;各个选择器之…...

线下零售数据采集:在精度与效率之间寻找平衡点

线下零售数据采集&#xff1a;在精度与效率之间寻找平衡点 为什么线下零售必须重视数据采集&#xff1f; 随着零售行业竞争加剧&#xff0c;门店执行的标准化与透明化成为供应链协作、销售提升的基础工作。 POG&#xff08;陈列执行规范&#xff09;的落地效果、陈列策略的调整…...

【Robocorp实战指南】Python驱动的开源RPA框架

目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1&#xff1a;网页数据抓取案例2&#xff1a;Excel报表生成 运行结果验证 三、性能对比测试方…...

新ubuntu物理机开启ipv6让外网访问

Ubuntu 物理机 SSH 远程连接与 IPv6 外网访问测试指南 1. 通过 SSH 远程连接 Ubuntu 物理机 1.1 安装 SSH 服务 sudo apt update sudo apt install openssh-server1.2 检查 SSH 服务状态 sudo systemctl status ssh确认出现 active (running)。 1.3 获取物理机 IP 地址 i…...

驱动开发硬核特训 │ Regulator 子系统全解

一、Regulator子系统概述 在 Linux 内核中&#xff0c;Regulator 子系统是专门用于管理电源开关、电压调整、电流控制的一套完整框架。 它主要解决以下问题&#xff1a; 设备需要的电压通常不一样&#xff0c;如何动态调整&#xff1f;有些设备休眠时需要关闭供电&#xff0…...

入门版 鸿蒙 组件导航 (Navigation)

入门版 鸿蒙 组件导航 (Navigation) 注意&#xff1a;使用 DevEco Studio 运行本案例&#xff0c;要使用模拟器&#xff0c;千万不要用预览器&#xff0c;预览器看看 Navigation 布局还是可以的 效果&#xff1a;点击首页&#xff08;Index&#xff09;跳转到页面&#xff08…...

怎样将visual studio 2015开发的项目 保存为2010版本使用

用的老旧电脑跑vs2015太慢了&#xff0c;实在忍不了了&#xff01; 想把用 Visual Studio 2015 的做的项目保存为 Visual Studio 2010 兼容的格式&#xff0c;以后都使用2010写了。自己在网上搜了一下&#xff0c;亲测以下步骤可以的 手动修改解决方案和项目文件 修改解决方案…...

【学习笔记】软件测试流程-测试设计阶段

软件测试设计阶段这个阶段主要工作是编写测试用例。 什么是测试用例&#xff1f; 测试用例&#xff08;TestCase&#xff09;是为项目需求而编制的一组测试输入、执行条件以及预期结果&#xff0c;以便测试某个程序是否满足客户需求。简而言之&#xff0c;测试用例是每一个测…...

Rust 学习笔记:关于切片的两个练习题

Rust 学习笔记&#xff1a;关于切片的两个练习题 Rust 学习笔记&#xff1a;关于切片的两个练习题引用和切片引用的大小以下程序能否通过编译&#xff1f; Rust 学习笔记&#xff1a;关于切片的两个练习题 参考视频&#xff1a; https://www.bilibili.com/video/BV1GrDQYeEzS…...

BeeWorks企业内部即时通讯软件支持国产化,已在鸿蒙系统上稳定运行

一、企业用户面临的困境与痛点 一些企业用的即时通讯软件比较旧&#xff0c;存在的问题不仅影响了日常工作的正常开展&#xff0c;也阻碍了企业信息化建设的进程&#xff1a; ● 国产系统与移动端不兼容&#xff1a;仅支持Windows和MAC系统&#xff0c;无法在银河麒麟、统信U…...

java对文字按照语义切分

实现目标 把一段文本按照一个完整的一句话为单元进行切分。如&#xff1a;以逗号&#xff0c;感叹号结尾看作是一个句子。 实现方案 StanfordCoreNLP切分 引入依赖 <dependency><groupId>edu.stanford.nlp</groupId><artifactId>stanford-corenlp<…...

华纳云:centos如何实现JSP页面的动态加载

JSP(JavaServer Pages)作为Java生态中常用的服务器端网页技术&#xff0c;具有动态内容生成、可扩展性强、与Java无缝结合等优势。 而CentOS作为一款稳定、高效、安全的Linux服务器操作系统&#xff0c;非常适合部署JSP应用。 想要让JSP页面实现动态更新加载&#xff0c;避免…...

Android 消息队列之MQTT的使用(二):会话+消息过期机制,设备远程控制,批量控制实现

目录 一、实际应用场景 室内温湿度数据上传设备远程控制批量控制实现 二、会话管理、消息过期设置 4.1 会话管理 Clean Session参数 新旧会话模式对比典型应用场景 4.2 消息过期设置 MQTT 5.0消息过期机制 Message Expiry Interval属性QoS级别影响 三、实际应用场景 …...

一、JVM基础概念

一、JVM的设计目标 一次编译&#xff0c;到处运行(跨平台) ➔ Java编译成字节码&#xff0c;由JVM在不同平台解释/编译执行&#xff0c;实现跨平台。 内存管理与垃圾回收 ➔ JVM统一负责内存分配和回收&#xff0c;降低内存泄漏的风险。 性能优化 ➔ JIT&#xff08;即时编译…...

深度学习---Pytorch概览

一、PyTorch 是什么&#xff1f; 1. 定义与定位 开源深度学习框架&#xff1a;由 Facebook&#xff08;Meta&#xff09;AI 实验室开发&#xff0c;基于 Lua 语言的 Torch 框架重构&#xff0c;2017 年正式开源&#xff0c;主打动态计算图和易用性。核心优势&#xff1a;灵活…...

第33周JavaSpringCloud微服务 分布式综合应用

第33周JavaSpringCloud微服务 分布式综合应用 一、分布式综合应用概述 分布式知识体系内容广泛&#xff0c;主要包括分布式事务、分布式锁、RabbitMQ等消息中间件的应用以及跨域问题的解决。 1.1 课程重点内容介绍 分布式事务 &#xff1a;在大型项目中普遍存在&#xff0c;…...

Paramiko 完全指南

目录 Paramiko 概述核心功能与模块框架安装与依赖基础用法与案例详解 SSH 连接与命令执行密钥认证SFTP 文件传输交互式会话端口转发 高级功能与实战技巧常见问题与解决方案总结与资源推荐 1. Paramiko 概述 是什么&#xff1f; Paramiko 是一个纯 Python 实现的 SSHv2 协议库…...

夜莺监控V8(Nightingale)二进制部署教程(保姆级)

夜莺监控部署 前置工作 1. 部署好mysql 2. 部署好redis 3. 部署好prometheus夜莺压缩包下载 本教程基于Centos7系统下的二进制方式部署&#xff0c;先去官网进行压缩包下载 在系统创建/opt/n9etest目录,并将压缩包拖进目录 mkdir /opt/n9etest进入/opt/n9etest&#xff0…...

鸿蒙应用开发 知识点 官网快速定位表

ArkTS 语言介绍 ArkTS 语言介绍 基础入门 资源分类与访问 添加组件(基础组件) 显示图片 (Image) 按钮 (Button) 单选框 (Radio) 切换按钮 (Toggle) 进度条 (Progress) 视频播放 (Video) 使用文本 文本显示 (Text/Span) 文本输入 (TextInput/TextArea) 使用弹窗 使用弹…...

【神经网络与深度学习】两种加载 pickle 文件方式(joblib、pickle)的差异

引言 从深度学习应用到数据分析的多元化需求出发&#xff0c;Python 提供了丰富的工具和模块&#xff0c;其中 pickle 和 joblib 两种方式在加载数据文件方面表现尤为突出。不同场景对性能、兼容性以及后续处理的要求不尽相同&#xff0c;使得这两种方式各显优势。本文将通过深…...

quickbi finebi 测评(案例讲解)

quickbi & finebi 测评 国产BI中入门门槛比较低的有两个&#xff0c;分别是quickbi和finebi。根据我的经验通过这篇文章做一个关于这两款BI的测评文章。 quickbi分为个人版、高级版、专业版、私有化部署四种。这篇文章以quickbi高级版为例&#xff0c;对quickbi进行分享。…...

vue的生命周期 以及钩子

最早可以在created 时调用后端接口获取数据&#xff0c;因为beforecreated的时候 那个data 都还还是初始化出来 修改数据的时候触发 update 案例1&#xff1a;create 案例2:一进来页面获取搜索框焦点 echarts 饼图渲染 初始化dom后才去准备实例&#xff0c;所以必须要在dom之后…...

Mariadb 防火墙服务器和端口:mysql | 3306

Centos7 Mariadb 理解&#xff1a;Mariadb数据库就类似于我们生活中常见的Excel。 主要工作原理就是我们创造一个数据库其中创造一个数据表再在数据表中输入内容&#xff0c;分为三类。在详细点就是打开Excel&#xff08;数据库&#xff09;&#xff0c;我们在其中加入…...

爬虫学习笔记(二)--web请求过程

Web请求全过程&#xff08;重要&#xff09; 从输入完网址&#xff08;如输入百度网址&#xff09;到返回页面以及页面中的数据这一完整的过程发生了什么事情&#xff1f; 服务器端渲染 在服务器端直接把数据和html整合&#xff0c;统一返回给浏览器&#xff0c;在页面源代码…...

开发vue项目所需要安装的依赖包

在开发Vue项目时&#xff0c;通常需要安装以下几个核心依赖包&#xff1a;1、Vue CLI、2、Vue Router、3、Vuex、4、Axios。这些依赖包可以确保你的Vue项目拥有基础的功能和良好的开发体验。接下来&#xff0c;我们将详细介绍每个依赖包的作用、安装方法以及使用案例。 一、VUE…...

Java SE(4)——方法详解

1.方法的概念&使用 1.1 什么是方法&#xff1f; Java中的方法类似于C语言中的函数&#xff0c;是用于执行特定任务的代码块。 那么用方法组织起来的代码块和普通的代码相比有什么优势呢&#xff1f; 1.当代码规模较大且应用场景较为复杂时&#xff0c;方法能够模块化地组…...

网络安全实战指南:从安全巡检到权限维持的应急响应与木马查杀全(命令查收表)

目录 一、安全巡检的具体内容 1. 巡检的频率与目标是什么 2. 巡检的内容是什么以及巡检后如何加固 二、Windows环境下应急响应的主要流程 1. 流程概述及每个步骤详细解释 步骤1&#xff1a;隔离与遏制 步骤2&#xff1a;识别与分析 步骤3&#xff1a;清除与恢复 步骤4…...

Infrared Finance:Berachain 生态的流动性支柱

在加密市场中&#xff0c;用户除了参与一级和二级交易&#xff0c;还有一种低门槛参与的就是空投。从 2021 年 DeFi 成为主流开始&#xff0c;空投一直都是“以小搏大”的机会&#xff0c;通过参与项目早期的链上交互和任务以获取空投奖励&#xff0c;近几年已成为一种广受欢迎…...

Hadoop和Spark大数据挖掘与实战

1.概述 本节将系统讲解大数据分析的完整流程&#xff0c;包括数据采集、预处理、存储管理、分析挖掘与结果可视化等核心环节。与此同时&#xff0c;我们还将对主流数据分析工具进行横向对比&#xff0c;帮助读者根据实际需求选用最合适的工具&#xff0c;提升数据价值挖掘的效…...

TCP vs UDP:核心区别、握手过程与应用场景(附对比图)

&#x1f310; 引言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;是两大核心传输层协议。它们各有优劣&#xff0c;适用于不同场景。本文将用图文对比实战示例&#xff0c;帮你彻底理解两者的区别&#xff0…...

人工智能-深度学习之多层感知器

深度学习 任务任务1任务2任务3 机器学习的弊端多层感知器 &#xff08;MLP/人工神经网络&#xff09;MLP实现非线性分类Keras介绍与实战准备Keras or TensorflowKeras建立MLP模型 实战&#xff08;1&#xff09;: 建立MLP实现非线性二分类实战&#xff08;2&#xff09;: MLP实…...

Improving Deep Learning For Airbnb Search

解决问题 问题1: 解决推荐酒店与用户实际预定酒店价格存在偏差问题&#xff0c;实际预定比推荐要更便宜&#xff1a; 所以问题为是否更低价格的list更倾向于用户偏好&#xff0c;应该被优先推荐&#xff1f; 1. 该文通过数据分析与模型演进&#xff0c;将模型改造为item sco…...

多模态大型模型,实现以人为中心的精细视频理解

大家看完觉得有帮助记得点赞和关注&#xff01;&#xff01;&#xff01; 抽象 精细理解视频中人类的动作和姿势对于以人为中心的 AI 应用程序至关重要。在这项工作中&#xff0c;我们介绍了 ActionArt&#xff0c;这是一个细粒度的视频字幕数据集&#xff0c;旨在推进以人为中…...

向量数据库Milvus的部署与使用

Milvus介绍 Milvus是一个开源、高性能、高扩展性的向量数据库&#xff0c;Milvus可以用来存储文本、图像、音频等非结构化数据&#xff0c;本质上是用Embeddings将非结构化数据转换成能够捕捉其基本特征的数字向量&#xff0c;然后将这些向量存储在向量数据库中&#xff0c;从…...

1.文档搜索软件Everything 的使用介绍

Everything 是 Windows 文件搜索的效率天花板&#xff0c;通过灵活语法和极速响应&#xff0c;彻底告别「找文件焦虑」。 定位&#xff1a;一款专注于 极速文件名搜索 的 Windows 工具&#xff0c;免费且轻量&#xff08;安装包仅几 MB&#xff09;。 核心优势…...

2025系统架构师---论企业集成平台的技术与应用

摘要 本文探讨了企业集成平台的技术与应用,以某商业银行开发的绩效考核平台系统为例,分析了企业集成平台的基本功能及关键技术,并详细阐述了在表示集成、数据集成、控制集成和业务流程集成方面的应用和实施方式。通过异构系统之间的集成,绩效考核平台与其他系统实现了有机…...

STM32Cubemx-H7-16-FreeRTOS-1-创建工程,实现两个灯的基本亮灭

前言 裸机也是开发到一半快要结束了&#xff0c;接下来开始上操作系统&#xff0c;然后先能使用基本的&#xff0c;后面再讲理论。 Cubemx创建工程 基本打开生成就不说了&#xff0c;直接从界面开始 从这里开始吧 1.首先开启外部高速晶振 2.先这样选择 选择HSE时钟环&#xff…...

深入浅出限流算法(二):更平滑的滑动窗口

好的&#xff0c;接续上一篇关于固定窗口计数器的讨论&#xff0c;我们现在来看看它的改进版——滑动窗口算法&#xff0c;它旨在解决固定窗口那个恼人的“临界突变”问题。 在上一篇文章中&#xff0c;我们探讨了最简单的固定窗口计数器限流算法&#xff0c;并指出了它最大的缺…...

纷析云开源财务软件:基于Spring Boot的轻量化财务中台实践

一、技术架构与核心设计 全栈开源技术栈 后端框架&#xff1a;基于Spring Boot 3.x构建&#xff0c;集成MyBatis-Plus作为ORM层&#xff0c;支持JDK 17特性&#xff08;如虚拟线程并发处理&#xff09;&#xff0c;确保高吞吐与稳定性。 前端框架&#xff1a;采用Vue 3 TypeS…...

软考-软件设计师中级备考 5、数据结构 树和二叉树

1、树的基本概念 节点的度&#xff1a;节点拥有的子树数目。例如&#xff0c;若一个节点有 3 棵子树&#xff0c;其度为 3。树的度&#xff1a;树中节点的最大度数。如树中所有节点的度最大为 4&#xff0c;则树的度是 4。叶子节点&#xff1a;度为 0 的节点&#xff0c;也…...

php 需要学会哪些技术栈,掌握哪些框架

作为一个「野生」程序员&#xff0c;我的学习过程比较急功近利。 我记得自己写的第一个 PHP 程序是留言本。一上来对 PHP 一窍不通&#xff0c;所以直接去网上找了个留言本的源码&#xff0c;下载下来后先想办法让它在自己电脑上运行起来。通过这个过程掌握了 PHP 开发环境的搭…...