Skip to content

Convolution Layer error #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Reichenbachian opened this issue Aug 2, 2017 · 9 comments
Open

Convolution Layer error #79

Reichenbachian opened this issue Aug 2, 2017 · 9 comments
Labels

Comments

@Reichenbachian
Copy link

Reichenbachian commented Aug 2, 2017

On a deep cnn, I'm getting the error "Incompatible combination of dilation_rate with strides."
The model works without problems within keras. Is padding not implemented? Is there a workaround?

Architecture

model = Sequential()
model.add(Conv1D(32, 64, strides=2, padding='same', input_shape=inputshape))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(pool_size=8))

model.add(Conv1D(64, 32, strides=2, padding='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling1D(pool_size=8))

model.add(Conv1D(128, 16, strides=2, padding='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))

model.add(Conv1D(256, 8, strides=2, padding='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))

model.add(Flatten())
model.add(Dense(128))
model.add(Dropout(p=0.5))

Tensorflow==1.1.0
Keras==2.0.4

@Reichenbachian
Copy link
Author

Reichenbachian commented Aug 3, 2017

I think I see the problem. It's coming from

 if (dilation_rate !== 1 && strides !== 1) {
      // Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1
      // https://keras.io/layers/convolutional/#conv1d
      throw new Error(`${this.name} [Conv1D layer] Incompatible combination of dilation_rate with strides.`)
    }

But I think that the line dilation_rate !== 1 && strides !== 1 isn't correct.

The keras documentation says

dilation_rate: an integer or tuple/list of a single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.

It's a confusing sentence, but I think it means this...
(dilation_rate !== 1 && strides == 1) || (dilation_rate == 1 && strides !== 1)
I'll branch out and try it.

@transcranial
Copy link
Owner

@Reichenbachian Based on your architecture, shouldn't dilation_rate be 1 (default)? In which case, why is it throwing this error at all? Can you check your model architecture definition and see what dilation_rate for the Conv1D layers actually are?

Btw, I think the original conditional is correct; for strides/dilation_rate pairs, we should have the following:

1/1 -> no error
1/2 -> no error
2/1 -> no error
2/2 -> error

@Reichenbachian
Copy link
Author

Yeah. I reread your condition. I think the condition is correct.
Which means that at some point before then, those numbers must have been changed.
In the model.json file, all the convolution layers are

            "strides": [2],
            "dilation_rate": [1],

I tried printing the values before the error was thrown, but I'm unable to build keras-js on my computer. (Working on that now, but separate error).

@transcranial
Copy link
Owner

@Reichenbachian
Copy link
Author

I got it building.
I put in

    if (dilation_rate !== 1 && strides !== 1) {
      // Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1
      // https://keras.io/layers/convolutional/#conv1d
      console.log("Dilation " + dilation_rate + " Strides" + strides + " " + (dilation_rate !== 1 && strides !== 1) + " " + (dilation_rate !== 1) + " " + (strides !== 1));
      console.log(typeof dilation_rate + " " + typeof strides)
      throw new Error(`${this.name} [Conv1D layer] Incompatible combination of dilation_rate with strides.`)
    }

It outputted Dilation 1 Strides2 true true true. Which is very confusing. I'm wondering if the types are screwed up. Checking now.

@Reichenbachian
Copy link
Author

Ah, so they're tuples. Just saw your response. I'll write a patch for now.

@Reichenbachian
Copy link
Author

Added

    if (Array.isArray(strides)) {
      this.strides = strides[0]
    }
    if (Array.isArray(dilation_rate)) {
      this.dilation_rate = dilation_rate[0]
    }

    if (Array.isArray(kernel_size)) {
      this.kernel_size = kernel_size[0]
    }

and

    var dilation_rate_temp = this.dilation_rate;
    const conv2dAttrs = {
      filters,
      kernel_size: [this.kernel_size, 1],
      strides: [this.strides, 1],
      padding,
      data_format: 'channels_first',
      dilation_rate_temp,
      activation,
      use_bias
    }
    this._conv2dAttrs = conv2dAttrs
    this._conv2d = new Conv2D(Object.assign(conv2dAttrs, { gpu: attrs.gpu }))
  }

It loaded without errors.

@Nollde
Copy link

Nollde commented Dec 14, 2017

Hi all, is this issue fixed right now?
I cloned the repo the day before yesterday and got the same error for Conv1D:

[Conv1D layer: conv1d_1] Incompatible combination of dilation_rate with strides.

I am not sure if it is exactly the same problem, it would be awesome if we could fix this.

I started by analyzing the shapes of the Strides and Dilation (which are now named h and u?):

console.log("[UO] Strides=" + h)
console.log("[UO] Strides isArray=" + Array.isArray(h))
console.log("[UO] DilationRate=" + u)
console.log("[UO] DilationRate isArray=" + Array.isArray(u))
console.log("[UO] (1 !== h)=" + (1 !== h))
console.log("[UO] (1 !== u)=" + (1 !== u))

prints me:

[Log] [UO] Strides=1 (keras.min.js, line 8762)
[Log] [UO] Strides isArray=true (keras.min.js, line 8763)
[Log] [UO] DilationRate=1 (keras.min.js, line 8764)
[Log] [UO] DilationRate isArray=true (keras.min.js, line 8765)
[Log] [UO] (1 !== h)=true (keras.min.js, line 8766)
[Log] [UO] (1 !== u)=true (keras.min.js, line 8767)

which basically is the problem as far as I understood.

I first tried @Reichenbachian 's fix and added:

if (Array.isArray(h)) {
    h =h[0]
}
if (Array.isArray(u)) {
    u = u[0]
}

But this throws me:

Error: cwise: Arrays do not all have the same shape!

But there my knowledge ends and I am not sure if that is the problem I want (need) to solve or just a follow up mistake. It would be great if we could work on this.

Below some additional information regarding the surroundings:


My model architecture:

model = Sequential([
            Conv1D(3, 3, input_shape=(1024, 1,)),
            Conv1D(1, 3),
            Flatten(),
            Dense(32),
            Activation('relu'),
            Dense(13),
            Activation('softmax'),
        ])

The data flowing through has the shape (4000, 1024, 1).

Training is done within: this Docker image.
With the version before the latest:
Keras Version: 2.0.2
Tensorflow Version: 1.0.1

Data is loaded via jQuery:

$.getJSON( data_path + "spectrum.json", function( json ) {
  data = json.spectrum_00
 });

with spectrum.json looking like:

{"spectrum_00": [[6379], [2568], [2089], [1715], ...]}

see model.bin attached
model.bin.zip

@Reichenbachian
Copy link
Author

I think I may have fixed it on my local machine and not submitted a PR. I'll do that today.

Reichenbachian added a commit to Reichenbachian/keras-js that referenced this issue Dec 14, 2017
Finally pushing patch. I haven't run it, so make sure that it works before merging. I bring it up again, as the dead issue thread was brought back to life - transcranial#79 .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants