Search code examples
tensorflowregressionorientationsupervised-learningestimation

is it possible to have a regression model with more than one output?


I am working with a CNN regression model using Tensorflow. I want to know is it possible to estimate more than one data from my dataset using regression? (In other words, I want to estimate the position(x,y,z) and rotation(pitch,yaw,roll) of shoulder and elbow of the human body using head and both hands positions and rotations)

So, the output of my model should be like 6 values for every joint. (for ex: for elbow) and also this is a sample of my code: (I used tf.session to train the model)

# define placeholder for inputs to network
xs = tf.placeholder(tf.float32, [None, 42], name ='input_node')
ys = tf.placeholder(tf.float32, [None, 1]) 
keep_prob = tf.placeholder(tf.float32) 

#Network computations and Layers
x_image = tf.reshape(xs, [-1, 3, 3,1])  
## conv1 layer
W_conv1 = weight_func([3, 3, 1, 32])  
b_conv1 = bias_func([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) 
h_pool1 = max_pool_2x2(h_conv1)     
# h_drop1 = tf.nn.dropout(h_conv1, keep_prob) 

## conv2 layer
W_conv2 = weight_func([3, 3, 32, 64])
b_conv2 = bias_func([64])
h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)
# h_drop2 = tf.nn.dropout(h_conv2, keep_prob)

## conv3 layer
W_conv3 = weight_func([3, 3, 64, 128])  
b_conv3 = bias_func([128])
h_conv3 = tf.nn.relu(conv2d(h_conv2, W_conv3) + b_conv3)  
# h_drop3 = tf.nn.dropout(h_conv3, keep_prob)  

## conv4 layer 
W_conv4 = weight_func([3, 3, 128,256]) 
b_conv4 = bias_func([256])
h_conv4 = tf.nn.relu(conv2d(h_conv3, W_conv4) + b_conv4) 
# h_drop4 = tf.nn.dropout(h_conv4, keep_prob)  

## fc1 layer 
W_fc1 = weight_func([3 * 3 * 256, 2304])
b_fc1 = bias_func([256])

h_pool2_flat = tf.reshape(h_conv4, [-1, 3* 3 * 256]) 
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 

# fc2 layer ## full connection
W_fc2 = weight_func([2304, 1])
b_fc2 = bias_func([1])

prediction = tf.add(tf.matmul(h_fc1_drop, W_fc2) , b_fc2, name= 'output_node')
cross_entropy = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), reduction_indices=[1]))

sess = tf.Session()
train_step = tf.train.AdamOptimizer(0.01).minimize(cross_entropy)
sess.run(tf.global_variables_initializer())
init=tf.global_variables_initializer()
for i in range(50):
  sess.run([train_step] , feed_dict = {xs: train_x, ys: train_y, keep_prob: 0.7})
prediction_value = sess.run(prediction, feed_dict={xs: test_x, ys: test_y, keep_prob: 1.0})`

Solution

  • Sure, just create a second output. Unfortunately I cannot tell you how to do this for Tensorflow 1.14 but in TF2.0 as I did in another model:

    output_categorical = layer.Dense(5, activation="softmax")(dense_layer_out_cat)
    output_continuus = layer.Dense(1, activation="sigmoid")(dense_layer_out_con)
    model = tf.keras.Model(inputs=[layer_input_categorical, layer_input_categorical_2, layer_input_continuus], \
                           outputs=[output_categorical, output_continuus])
    model.compile(optimizer="Nadam", loss=["mse","sparse_categorical_crossentropy"])
    

    In this piece of code you can see a model, outputting one regression value and one categorical value (for a classification). Thats it at the end, no big magic. Just create two output layers with a sigmoid activation, tell the model to use both layers as output, define two! loss functions (which might be the same 6 times, if you go for 6 regressions) and thats it. Having multiple outputs, also means, that you need as many y-label value as outputs of course, so keep that in mind during data preparation.