Для решения задачи обучения с несколькими задачами импортируются следующие модули.
import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from sklearn.datasets import load_iris
from tensorflow.keras.utils import to_categorical
import tensorflow.keras.backend as K
tf.keras.backend.set_floatx('float64')
import numpy as np
Затем мы определяем сеть с несколькими выходами, как показано ниже:
x
| Dense(16)
x
| Dense(32)
x
Dense(1) / \ Dense(4, softmax)
/ \
(continuous) y_cont y_cat (categorical)
код показан ниже:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.d0 = Dense(16, activation='relu')
self.d1 = Dense(32, activation='relu')
self.cont = Dense(1) # Continuous output
self.cat = Dense(4, activation='softmax') # Categorical output
def call(self, x):
x = self.d0(x)
x = self.d1(x)
print(x.shape)
y_cont = self.cont(x)
y_cat = self.cat(x)
return y_cont, y_cat
model = MyModel()
Далее мы определим функцию потерь и оптимизатор. Мы используем совместное обучение. Функция потерь представляет собой сумму средней абсолютной ошибки для непрерывной переменной и кросс-энтропии для переменной категории.
cont_loss_func = tf.keras.losses.MeanAbsoluteError()
cat_loss_func = tf.keras.losses.SparseCategoricalCrossentropy()
def cont_cat_loss_func(real_cont, pred_cont, real_cat, pred_cat):
return cat_loss_func(real_cat, pred_cat) + cont_loss_func(real_cont, pred_cont)
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4)
Шаг поезда определяется следующим образом:
@tf.function
def train_step(inputs, target_cont, target_cat):
with tf.GradientTape() as tape:
#Forward pass
output_cont, output_cat = model(inputs)
#Compute the losses
total_loss = cont_cat_loss_func(target_cont, output_cont, target_cat, output_cat)
#Backpropagation
gradients = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return output_cont, output_cat
Мы тренируемся сеть на 50 эпох и производительность модели для каждой эпохи будут показаны во время обучения.
#Model performance
acc_res = tf.keras.metrics.Accuracy()
mae_res = tf.keras.metrics.MeanAbsoluteError()
for epoch in range(50):
for xx, yy, zz in ds:
out_cont, out_cat = train_step(xx, yy, zz)
res1 = acc_res.update_state(zz, np.argmax(out_cat, axis=1))
res2 = mae_res.update_state(yy, out_cont)
template = 'Epoch {:>2}, Accuracy: {:>5.2f}, MAE: {:>5.2f}'
print(template.format(epoch+1, acc_res.result(), mae_res.result()))
acc_res.reset_states()
mae_res.reset_states()
Вместо использования совместного обучения (т. е. суммирования потери непрерывной переменной и категориальной переменной) ), @ thushv89 использует другой метод для расчета потерь в сети. Но я не совсем понимаю, как это работает.
loss_objects = [tf.keras.losses.MeanAbsoluteError(), tf.keras.losses.SparseCategoricalCrossentropy()]
losses = [l(t, o) for l,o,t in zip(loss_objects, outputs, targets)]