7

I have a problem with my current attempt to build a sequential model for time series classification in Keras. I want to work with channels_first data, because it is more convenient from a perprocessing perspective (I only work with one channel, though). This works fine for the Convolution1D layers I'm using, as I can specify data_sample='channels_first', but somehow this won't work for Maxpooling1D, which doesn't have this option as it seems.

The model I want to build is structured as follows:

model = Sequential()
model.add(Convolution1D(filters=16, kernel_size=35, activation='relu', input_shape=(1, window_length), data_format='channels_first'))
model.add(MaxPooling1D(pool_size=5)
model.add(Convolution1D(filters=16, kernel_size=10, activation='relu', data_format='channels_first'))
[...] #several other layers here

With window_length = 5000 I get the following summary after all three layers are added:

_________________________________________________________________
Layer (type)                 Output Shape              Param #  
=================================================================
conv1d_1 (Conv1D)           (None, 32, 4966)          1152     
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 4, 4966)           0        
_________________________________________________________________
conv1d_2 (Conv1D)           (None, 16, 4957)          656      
=================================================================
Total params: 1,808
Trainable params: 1,808
Non-trainable params: 0

Now, I wonder if this is correct, as I would expect the third dimension (i.e. the number of neurons in a feature map) and not the second (i.e. the number of filters) to be reduced by the pooling layer? As I see it, MaxPooling1D does not recognize the channels_first ordering and while the Keras documentation says there exists a keyword data_format for MaxPooling2D, there's no such keyword for MaxPooling1D.

I tested the whole setup with a channels_last data format, and it worked as I expected. But since the conversion from channels_first to channels_last takes quite some time for me, I'd really rather have this work with channels_first. And I have the feeling that I'm simply missing something.

If you need any more information, let me know.

today
  • 32,602
  • 8
  • 95
  • 115
Gretel_f
  • 175
  • 6
  • Reading the [source code](https://github.com/keras-team/keras/blob/master/keras/layers/pooling.py#L57), it looks like you can just pass `data_format='channels_first'`. – fractals Aug 22 '18 at 07:58
  • @HSK When i try to do so (`model.add(MaxPooling1D(pool_size=8, data_format='channels_first')`) i get an error `TypeError: ('Keyword argument not understood:', 'dataformat')`. Am I missing something? – Gretel_f Aug 22 '18 at 08:00
  • Sorry, I misread the code; reading up to where `class Layer` is actually defined, it does not accept `data_format` as one of the keyword arguments. I thought it accepts `data_format` as it calls `K.pool2d(inputs, pool_size, strides, padding, data_format, pool_mode='max')`, but the rest of the source code assumes everything is in `channels_last`. Unfortunately, it looks like you would have to implement this yourself if you want to use `channels_first` if I didn't miss something. – fractals Aug 22 '18 at 08:10
  • No harm done. I tried it out before, because it was the natural thing to try first. But it's good to know, that I'm not the only one confused by this. – Gretel_f Aug 22 '18 at 08:13
  • 1
    I made a PR regarding this and is now merged. https://github.com/keras-team/keras/pull/10966 – fractals Aug 23 '18 at 03:28

1 Answers1

4

Update: as mentioned by @HSK in the comments, the data_format argument is now supported in MaxPooling layers as a result of this PR.


Well, one alternative is to use the Permute layer (and remove the channels_first for the second conv layer):

model = Sequential()
model.add(Convolution1D(filters=16, kernel_size=35, activation='relu', input_shape=(1, 100), data_format='channels_first'))
model.add(Permute((2, 1)))
model.add(MaxPooling1D(pool_size=5))
model.add(Convolution1D(filters=16, kernel_size=10, activation='relu'))

model.summary()

Model summary:

Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_7 (Conv1D)            (None, 16, 66)            576       
_________________________________________________________________
permute_1 (Permute)          (None, 66, 16)            0         
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 13, 16)            0         
_________________________________________________________________
conv1d_8 (Conv1D)            (None, 4, 16)              2096      
=================================================================
Total params: 2,672
Trainable params: 2,672
Non-trainable params: 0
_________________________________________________________________
today
  • 32,602
  • 8
  • 95
  • 115