Выборка Монте-Карло с нейронной сетью в тензорном потоке - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь решить эту проблему. У меня есть конфигурации из 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 '].

...