Keras: Keras CNN with vector (or matrix) output ?

Created on 10 Dec 2018  路  7Comments  路  Source: keras-team/keras

Hi everyone. I have an issue i couldnt find on the internet. Also i tried a lot different models to find solution, but i coulndt create a model with vector output.

Let we have 2589 images with shape 1287 rows and 69 columns (Actually these arent images, but we can see as images.).

Also each images has an vector output with shape 1287x1. Actually each row of input has a output value range between 1-7. I mean, for example for a given image ouput is like [1,2,1,5,6,....1,7,3,5,4] (1287x1)

Here my codes :

X_train = train_input.reshape(train_input.shape[0],train_input.shape[1],train_input.shape[2],1)
Xs = X_train.shape

ys = y_train.shape

input_layer     = Input(shape=(Xs[1],Xs[2],Xs[3]))
conv1           = Conv2D(64,kernel_size=(3,3),padding="same",activation="relu")(input_layer)
pool1           = MaxPooling2D(pool_size=(2,2),padding="same")(conv1)
flat            = Flatten()(pool1)
hidden1         = Dense(100, activation='relu')(flat)
output_layer    = Dense(1287, activation='sigmoid')(hidden1)
model           = Model(inputs=input_layer, outputs=output_layer)

print Xs
print ys
print model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.fit(X_train,y_train,epochs=10)

Output image below :
image

Firstly i used softmax output with one-hot encoded class labels. But when i one-hot encoded classes, y_train becomes matrix.

How i can model Keras CNN with vector output like above ? I tried losses to "MSE", but im not sure its true.

I hope u can help me. Thanks very much

support

All 7 comments

First of all - if you've a binary problem (0\1) (hot-dog\not hot-dog) then you should use sigmoid

Since your classification problem contains more then 1 class you should use softmax activation because you have categorical classes (0,1,2,3 ...) (make sure you offset the classes to be 0-6 and not 1-7)

Then you have to understand the fundamentals of what you're trying to do, that is - for each of the 1287 examples you've to assign a Probability of being a specific class (in case of 7 categories your final output should be at shape of (None, 1287, 7) - so your last Dense filter should have 1287*7 filters and then you need to reshape it to (None, 1287, 7).

Also, when your output is not a single prediction, but contains many classes you have to set your model to do timestep-wise sample in the compilation, check here: https://keras.io/models/model/#compile

anyway, I've created a code for you that executes this model:

import keras
from keras import backend as K
from keras.layers import Conv2D, Input, MaxPooling2D, Flatten, Dense, Reshape
import numpy as np
from keras.models import Model
output_nodes = 1287
n_classes = 7
X_train = np.random.random((100, 1287, 69, 1)).astype('float32')

y_train = np.random.randint(0, n_classes, size=(100, output_nodes, 1)).astype('float32')

Xs = X_train.shape

ys = y_train.shape

input_layer     = Input(shape=(Xs[1],Xs[2],Xs[3]))
conv1           = Conv2D(16,3,padding="same",activation="relu")(input_layer)
pool1           = MaxPooling2D(pool_size=(2,2),padding="same")(conv1)
flat            = Flatten()(pool1)
hidden1         = Dense(10, activation='relu')(flat)
output_layer    = Dense(output_nodes*n_classes, activation='softmax')(hidden1)
output_reshape  = Reshape((output_nodes, n_classes))(output_layer)
model           = Model(inputs=input_layer, outputs=output_reshape)
print(model.summary())
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', sample_weight_mode='temporal')
model.fit(X_train,y_train,batch_size=2,epochs=10)

You don't have to do one-hot encoding to train multi-class classification model. For this purpose you can use "sparse_categorical_crossentropy" and it'll do it for you.

P.S. your model is VERY computationally expensive and has 145M parameters, and it will almost certainly over-fit. I suggest you to remove the "Dense" layers and change them with Conv2 layers with stride=(1,3) and padding='valid' so you'll end-up with output shape of (1287,7)

@Golbstein thanks very much for reply. I'll try this model . But can i ask a small question. When i predict test data, this model gives me probabality of each row im i right ? I mean when i use model.predict(Xtest[:10]) , this returns me an array with shape 10x1287x7? And each 1287x7 has probablities ?

@HerocypheR When i predict test data, this model gives me probabality of each row im i right ? I mean when i use model.predict(Xtest[:10]) , this returns me an array with shape 10x1287x7? And each 1287x7 has probablities ?

Yes. And in order to get the predicted labels you should arg-max it:

preds = model.predict(Xtest[:10])
pred_labels = np.argmax(preds, axis=-1)

@Golbstein Thanks very much, im greateful. Im closing the issue. its solved.

please share the correct version of below codes for (output_nodes x n_classes) matrix

input_layer = Input(shape=(Xs[1],Xs[2],Xs[3]))
conv1 = Conv2D(16,3,padding="same",activation="relu")(input_layer)
pool1 = MaxPooling2D(pool_size=(2,2),padding="same")(conv1)
flat = Flatten()(pool1)
hidden1 = Dense(10, activation='relu')(flat)
output_layer = Dense(output_nodes*n_classes, activation='softmax')(hidden1)
output_reshape = Reshape((output_nodes, n_classes))(output_layer)
model = Model(inputs=input_layer, outputs=output_reshape)

@Golbstein

please share the correct version of below codes for (output_nodes x n_classes) matrix

input_layer = Input(shape=(Xs[1],Xs[2],Xs[3]))
conv1 = Conv2D(16,3,padding="same",activation="relu")(input_layer)
pool1 = MaxPooling2D(pool_size=(2,2),padding="same")(conv1)
flat = Flatten()(pool1)
hidden1 = Dense(10, activation='relu')(flat)
output_layer = Dense(output_nodes*n_classes, activation='softmax')(hidden1)
output_reshape = Reshape((output_nodes, n_classes))(output_layer)
model = Model(inputs=input_layer, outputs=output_reshape)

@Golbstein
please share the correct version of below codes for (output_nodes x n_classes) matrix without one hot encoding

input_layer = Input(shape=(Xs[1],Xs[2],Xs[3]))
conv1 = Conv2D(16,3,padding="same",activation="relu")(input_layer)
pool1 = MaxPooling2D(pool_size=(2,2),padding="same")(conv1)
flat = Flatten()(pool1)
hidden1 = Dense(10, activation='relu')(flat)
output_layer = Dense(output_nodes*n_classes, activation='softmax')(hidden1)
output_reshape = Reshape((output_nodes, n_classes))(output_layer)
model = Model(inputs=input_layer, outputs=output_reshape)

Was this page helpful?
0 / 5 - 0 ratings