@GSimonX37

Как в tensorflow построить модель с несколькими выходами?

Необходимо создать модель, которая получает изображение постера фильма и возвращает возрастной рейтинг (многоклассовая классификация) и список жанров (классификация по нескольким меткам).

Код модели:
class NNetwork(Model):
    def __init__(self, rating: int, genres: int):
        super(NNetwork, self).__init__()
        self.rescaling = Rescaling(1.0 / 255.0)

        self.convolution = [
            Conv2D(16, 3, padding='same', activation='relu'),
            Conv2D(32, 3, padding='same', activation='relu'),
            Conv2D(64, 3, padding='same', activation='relu')
        ]
        self.pooling = [
            MaxPooling2D(),
            MaxPooling2D(),
            MaxPooling2D()
        ]
        self.flatten = Flatten()

        self.dense = [
            Dense(128, activation='relu'),
            Dense(rating, activation='softmax'),
            Dense(genres, activation='softmax')
        ]

    def call(self, images: Tensor, training=None, **kwargs) -> tuple[Tensor, Tensor]:
        x = self.rescaling(images)

        for i in range(3):
            x = self.convolution[i](x)
            x = self.pooling[i](x)

        x = self.flatten(x)

        x = self.dense[0](x)

        rating = self.dense[1](x)
        genres = self.dense[2](x)

        return rating, genres


Код функции потерь:
def loss(true: Tensor,
         predict: Tensor) -> Tensor:
    
    categorical = CategoricalCrossentropy(
        reduction=None
    )

    loss = tf.reduce_mean(categorical(
        y_true=true,
        y_pred=predict
    ))

    return loss


Код цикла обучения:
@tf.function
def train_step(images_batch, rating_batch, genres_batch):
    with tf.GradientTape() as tape:
        rating_predict, genres_predict = model(images_batch)
        
        rating_loss = loss(rating_batch, rating_predict)
        genres_loss = loss(genres_batch, genres_predict)
        
    gradients = tape.gradient([rating_loss, genres_loss], model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    rating_score.update_state(rating_batch, rating_predict)
    genres_score.update_state(genres_batch, genres_predict)
    
    return rating_loss, genres_loss


Код основного цикла:
for n in range(EPOCHS):
    total_loss = 0
    total_rating_loss = 0
    total_genres_loss = 0
    
    for inputs, outputs in train:
        images_batch = inputs['image']
        rating_batch = outputs['rating']
        genres_batch = outputs['genres']
        
        rating_loss, genres_loss = train_step(images_batch, rating_batch, genres_batch)

        total_loss += (rating_loss + genres_loss)
        total_rating_loss += rating_loss
        total_genres_loss += genres_loss
    
    print(f'EPOCHS: {n} - total_loss: {total_loss.numpy()}, total_rating_loss: {total_rating_loss.numpy()}, total_genres_loss: {total_genres_loss.numpy()}')


Процесс обучения запускается, но функция потерь на каждой эпохе огромная, 10 в 15 степени. Значит алгоритм обучения составлен неверно.

Я предполагаю в чем может быть проблема:
1. Неверно выбрана или оформлена функция потерь.
2. Неверно вычисляются и применяются градиенты.

В чем может быть еще причина такой большой функции потерь?
  • Вопрос задан
  • 91 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы