keras-js
keras-js copied to clipboard
NaN Output
I have a CNN with architecture as shown below.
model = Sequential()
model.add(Conv1D(32, 64, strides=2, padding='same', input_shape=(19200, 1))
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))
model.add(Dense(2, name = '...'))
model.add(Activation('softmax'))
model.compile(loss='categorical_cross_entropy',
optimizer='adam',
metrics='')
The output of the model is [NaN, NaN] regardless of import. The only error output I can find is in the promise stack trace.
Error
at Promise.longStackTracesCaptureStackTrace [as _captureStackTrace] (http://127.0.0.1:8383/dist/keras.js:22373:19)
at Promise._then (http://127.0.0.1:8383/dist/keras.js:24303:17)
at Promise.then (http://127.0.0.1:8383/dist/keras.js:24196:17)
at <anonymous>:1:105
I have broken it down into the simplest situation possible and am still getting the error. Any suggestions as to what could be causing this?
The model seems to output correctly, with the output of model.modelDAG being
activation_1: inbound: ["batch_normalization_1"]
layerClass: "Activation"
name: "activation_1"
outbound: ["max_pooling1d_1"]
__proto__: Object
activation_2: {layerClass: "Activation", name: "activation_2", inbound: Array(1), outbound: Array(1)}
activation_3: {layerClass: "Activation", name: "activation_3", inbound: Array(1), outbound: Array(1)}
activation_4: {layerClass: "Activation", name: "activation_4", inbound: Array(1), outbound: Array(1)}
batch_normalization_1: {layerClass: "BatchNormalization", name: "batch_normalization_1", inbound: Array(1), outbound: Array(1)}
batch_normalization_2: {layerClass: "BatchNormalization", name: "batch_normalization_2", inbound: Array(1), outbound: Array(1)}
batch_normalization_3: {layerClass: "BatchNormalization", name: "batch_normalization_3", inbound: Array(1), outbound: Array(1)}
batch_normalization_4: {layerClass: "BatchNormalization", name: "batch_normalization_4", inbound: Array(1), outbound: Array(1)}
conv1d_1: {layerClass: "Conv1D", name: "conv1d_1", inbound: Array(1), outbound: Array(1)}
conv1d_2: {layerClass: "Conv1D", name: "conv1d_2", inbound: Array(1), outbound: Array(1)}
conv1d_3: {layerClass: "Conv1D", name: "conv1d_3", inbound: Array(1), outbound: Array(1)}
conv1d_4: {layerClass: "Conv1D", name: "conv1d_4", inbound: Array(1), outbound: Array(1)}
dense_1: {layerClass: "Dense", name: "dense_1", inbound: Array(1), outbound: Array(1)}
dropout_1: {layerClass: "Dropout", name: "dropout_1", inbound: Array(1), outbound: Array(1)}
flatten_1: {layerClass: "Flatten", name: "flatten_1", inbound: Array(1), outbound: Array(1)}
gender_cnn_activation: {layerClass: "Activation", name: "gender_cnn_activation", inbound: Array(1), outbound: Array(0)}
gender_cnn_output: {layerClass: "Dense", name: "gender_cnn_output", inbound: Array(1), outbound: Array(1)}
input: {layerClass: "InputLayer", name: "input", inbound: Array(0), outbound: Array(1)}
max_pooling1d_1: {layerClass: "MaxPooling1D", name: "max_pooling1d_1", inbound: Array(1), outbound: Array(1)}
max_pooling1d_2: {layerClass: "MaxPooling1D", name: "max_pooling1d_2", inbound: Array(1), outbound: Array(1)}
Isolated the problem layer using brute force. It's the MaxPooling1D layer. Probably #79, repeated.
Found the bug! It was same as #79. I rewrote the _Pooling1D.js It no longer outputs NaN. Here are the changes...
/**
* _Pooling1D layer class
*/
export default class _Pooling1D extends Layer {
/**
* Creates a _Pooling1D layer
*/
constructor(attrs = {}) {
super(attrs)
this.layerClass = '_Pooling1D'
const { pool_size = 2, strides = null, padding = 'valid' } = attrs
if (Array.isArray(pool_size)) {
this.poolSize = pool_size[0]
} else {
this.poolSize = pool_size
}
if (Array.isArray(strides)) {
this.strides = strides[0]
} else if(strides === null) {
this.strides = this.poolSize
} else {
this.strides = strides
}
// this.strides = strides === null ? this.poolSize : strides
this.padding = padding
// default pooling function
// can be `max` or `average`
this.poolingFunc = 'max'
}