Keras 独立卷积一维通道,[样本,时间步长,特征],风力涡轮机数据集
Keras convolution 1D channel indepently, [samples,timesteps,features] , wind turbine dataset
我正在处理具有规则矩阵格式的风力涡轮机数据集:[ row:datetime , column:features]
但我想用卷积捕捉每个特征的进展,就像在 LSTM 中完成的那样。因此,我生成了一个具有以下维度的新数据集:
[日期时间,15 个时间步长,128 个特征]:每个原始日期时间行现在有 15 个寄存器串联(t-0,t-1,...,t-14)用于每个特征。
我的计划是分别使用大小为 1x5 且步长为 5 的内核在每个特征(通道)的时间步维度中进行卷积。为每个 DateTime(批次)获取 128 个特征中长度为 5 的 3 个过滤器,输出形状为 (None,3,128).
然后我将最大池化应用于之前的第二维 (3) 结果,以获得 "the most important convoluted timestep" 预期的输出大小:(None,1,128)
最后我连接了一个密集层进行二元分类。
目前在keras中实现的网络架构如下:
model.add( Conv1D(padding = 'valid',filters = nfeatures,strides = 5,kernel_size = 5,
activation = 'relu',input_shape = (timesteps,nfeatures)) )
model.add( MaxPooling1D() )
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
问题是当我检查第一层 (conv1d) 的权重时,权重具有以下维度:[5,128,128] 和偏差 [128]。
预期的权重格式是:[5,1,128] 为什么是 5x128x128? ,我只想要每个 feature/channel.
的 5 个权重(内核大小)
谢谢!
标准卷积滤波器:
为了获得更好的结果,神经网络很少单独考虑一个特征,相反,它们促进特征之间的相关性以提取更智能的结果。
这就是为什么标准的卷积滤波器形状是:
(width, input_features, output_features)
在这个卷积中,所有的输入特征都被认为是创建新的输出特征。
如何完全个性化特征?
warning: this uses the same exact filter for all features (you may want one individual filter per feature, then see the next answer)
您可以对数据重新排序,使特征成为一个主要组,并使每个组只有一个特征和过滤器。
然后可以与 TimeDistributed
层并行处理这些组。
model = Sequential()
#reordering data and adding 1 dummy feature per group
model.add(Permute((2,1), input_shape = (timesteps,nfeatures))) #(batch, feat, steps)
model.add(Lambda(lambda x: K.expand_dims(x))) #(batch, feat, steps, 1)
#applying the 1 filter convolution for each group
model.add(TimeDistributed(Conv1D(padding = 'valid',filters = 1,strides = 5,
kernel_size = 5, activation = 'relu')))
model.add( TimeDistributed(MaxPooling1D()) )
#restoring to (batch,features)
model.add(Reshape((nfeatures,)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
老实说,您的模型使用标准卷积会更强大,但您可能有特殊原因这样做。
每个特征一个单独的过滤器
这需要更多的工作。我们将需要一个实现 depthwise_conv1d 的自定义层(Keras 不提供),或者我们创建 128 个单独的 conv1D 层和 1 个过滤器(更容易)。
使用第二种方法(多个转换层),我们将需要一个功能性 API 模型来制作并行分支。
from keras.model import Model
#function to split the input in multiple outputs
def splitter(x):
return [x[:,:,i:i+1] for i in range(nfeatures)]
#model's input tensor
inputs = Input((timesteps,nfeatures))
#splitting in 128 parallel tensors - 128 x (batch,15,1)
multipleFeatures = Lambda(splitter)(inputs)
#applying one individual convolution on each parallel branch
multipleFeatures = [
Conv1D(padding = 'valid',filters = 1,strides = 5, kernel_size = 5)(feat)
for feat in multipleFeatures ]
#joining the branches into (batch, 3, 128)
joinedOutputs = Concatenate()(multipleFeatures)
joinedOutputs = Activation('relu')(joinedOutputs)
outputs = MaxPooling1D()(joinedOutputs)
outputs = Lambda(lambda x: K.squeeze(x,axis=1))(outputs)
outputs = Dropout(0.5)(outputs)
outputs = Dense(1, activation='sigmoid')(outputs)
model = Model(inputs,outputs)
我正在处理具有规则矩阵格式的风力涡轮机数据集:[ row:datetime , column:features]
但我想用卷积捕捉每个特征的进展,就像在 LSTM 中完成的那样。因此,我生成了一个具有以下维度的新数据集:
[日期时间,15 个时间步长,128 个特征]:每个原始日期时间行现在有 15 个寄存器串联(t-0,t-1,...,t-14)用于每个特征。
我的计划是分别使用大小为 1x5 且步长为 5 的内核在每个特征(通道)的时间步维度中进行卷积。为每个 DateTime(批次)获取 128 个特征中长度为 5 的 3 个过滤器,输出形状为 (None,3,128).
然后我将最大池化应用于之前的第二维 (3) 结果,以获得 "the most important convoluted timestep" 预期的输出大小:(None,1,128)
最后我连接了一个密集层进行二元分类。
目前在keras中实现的网络架构如下:
model.add( Conv1D(padding = 'valid',filters = nfeatures,strides = 5,kernel_size = 5,
activation = 'relu',input_shape = (timesteps,nfeatures)) )
model.add( MaxPooling1D() )
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
问题是当我检查第一层 (conv1d) 的权重时,权重具有以下维度:[5,128,128] 和偏差 [128]。
预期的权重格式是:[5,1,128] 为什么是 5x128x128? ,我只想要每个 feature/channel.
的 5 个权重(内核大小)谢谢!
标准卷积滤波器:
为了获得更好的结果,神经网络很少单独考虑一个特征,相反,它们促进特征之间的相关性以提取更智能的结果。
这就是为什么标准的卷积滤波器形状是:
(width, input_features, output_features)
在这个卷积中,所有的输入特征都被认为是创建新的输出特征。
如何完全个性化特征?
warning: this uses the same exact filter for all features (you may want one individual filter per feature, then see the next answer)
您可以对数据重新排序,使特征成为一个主要组,并使每个组只有一个特征和过滤器。
然后可以与 TimeDistributed
层并行处理这些组。
model = Sequential()
#reordering data and adding 1 dummy feature per group
model.add(Permute((2,1), input_shape = (timesteps,nfeatures))) #(batch, feat, steps)
model.add(Lambda(lambda x: K.expand_dims(x))) #(batch, feat, steps, 1)
#applying the 1 filter convolution for each group
model.add(TimeDistributed(Conv1D(padding = 'valid',filters = 1,strides = 5,
kernel_size = 5, activation = 'relu')))
model.add( TimeDistributed(MaxPooling1D()) )
#restoring to (batch,features)
model.add(Reshape((nfeatures,)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
老实说,您的模型使用标准卷积会更强大,但您可能有特殊原因这样做。
每个特征一个单独的过滤器
这需要更多的工作。我们将需要一个实现 depthwise_conv1d 的自定义层(Keras 不提供),或者我们创建 128 个单独的 conv1D 层和 1 个过滤器(更容易)。
使用第二种方法(多个转换层),我们将需要一个功能性 API 模型来制作并行分支。
from keras.model import Model
#function to split the input in multiple outputs
def splitter(x):
return [x[:,:,i:i+1] for i in range(nfeatures)]
#model's input tensor
inputs = Input((timesteps,nfeatures))
#splitting in 128 parallel tensors - 128 x (batch,15,1)
multipleFeatures = Lambda(splitter)(inputs)
#applying one individual convolution on each parallel branch
multipleFeatures = [
Conv1D(padding = 'valid',filters = 1,strides = 5, kernel_size = 5)(feat)
for feat in multipleFeatures ]
#joining the branches into (batch, 3, 128)
joinedOutputs = Concatenate()(multipleFeatures)
joinedOutputs = Activation('relu')(joinedOutputs)
outputs = MaxPooling1D()(joinedOutputs)
outputs = Lambda(lambda x: K.squeeze(x,axis=1))(outputs)
outputs = Dropout(0.5)(outputs)
outputs = Dense(1, activation='sigmoid')(outputs)
model = Model(inputs,outputs)