Как обеспечить, чтобы процесс передискретизации TensorFlow Generator создавал начальное число с полным покрытием случайного шума?

Я работаю над адаптацией кода из учебника tenorflow 2.0 dcGAN (https://www.tensorflow.org/beta/tutorials/generative/dcgan) в спектрограмму аудиосигналов. Я использую libroasa chroma_cqt для преобразования необработанных аудиоданных в матрицу WxHx2 и использую это в качестве входных данных. Когда я пытаюсь создать исходную матрицу путем апскейлинга случайного шума, в результате я получаю чередующиеся полосы случайного шума и нулей во времени-пространстве и тонкую черную полосу вверху (см. Изображение).  без шума

Я адаптировал исходный учебный код для работы с изображениями различного размера с хорошими результатами для исходного изображения и конечного результата, но те же принципы не ведут меня к трехмерным данным. Как я могу гарантировать, что создаю семя с соответствующим покрытием и не продолжаю проблему во время обучения модели?

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

tf.__version__

import numpy as np
import os
from tensorflow.keras import layers
import librosa
import librosa.display

import matplotlib.pyplot as plt

os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

sr = 44100/2
sample_path = os.getcwd()


def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(2*7*19*128, use_bias=False, dtype='float32', input_shape=(361,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((2 ,7, 19, 128)))
    assert model.output_shape == (None,2, 7, 19, 128) # Note: None is the batch size

    model.add(layers.Conv3DTranspose(128, (2, 5, 5), strides=(1, 6, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 2, 42, 19, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv3DTranspose(128, (2, 5, 5), strides=(1, 3, 19), padding='same', use_bias=False))
    assert model.output_shape == (None, 2, 126, 361, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv3DTranspose(1, (2, 5, 5), strides=(1, 2, 1), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 2, 252, 361, 1)

    return model


generator = make_generator_model()
noise = tf.random.normal([1, 361])
generated_audio = generator(noise, training=False)


D = []
for x in range(len(generated_audio[0][0])):
    this_line = []    
    for y in range(len(generated_audio[0][0][x])):
        this_line.append(np.complex(generated_audio[0][0][x][y],generated_audio[0][1][x][y]))
    D.append(this_line)
D = np.asarray(D)


librosa.display.specshow(librosa.amplitude_to_db(np.abs(D), ref=np.max),
                          sr=sr, x_axis='time', y_axis='cqt_note')
plt.axis('off')
plt.savefig(sample_path + '\\image_at_epoch_fuzz.png')
plt.show()


print(D.shape)

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

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


person Community    schedule 22.06.2019    source источник


Ответы (2)


Это случается, когда ваш шаг слишком велик. Попробуйте использовать больший Dense слой и меньшие шаги или больше Conv3DTranspose слоев. Что-то вроде:

def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(2*32*46*128, use_bias=False, dtype='float32', input_shape=(361,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((2, 32, 46, 128)))
    # assert model.output_shape == (None,2, 7, 19, 128) # Note: None is the batch size

    model.add(layers.Conv3DTranspose(128, (2, 3, 3), strides=(1, 2, 2), padding='same', use_bias=False))
    # assert model.output_shape == (None, 2, 42, 19, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv3DTranspose(128, (2, 3, 3), strides=(1, 2, 2), padding='same', use_bias=False))
    # assert model.output_shape == (None, 2, 126, 361, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv3DTranspose(1, (2, 3, 3), strides=(1, 2, 2), padding='same', use_bias=False, activation='tanh'))
    # assert model.output_shape == (None, 2, 252, 361, 1)
    model.add(layers.Lambda(lambda x: x[:, :, :252, :361, :]))

    return model
person spadarian    schedule 23.06.2019
comment
Спасибо, это работает! Но я до сих пор не понимаю, как работает взаимосвязь между плотным слоем и шагами. Учитывая выходную форму MxNxP, какой размер плотного слоя и какую длину шага мне следует использовать? - person ; 23.06.2019
comment
Я просто старался, чтобы шаги были небольшими (2 или 3, кажется, работают). Если вы начнете с небольшого плотного слоя, вам потребуется больше шагов деконволюции для достижения желаемого размера вывода. Я не эксперт по случайности, поэтому не знаю, как это повлияет на ваш GAN. Дайте нам знать, что вы найдете! - person spadarian; 24.06.2019

Таким образом, проблема заключалась, в конечном счете, в связи между сверткой kernel_size и шагами (для лучшего объяснения каждого термина см. Раздел Conv3DTranspose здесь https://keras.io/layers/convolutional/). Плотный слой был просто прекрасен для начала. В исходном коде в следующих строках Conv3DTranspose параметр kernel_size не покрывает шаг по высоте (5 ‹6) и ширине (5‹ 19).

model.add(layers.Conv3DTranspose(128, (2, 5, 5), strides=(1, 6, 1), padding='same', use_bias=False))

model.add(layers.Conv3DTranspose(128, (2, 5, 5), strides=(1, 3, 19), padding='same', use_bias=False))

Проблема устраняется путем проверки того, что минимальные размеры kernel_size совпадают с выбранными размерами шагов. Вот исправленный код:

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf

tf.__version__

import numpy as np
import os
from tensorflow.keras import layers
import librosa
import librosa.display

import matplotlib.pyplot as plt

os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

sr = 44100/2
sample_path = os.getcwd()


def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(2*7*19*128, use_bias=False, dtype='float64', input_shape=(50,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((2 ,7, 19, 128)))
    #assert model.output_shape == (None,2, 7, 9, 128) # Note: None is the batch size

    model.add(layers.Conv3DTranspose(128, (1, 6, 1), strides=(1, 6, 1), padding='same', use_bias=False))
    #assert model.output_shape == (None, 2, 42, 19, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReL())


    model.add(layers.Conv3DTranspose(128, (1, 3, 19), strides=(1, 3, 19), padding='same', use_bias=False))
    #assert model.output_shape == (None, 2, 126, 361, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv3DTranspose(1, (1, 2, 1), strides=(1, 2, 1), padding='same', use_bias=False, activation='tanh'))
    #assert model.output_shape == (None, 2, 252, 361, 1)

    return model


generator = make_generator_model()
noise = tf.random.normal([1, 50])
generated_audio = generator(noise, training=False)


D = []
for x in range(len(generated_audio[0][0])):
    this_line = []    
    for y in range(len(generated_audio[0][0][x])):
        this_line.append(np.complex(generated_audio[0][0][x][y],generated_audio[0][1][x][y]))
    D.append(this_line)
D = np.asarray(D)


librosa.display.specshow(librosa.amplitude_to_db(np.abs(D), ref=np.max),
                          sr=sr, x_axis='time', y_axis='cqt_note')
plt.axis('off')
plt.savefig(sample_path + '\\image_at_epoch_fuzz.png')
plt.show()


print(D.shape)

результат:  изображение шума с повышенной частотой дискретизации

person Community    schedule 09.07.2019