GAN Discriminator отрицает сгенерированные модели - PullRequest
0 голосов
/ 01 декабря 2019

У меня есть сеть GAN, которая должна генерировать 3d модели мечей. Я построил его на основе Tensorflow GAN Tutorial по созданию цифровых изображений: https://www.tensorflow.org/tutorials/generative/dcgan.

Я конвертирую файлы .obj (все модели имеют 240 граней) в мат [240;9] (где 9 - координатывершин лица). Все координаты <= 1.0, и у меня есть ~ 3000+ моделей в наборе данных. </p>

Я смешал матрицы 3d-моделей и начал изучать свою сеть GAN. Каждые 100 эпох я печатаю среднее значение предсказания дискриминатора для: набора данных, который использовался для изучения, набора данных неиспользуемых моделей для проверки дискриминатора, сгенерированных моделей и мусора (случайные сгенерированные матрицы [240,9])

Функция активации дискриминатора равналинейный: если результат> 0 => принятая модель дискриминатора, если она <0, значит, модель дискриминатора запрещена</p>

Но что я имею в результате:

> 1-th epoch:
> Learned Dataset AVG Prediction: ~ 0.002
> Unused Checking Dataset AVG Prediction ~ 0.0018
> Generated Dataset AVG Prediction ~ -0.002
> Garbage Dataset AVG Prediction ~ -1.5
> 
> 6000-th epoch:
> Learned Dataset AVG Prediction: ~ 17.000
> Unused Checking Dataset AVG Prediction ~ 19.000
> Generated Dataset AVG Prediction ~ -3.000
> Garbage Dataset AVG Prediction ~ -20000.000

Это означает, что дискриминатор учится правильно, но генератор не может обмануть дискриминатор. И я получил 3D-модель, как меч, но где многоугольники вращались случайным образом и не имеют связей: https://imgur.com/FGOVDTT (100.000 эпох)

Прав ли я в том, что мой набор данных хорош, а дискриминатор учится правильно? Должен ли я изменить структуру сети моделей генераторов? В чем может быть причина такого обучения?

def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(30 * 9 * 512, use_bias=False, input_shape=(100,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((30, 9, 512)))
    assert model.output_shape == (None, 30, 9, 512)  # Note: None is the batch size

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 60, 9, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 120, 9, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 1), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 240, 9, 1)

    return model

Весь другой код из моей программы идентичен коду с сайта TensorFlow

1 Ответ

0 голосов
/ 01 декабря 2019

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

Одним из решений этой проблемы может быть изменение вашего представления, например, один из следующих параметров:

  1. представляет каждую грань с ее центральной точкой, для создания 3D-модели вы просто соединяете каждую точку с ее тремя ближайшими соседями.
  2. сохраняете каждую вершину отдельно и восстанавливаете поверхности позже, соединяя каждуювершина с ее тремя ближайшими соседями.

Вариант 1) имеет дополнительное преимущество, заключающееся в дальнейшем сокращении пространства ввода, но может привести к несколько иным результатам. Существуют некоторые граничные поверхности, которые нельзя представить, как описано выше, но это наиболее простые подходы. Если у вас есть сложные 3D-модели, которые не могут быть представлены таким образом, вы должны придумать что-то еще, но есть много вариантов для выбора.

...