Я пытаюсь решить эту проблему. У меня есть конфигурации из 10 коробок, в каждой из которых можно разместить до 10 шаров. Существует нейронная сеть, которая позволяет мне вычислить величину, которая говорит о вероятности существования конфигурации. Архитектура NN представляет собой входной слой из 10 нейронов, где размещается 10 блоков. Тогда есть пара слоев с некоторыми нейронами и выходной слой с 2 нейронами A и B. Вероятность, что я заинтересован в вычислениях, имеет вид:
prob (config) = | exp (A + 1j * B) | ^ 2
Код:
keras_model=tf.keras.Sequential([
tf.keras.layers.Dense(32,activation=tf.nn.relu,input_shape=[10]),
tf.keras.layers.Dense(32,activation=tf.nn.relu),
tf.keras.layers.Dense(2)
]
)
def psi(nn_output):
real = nn_output[:, 0]
imag = nn_output[:, 1]
return tf.exp(real + 1j*imag)[0]
Я начинаю с одной конфигурации C1. Сейчас я создаю новую конфигурацию C2. Я приму эту новую конфигурацию, если prob (C2)> prob (C1). Иначе, я генерирую случайное число с равномерным распределением между 0 и 1. Если это число больше, чем prob (C1) / prob (C2), я принимаю конфигурацию C2. Это известно как алгоритм Метрополиса для выборки. Теперь у меня есть список configs
, где я храню принятые конфигурации. Я повторяю этот процесс несколько раз:
def metropolis_crit(old_psi, new_psi):
ratio = tf.abs(new_psi/old_psi)**2
if ratio > 1:
return True
else:
numerito = np.random.random()
if ratio > numerito:
return True
else:
return False
initial = np.random.randint(0, 10, 10)
oldpsi = psi(keras_model.predict(initial.reshape(1, -1)))
configs = []
for x in range(100):
new_config = np.random.randint(0, 10, 10).astype(np.float32)
new_psi = psi(keras_model.predict(new_config.reshape(1, -1)))
if metropolis_crit(oldpsi, new_psi):
oldpsi = new_psi
configs.append(new_config)
Затем я определяю функцию потерь, которую для простоты я буду считать средним числом шаров в коробках. После этого я оптимизирую функцию потерь через одну эпоху обучения. Идея состоит в том, чтобы повторять этот процесс снова и снова до сближения. Здесь изображен шаг:
def custom_loss(y_actual,y_pred):
# Try 1 (failed):
#custom_loss=kb.mean(kb.sum(y_actual, axis=1))
# Try 2
y_actual = tf.cast(y_actual, tf.complex64)
custom_loss = kb.mean(kb.abs(psi(y_actual)))
print(custom_loss)
return custom_loss
tfconfigs = np.array(configs)
optimizer=tf.keras.optimizers.RMSprop(0.001)
keras_model.compile(loss=custom_loss,optimizer=optimizer)
keras_model.fit(tfconfigs,tfconfigs,batch_size=10,epochs=1)
Так как функция потерь - это среднее количество шаров в ящиках, когда оптимизация заканчивается, NN должен давать высокую вероятность для конфигураций с пустыми ящиками, в то время как низкая вероятность для конфигураций с полными полями.
Пока что я получаю эту ошибку:
ValueError: Градиенты для любой переменной не заданы: ['dens / kernel: 0', 'density / смещение: 0 ',' плотность_1 / ядро: 0 ',' плотность_1 / смещение: 0 ',' плотность_2 / ядро: 0 ',' плотность_2 / смещение: 0 '].