странный подход к нейронным сетям

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

Я работаю над проблемой, где мне нужно создать нейронную сеть для оптимизации рассадки 24 уникальных человек в сетке 6×4, минимизируя конфликты между соседними (вверх, вниз, вбок) людьми в этой сетке. Цель заключается в том, чтобы разработать нейронную сеть, которая находит лучший способ рассадки людей на основе входных конфликтных матриц. У нас есть конфликтная матрица, представляющая собой бинарную матрицу размером (24,24), которая показывает отношение между каждой парой людей, где значение 1 указывает на конфликт между двумя людьми, а 0 указывает на отсутствие конфликта. Любые предложения о том, как подойти к этой задаче, используя архитектуру нейронной сети, будут очень признательны. Спасибо!

Мы должны решить эту проблему только с помощью контролируемой или неконтролируемой нейронной сети, а не теории графов и оптимизации, графовой сети или Q-обучения или RL или других методов.

Моя попытка найти решение приведена ниже:


import tensorflow as tf
import random
import numpy as np

list_of_conflicts = []

while len(list_of_conflicts) < 500:
    pairs_list = set()
    matrix = np.zeros((24, 24), dtype=int)

    while matrix.sum() < 40:
        num1 = np.random.choice(range(24))
        num2 = np.random.choice(range(24))

        if num1 == num2:
            continue

        pair = (num1, num2)
        if pair in pairs_list:
            continue

        pairs_list.add(pair)
        matrix[num1, num2] = 1

    if not any(np.array_equal(matrix, conflict) for conflict in list_of_conflicts):
        list_of_conflicts.append(matrix)

# входные данные - конфликтные матрицы
conflicts = np.array(list_of_conflicts)

def create_adjacent_mask(n_seats, seats_per_row, seats_per_col):
    adjacent_mask = np.zeros((n_seats, n_seats))
    for i in range(n_seats):
        if i % seats_per_row != 0:
            adjacent_mask[i, i-1] = 1
        if i % seats_per_row != seats_per_row-1:
            adjacent_mask[i, i+1] = 1
        if i >= seats_per_row:
            adjacent_mask[i, i-seats_per_row] = 1
        if i < n_seats-seats_per_row:
            adjacent_mask[i, i+seats_per_row] = 1
    return adjacent_mask

adjacent_mask = create_adjacent_mask(24,6,4)
# Определите функцию для расчета общего количества конфликтов для данного расположения
def calculate_conflict(seating_arrangement, conflict_matrix):
    conflicts = 0
    ca_mul = tf.convert_to_tensor(conflict_matrix * adjacent_mask, tf.float64)
    conflicts = tf.reduce_sum(tf.matmul(tf.cast(seating_arrangement,tf.float64), ca_mul))
    # print(conflicts)
    return conflicts

# Пользовательская функция потерь с использованием расчета конфликтов
def custom_loss(predicted_seating_arrangement, conflicts_tensor):
    loss = 0
    for i in range(predicted_seating_arrangement.shape[0]):
        conflict = tf.py_function(calculate_conflict,[predicted_seating_arrangement[i],conflicts_tensor[i]], tf.float64)
        # штрафуйте за количество больше 1 
        occurrences = tf.reduce_sum(predicted_seating_arrangement[i], axis=0)

        # Расчет числа повторяющихся элементов
        repetitive_elements = tf.reduce_sum(tf.abs(occurrences - 1))/24

        loss += tf.cast(repetitive_elements, tf.float64) + conflict
    return tf.cast(loss, tf.float64) / tf.cast(predicted_seating_arrangement.shape[0], tf.float64)

conflicts_tensor = tf.convert_to_tensor(conflicts, tf.float64)

# Определите нейронную сеть
model = tf.keras.Sequential([
    tf.keras.layers.Input(conflicts_tensor.shape[1:]),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(24*24, activation='softmax'),
    tf.keras.layers.Reshape((24,24))
])

# Оптимизатор
optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)

# Цикл обучения
for epoch in range(2):
    with tf.GradientTape() as tape:
        predicted_seating_arrangement = model(conflicts_tensor, training=True)
        # print(predicted_seating_arrangement.shape)
        # Рассчитайте потери
        loss = custom_loss(predicted_seating_arrangement, conflicts_tensor)
    # Рассчитайте градиенты
    gradients = tape.gradient(loss, model.trainable_variables)
    # Обновите веса
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    # Выведите потери
    print(f'Эпоха: {epoch}, Потери: {loss.numpy()}')

```

Я думаю, что вам не нужно использовать нейронную сеть для рассадки. Рассадка гостей — известная проблема в операционных исследованиях, моделируемая как Квадратная задача многопесчаных рюкзаков. Вы можете найти рабочие подходы в этой статье или в этой. Однако, если эти более формальные подходы вам не подходят, генетические алгоритмы вполне подойдут для вашей проблемы, особенно из-за небольшого количества людей, чьи позиции нужно оптимизировать.

С другой стороны, если вам нужно использовать нейронную сеть, я бы, безусловно, начал с обдумывания вашей функции потерь. Она должна быть непрерывной, и ее значение должно направлять вашу модель к конечным результатам – что-то вроде расстояния между единицами, умноженного на значение конфликта. Дополнительно, я не уверен, стоит ли принимать конфликтную матрицу в качестве входных и выходных данных. Насколько я понимаю, вы должны иметь возможность рассаживать людей на основе вывода модели. Я бы попробовал включить конфликтную матрицу скорее в функцию потерь или в качестве вспомогательного входа, чем как единственный вход.

Также начните с меньшей модели, чтобы быстрее прототипировать.

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

Уникальные подходы к нейронным сетям для оптимизации рассадки гостей

Оптимизация рассадки гостей в сетке 6×4, основываясь на матрице конфликтов, представляет собой интересную задачу, требующую глубокого рассмотрения методов, основанных на нейронных сетях. Ниже приведен подробный подход к созданию нейронной сети для решения этой задачи.

Понимание проблемы

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

Этап 1: Подготовка данных

Входные данные – это конфликтные матрицы размером (24, 24), содержащие бинарные значения, которые указывают, конфликтует ли один человек с другим. Эти данные можно собрать в формате, который будет использован в процессе обучения вашей нейронной сети.

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

Этап 2: Архитектура нейронной сети

Для решения проблемы seating arrangement, можно использовать комбинацию следующих слоев:

  1. Входной слой: принимает конфликтную матрицу.
  2. Скрытые слои: несколько полносвязных слоев с активацией ReLU для учета интерактивных характеристик входных данных.
  3. Выходной слой: слой с активацией softmax, который выдает вероятностное распределение для отклонений от конфликтов, представляя оптимальную посадку.

Примерная архитектура может выглядеть следующим образом:

model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(24, 24)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(24 * 24, activation='softmax'),
    tf.keras.layers.Reshape((24, 24))
])

Этап 3: Определение функции потерь

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

  • Совокупный конфликт: используйте матрицу смежности для учета конфликтов между людьми, сидящими рядом.
  • Уникальность сидений: наказывайте модель за повторяющиеся элементы в выходном слое, что обеспечит уникальность рассадки.

Ваш код для функции потерь может выглядеть следующим образом:

def custom_loss(predicted_seating_arrangement, conflict_matrix):
    loss = 0
    for i in range(predicted_seating_arrangement.shape[0]):
        conflict_score = compute_conflict(predicted_seating_arrangement[i], conflict_matrix[i])
        uniqueness_penalty = ...  # Ваш расчет уникальности
        loss += conflict_score + uniqueness_penalty
    return loss / predicted_seating_arrangement.shape[0]

Этап 4: Обучение модели

При обучении модели стоит использовать метод обратного распространения ошибки для минимизации функции потерь. В качестве оптимизатора рекомендую использовать Adam или RMSProp, благодаря их способности адаптивно изменять скорость обучения.

Заключение

Хотя ваша задача довольно сложна, применение нейронных сетей и подхода глубокого обучения может привести к интересным результатам. Однако, имейте в виду, что существуют и традиционные методы, такие как генетические алгоритмы или другие методы оптимизации, которые могут быть более эффективны для конкретных случаев. Тем не менее, если ваша цель — использовать нейронные сети, то следуя вышеописанным этапам, вы сможете создать рабочую модель, способствующую оптимизации рассадки индивидуумов.

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

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