Модель нейронной сети для разреженного многоклассового классификатора на Tensorflow

Вопрос или проблема

Проблема, которую я пытаюсь решить, заключается в следующем:

данные из Movielens с N_users=6041 и N_movies=3953, ~1 миллион оценок.

Для каждого пользователя определяется вектор размером N_movies, и значения вектора равны 1, если пользователь оценил фильм до времени T, и 0, если нет. Например, если пользователь оценил фильмы 3 и 5, то входной вектор будет [0,0,1,0,1].

Цель состоит в том, чтобы предсказать фильм, который пользователь оценит в будущем (между временем T и T+delta T). Метки представляют собой вектор размером N_movies, и если пользователь оценит фильм 4, то вектор меток будет [0,0,0,1,0].

В настоящее время я пытаюсь получить некоторые начальные результаты на основе полно связанных слоев, но похоже, что модель совсем не может оптимизировать ошибку. Возможно, представление слишком разреженное, но кажется, что нейронная сеть должна быть в состоянии выучить хотя бы некоторые характеристики.

Возможно ли заставить эту модель работать, есть ли проблема с функцией потерь или оптимизатором?

from __future__ import print_function
import tensorflow as tf
from tensorflow.contrib import rnn
import csv
import bisect
import glob
import re
import numpy as np
import random
import data
import config

cfg = config.Config()
graph_data = data.Graph_data(cfg)

X = tf.placeholder("float", [None, cfg.N_movies])
Y = tf.placeholder("float", [None, cfg.N_movies])

def Dense(x):
    hidden_layer_1 = tf.layers.dense(inputs=x, units=500, activation=tf.nn.relu)
    hidden_layer_2 = tf.layers.dense(inputs=hidden_layer_1, units=50, activation=tf.nn.relu)
    output_layer = tf.layers.dense(inputs = hidden_layer_2, units= cfg.N_movies, activation=tf.nn.softmax)
    return output_layer

logits = Dense(X)
cross_entropy = tf.reduce_sum(- Y * tf.log(logits), 1)
loss_op = tf.reduce_mean(cross_entropy)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=cfg.learning_rate)
train_op = optimizer.minimize(loss_op)

init = tf.global_variables_initializer()

with tf.Session() as sess:
  sess.run(init)

  for step in range(1, cfg.training_steps+1):
    batch_x, batch_y = graph_data.train_next_batch(cfg.batch_size)
    sess.run(train_op, feed_dict={X: batch_x, Y: batch_y})
    if step % cfg.display_step == 0 or step == 1:
      loss = sess.run(loss_op, feed_dict={X: batch_x,
                                                                  Y: batch_y})
      print("loss = ",loss)

Модель выглядит нормально для меня. Вы пытались оптимизировать гиперпараметры? Вы можете использовать методы проб и ошибок для оптимизации параметров, таких как:

  • Скорость обучения
  • Число эпох
  • Размер партии и т.д.,

И вместо обычного оптимизатора градиентного спуска вы можете попробовать другие оптимизаторы, такие как Adagrad, Adam или RMSProp и т.д.

С уважением,
Сангатамиллан Равичандран.

Учитывая, что ваши данные разреженные, стоит попробовать функцию потерь для такого типа представления.

Например, Keras имеет класс SparseCategoricalCrossentropy:

tf.keras.losses.SparseCategoricalCrossentropy(
    from_logits=False, reduction="auto", name="sparse_categorical_crossentropy"
)

Более подробная информация об этом доступна здесь.

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

Ответ или решение

Нейронная сеть для разреженного многоклассового классификатора на TensorFlow

Ваша задача заключается в разработке модели нейронной сети для обработки разреженных данных с использованием пиковых предпочтений пользователей в MovieLens. Исходя из предоставленной информации, у вас уже есть начальная реализация, однако вы сталкиваетесь с проблемами в оптимизации потерь. Возможные причины таких сложностей и рекомендации по их устранению будут рассмотрены ниже.

Предварительный анализ

Вы работаете с данными, содержащими информацию о 6041 пользователе и 3953 фильмах, сформировавшими матрицу оценок, в которой значениями являются бинарные индикаторы (1 — фильм был оценен, 0 — не был). Ваши входные данные представляют собой разреженные векторы, что может усложнять обучение модели из-за недостатка информации.

Возможные пути решения

  1. Выбор оптимизатора:
    Некоторым задачам лучше подходит использование более сложных оптимизаторов, таких как Adam, RMSProp или Adagrad, которые могут адаптивно настраивать скорость обучения для каждого параметра. Это может помочь вам лучше справляться с разреженностью данных.

    optimizer = tf.train.AdamOptimizer(learning_rate=cfg.learning_rate)
  2. Функция потерь:
    Поскольку ваши данные разрежены, пробуйте использовать более подходящие функции потерь. Например, если ваша задача предполагает выбор одного верного класса (фильма), рассмотрите возможность применения функции потерь SparseCategoricalCrossentropy, которая учитывает разреженное представление:

    loss_op = tf.keras.losses.SparseCategoricalCrossentropy()(Y, logits)
  3. Параметры обучения:
    Поэкспериментируйте с различными гиперпараметрами:

    • Скорость обучения: Попробуйте использовать такие значения, как 0.001 или 0.0001.
    • Размер батча: Измените его в диапазоне от 32 до 256, чтобы увидеть, как это влияет на обучение.
    • Число эпох: Увеличьте количество эпох обучения, чтобы убедиться, что модель успевает сойтись.
  4. Архитектура модели:
    Вам следует пересмотреть архитектуру вашей модели. Я рекомендую попробовать следующие изменения:

    • Увеличьте количество скрытых слоев и их размеры.
    • Включите метод регуляризации, такой как Dropout, чтобы уменьшить переобучение.
    • Рассмотрите возможность использования Batch Normalization для улучшения стабильности обучения и ускорения сходимости.

    Примерно это будет выглядеть так:

    def Dense(x):
       hidden_layer_1 = tf.layers.dense(inputs=x, units=500, activation=tf.nn.relu)
       hidden_layer_1 = tf.layers.dropout(hidden_layer_1, rate=0.5)
       hidden_layer_2 = tf.layers.dense(inputs=hidden_layer_1, units=50, activation=tf.nn.relu)
       output_layer = tf.layers.dense(inputs=hidden_layer_2, units=cfg.N_movies, activation=None)
       return output_layer
  5. Проверка данных и отладка:
    Запустите свою модель на смоделированных данных, чтобы убедиться, что граф вычислений построен корректно и модель может обучаться. Это поможет диагностировать потенциальные проблемы на этапе инициализации.

Заключение

Проблема разреженных данных в задачах классификации требует тщательного подхода как к выбору модели, так и к методам ее обучения. Используя предложенные рекомендации, вы сможете улучшить процесс обучения вашей нейронной сети на TensorFlow. Не забывайте о значимости гиперпараметров и экспериментировании с различными алгоритмами и функциями потерь. Удачи в ваших экспериментах!

Оцените материал
Добавить комментарий

Капча загружается...