I am a newcomer to convolutional neural networks and have the following question: Is there a way to create a CNN with multiple outputs, including 10 for classification and two more for regression with Keras in Python?
I am a newcomer to convolutional neural networks and have the following question: Is there a way to create a CNN with multiple outputs, including 10 for classification and two more for regression with Keras in Python?
Yes it's possible. You can do this by using the Functional API or the Subclassing API (see example below). I think this short example where I did both regression and classification on the Iris dataset could help you. It's not a CNN, but you'd just have to change the layers and the dataset. Most of the rest remains the same.
You can see that there are 2 targets, one for classification and the other one regression. There are also two different losses, of course.
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from sklearn.datasets import load_iris
from functools import partial
iris, target = load_iris(return_X_y=True)
X = iris[:, :3]
y = iris[:, 3]
z = target
onehot = partial(tf.one_hot, depth=3)
dataset = tf.data.Dataset.from_tensor_slices((X, y, z)).shuffle(150)
train_ds = dataset.take(120).\
shuffle(10).batch(8).\
map(lambda a, b, c: (a, b, onehot(c)))
test_ds = dataset.skip(120).take(30).\
shuffle(10).batch(8).\
map(lambda a, b, c: (a, b, onehot(c)))
next(iter(train_ds))
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.d0 = Dense(64, activation='relu')
self.d1 = Dense(128, activation='relu')
self.d2 = Dense(1)
self.d3 = Dense(3)
def call(self, x, training=None, **kwargs):
x = self.d0(x)
x = self.d1(x)
a = self.d2(x)
b = self.d3(x)
return a, b
model = MyModel()
loss_obj_reg = tf.keras.losses.MeanAbsoluteError()
loss_obj_cat = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
loss_reg_train = tf.keras.metrics.Mean(name='regression loss')
loss_cat_train = tf.keras.metrics.Mean(name='categorical loss')
loss_reg_test = tf.keras.metrics.Mean(name='regression loss')
loss_cat_test = tf.keras.metrics.Mean(name='categorical loss')
train_acc = tf.keras.metrics.CategoricalAccuracy()
test_acc = tf.keras.metrics.CategoricalAccuracy()
@tf.function
def train_step(inputs, y_reg, y_cat):
with tf.GradientTape() as tape:
pred_reg, pred_cat = model(inputs, training=True)
reg_loss = loss_obj_reg(y_reg, pred_reg)
cat_loss = loss_obj_cat(y_cat, pred_cat)
gradients = tape.gradient([reg_loss, cat_loss], model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
loss_reg_train(reg_loss)
loss_cat_train(cat_loss)
train_acc(y_cat, pred_cat)
@tf.function
def test_step(inputs, y_reg, y_cat):
pred_reg, pred_cat = model(inputs, training=False)
reg_loss = loss_obj_reg(y_reg, pred_reg)
cat_loss = loss_obj_cat(y_cat, pred_cat)
loss_reg_test(reg_loss)
loss_cat_test(cat_loss)
test_acc(y_cat, pred_cat)
for epoch in range(250):
loss_reg_train.reset_states()
loss_cat_train.reset_states()
loss_reg_test.reset_states()
loss_cat_test.reset_states()
train_acc.reset_states()
test_acc.reset_states()
for xx, yy, zz in train_ds:
train_step(xx, yy, zz)
for xx, yy, zz in test_ds:
test_step(xx, yy, zz)
template = 'Epoch {:3} ' \
'MAE {:5.3f} TMAE {:5.3f} ' \
'Entr {:5.3f} TEntr {:5.3f} ' \
'Acc {:7.2%} TAcc {:7.2%}'
print(template.format(epoch+1,
loss_reg_train.result(),
loss_reg_test.result(),
loss_cat_train.result(),
loss_cat_test.result(),
train_acc.result(),
test_acc.result()))
Epoch 239 MAE 0.137 TMAE 0.127 Entr 0.097 TEntr 0.044 Acc 97.50% TAcc 100.00%
Epoch 240 MAE 0.128 TMAE 0.140 Entr 0.110 TEntr 0.075 Acc 95.83% TAcc 96.67%
Epoch 241 MAE 0.136 TMAE 0.095 Entr 0.088 TEntr 0.044 Acc 97.50% TAcc 100.00%
Epoch 242 MAE 0.133 TMAE 0.116 Entr 0.132 TEntr 0.141 Acc 93.33% TAcc 93.33%
Epoch 243 MAE 0.135 TMAE 0.156 Entr 0.130 TEntr 0.066 Acc 95.00% TAcc 100.00%
Epoch 244 MAE 0.139 TMAE 0.125 Entr 0.109 TEntr 0.107 Acc 94.17% TAcc 93.33%
Epoch 245 MAE 0.119 TMAE 0.082 Entr 0.105 TEntr 0.076 Acc 96.67% TAcc 96.67%