Вопрос или проблема
Структура, которую я себе представляю, похожа на ту, что на изображении ниже
где на выходе используется softmax. Для скрытого слоя у нас было бы
$$Z_1 = W_{11}^{[1]}x_2 + W_{12}^{[1]}x_2$$
$$Z_2 = W_{21}^{[1]}x_2 + W_{22}^{[1]}x_2$$
$$Z_3 = W_{11}^{[1]}x_3 + W_{12}^{[1]}x_4$$
$$Z_4 = W_{21}^{[1]}x_3 + W_{22}^{[1]}x_4$$
такой же принцип применим к softmax. Я пришел к этой идее, пытаясь создать нейронную сеть, которая бы вела себя похоже на условную логистическую регрессию (https://en.wikipedia.org/wiki/Conditional_logistic_regression).
Я сделал реализацию с помощью Keras и Tensorflow, которая, как я полагаю, будет вести себя так, как надо, но я не уверен.
class ConditionalNN(tf.keras.Model):
def __init__(self, out_dim, l1 = 0, l2 = 0):
super(ConditionalNN, self).__init__(name="")
self.layer1 = tf.keras.layers.Dense(20,'tanh',kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1, l2=l2))
self.layerL1 = tf.keras.layers.Dense(1,'linear',kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1, l2=l2))
self.layerL2 = tf.keras.layers.Softmax(axis=-2)
def call(self, input_tensor, training=False):
x = self.layer1(input_tensor,training=training)
x = self.layerL1(x,training=training)
x = self.layerL2(x,training=training)
return x
В этом случае входными данными будет 3D-тензор, например:
X = [
[[x1,x2],
[x3,x4]],
...
]
а выход будет чем-то вроде:
Y = [[1,0],
[0,1],
[1,0],
...
]
Это интересная идея, и я думаю, имеет смысл делиться весами. Я не видел точно того, что вы описали, но обычно делятся весами в случаях, когда два входа имеют схожий смысл. Например, в этой статье они используют общие векторы эмбеддинга для целевого видео и видео из истории пользователя, у которых одинаковый video_id
. Это определенно возможно реализовать в TensorFlow, если два входа имеют одинаковые размеры. Способ реализации очевиден: создайте матрицу весов с размерами (feature_dimension
, num_neuron
) и умножьте разные входы на одну и ту же матрицу.
Ответ или решение
Создание нейронной сети с одинаковыми весами для различных узлов в одном слое представляет собой интересную задачу, особенно учитывая ваше сравнение с условной логистической регрессией. Рассмотрим, как можно реализовать такую архитектуру с помощью TensorFlow и Keras, а также обсудим теоретические аспекты, лежащие в основе этого подхода.
Понимание концепции общего веса
Ваша идея о том, что некоторые узлы в скрытом слое могут делить одни и те же веса, может быть полезна в случаях, когда различные входные данные имеют схожие характеристики или требуют применения одних и тех же признаков. Это может помочь в обучении модели, так как она будет более универсальной и сможет лучше адаптироваться к различным входным данным.
Построение модели
Для реализации такой модели вам нужно следующее:
-
Определение структуры сети: Вам потребуется слой, который будет использовать одинаковые веса для нескольких узлов. Это можно сделать с помощью кастомной функции вызова, которая будет применять один и тот же набор весов к различным входным данным.
-
Создание общей весовой матрицы: Ваша задача будет заключаться в создании матрицы весов с размерностью, соответствующей размеру признаков и количеству нейронов в вашем слое.
-
Использование TensorFlow/Keras: Вы можете задать веса в TensorFlow, используя подходы, применяемые в Keras. Например, вы можете создать массив весов в конструкторе класса и использовать его в функции
call
.
Пример реализации
import tensorflow as tf
class ConditionalNN(tf.keras.Model):
def __init__(self, out_dim, l1=0, l2=0):
super(ConditionalNN, self).__init__(name="")
self.shared_weights = tf.keras.layers.Dense(20, activation='tanh',
kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1, l2=l2))
self.output_layer = tf.keras.layers.Dense(out_dim, activation='softmax',
kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1, l2=l2))
def call(self, inputs, training=False):
# Предполагаем, что inputs имеет вид [batch_size, num_samples, feature_dim]
# Применяем общий весовой слой
shared_output = self.shared_weights(inputs)
# Объединяем выводы для получения конечных результатов
outputs = self.output_layer(shared_output)
return outputs
# Пример входных данных
X = tf.random.normal(shape=(batch_size, num_samples, feature_dimension))
model = ConditionalNN(out_dim=2)
output = model(X)
Ключевые моменты
-
Единая весовая матрица: Все узлы в одном слое применяют одну и ту же матрицу весов
shared_weights
, что позволяет объявлять веса один раз и использовать их для различных входных сигналов. -
Соглашение о размерностях: Важно, чтобы ваши входные данные имели совместимые размерности, чтобы избежать ошибок при матричных умножениях.
-
Значение softmax: На выходе, применение функции активации softmax обеспечивает нормализованные вероятностные оценки, которые могут быть использованы для многоклассовой классификации.
Заключение
Использование одинаковых весов для разных узлов в одном слое является мощным инструментом при разработке нейронных сетей. Это может способствовать более эффективному обучению и лучшему обобщению модели. Надеюсь, представленная информация окажется полезной для вас в реализации задуманной архитектуры и достижения ваших целей в области машинного обучения и анализа данных.