1. 我的模型结构是这样的:
self.model1 = nn.Sequential(
nn.Conv1d(1, 8, 1),
nn.BatchNorm1d(8),
nn.ReLU(),
nn.MaxPool1d(2),
nn.Conv1d(8, 32, 1),
nn.BatchNorm1d(32),
nn.ReLU(),
nn.MaxPool1d(2),
nn.Conv1d(32, 64, 1),
nn.BatchNorm1d(64),
nn.ReLU(),
nn.Conv1d(64, 64, 1),
nn.BatchNorm1d(64), # 加入批归一化
nn.ReLU(),
nn.Conv1d(64, 64, 1),
nn.BatchNorm1d(64), # 加入批归一化
nn.ReLU(),
nn.Dropout(0.9),
nn.ReLU(),
nn.Flatten()
)
2. 每一层数据形状的变化:
nn.Conv1d(1, 8, 1)
: 输入形状为(batch_size, 1, seq_len)
,输出形状为(batch_size, 8, seq_len)
(假设seq_len
是序列长度)。nn.BatchNorm1d(8)
: 保持形状不变,仍为(batch_size, 8, seq_len)
。nn.ReLU()
: 保持形状不变,仍为(batch_size, 8, seq_len)
。nn.MaxPool1d(2)
: 输出形状变为(batch_size, 8, seq_len // 2)
。
接下来,对于第二个卷积层:
nn.Conv1d(8, 32, 1)
: 输入形状为(batch_size, 8, seq_len // 2)
,输出形状为(batch_size, 32, seq_len // 2)
。nn.BatchNorm1d(32)
: 保持形状不变,仍为(batch_size, 32, seq_len // 2)
。nn.ReLU()
: 保持形状不变,仍为(batch_size, 32, seq_len // 2)
。nn.MaxPool1d(2)
: 输出形状变为(batch_size, 32, seq_len // 4)
。
对于第三个卷积层:
nn.Conv1d(32, 64, 1)
: 输入形状为(batch_size, 32, seq_len // 4)
,输出形状为(batch_size, 64, seq_len // 4)
。
接下来的几个卷积层、批归一化层和ReLU层都不会改变数据的形状,因此:
nn.Conv1d(64, 64, 1)
,nn.BatchNorm1d(64)
,nn.ReLU()
: 保持形状不变,仍为(batch_size, 64, seq_len // 4)
。nn.Conv1d(64, 64, 1)
,nn.BatchNorm1d(64)
,nn.ReLU()
: 保持形状不变,仍为(batch_size, 64, seq_len // 4)
。
然后,Dropout和ReLU层也不会改变形状:
nn.Dropout(0.9)
,nn.ReLU()
: 保持形状不变,仍为(batch_size, 64, seq_len // 4)
。
最后,Flatten层会将多维的输入一维化:
nn.Flatten()
: 输出形状变为(batch_size, 64 * seq_len // 4)
。
3. 修改意见
卷积层、批归一化层和最大池化层会依次作用于输入数据,并且每次操作后数据的形状都会发生变化。
-
第一个卷积层 (
nn.Conv1d(1, 8, 1)
):- 输入形状:假设是
(batch_size, 1, seq_len)
(其中batch_size
是批次大小,seq_len
是序列长度)。 - 输出形状:
(batch_size, 8, seq_len)
。因为卷积核的大小是1,所以输出特征图的宽度(seq_len
)保持不变,通道数从1增加到8。
- 输入形状:假设是
-
第一个批归一化层 (
nn.BatchNorm1d(8)
):- 输入形状:
(batch_size, 8, seq_len)
。 - 输出形状:
(batch_size, 8, seq_len)
。批归一化层不会改变数据的形状,只会对每个通道的数值进行归一化。
- 输入形状:
-
第一个ReLU激活函数:
- 输入/输出形状:
(batch_size, 8, seq_len)
。ReLU函数也不会改变数据的形状。
- 输入/输出形状:
-
第一个最大池化层 (
nn.MaxPool1d(2)
):- 输入形状:
(batch_size, 8, seq_len)
。 - 输出形状:
(batch_size, 8, seq_len // 2)
。最大池化层将每个通道的宽度减半(这里假设seq_len
是偶数,否则宽度会向下取整)。
- 输入形状:
-
第二个卷积层 (
nn.Conv1d(8, 32, 1)
):- 输入形状:
(batch_size, 8, seq_len // 2)
。 - 输出形状:
(batch_size, 32, seq_len // 2)
。通道数增加到32,宽度保持不变。
- 输入形状:
以此类推,每个卷积层都会增加输出通道数,而每个最大池化层都会将宽度减半。