現在1次元データを入力とするGANを作成しようとしています.プログラム初心者のため,ネットのコードを参考に実装を目指しているのですが,あるコードで理解ができない箇所があります.

プログラムの名前はWGAN(Wasserstein GAN)となっているのですが,Discriminatorの出力や損失関数が,通常のWGANでは見られない実装をしているため,WGANの派生版ではないかと考えました.しかし,コードからどのGANを実装したのかが分からず,プログラム全体として何をしているかが理解できません.

理解できなかった箇所を元コードから抜粋して下部に書いています.
・C(X)の意義
・Discriminatorの出力次元数(通常WGANだと1次元なのではないか?)
・変数res,plossの意味
・lossの定義(通常のWGANとは違う定義をしている)

URLはコードが載っていたgithubのリンク先です.
https://github.com/whyre788/GAN-1D/blob/master/train.py

このGANの種類もしくは,このコードがやろうとしていることを理解できる方がいれば教えて欲しいです.

また,ソースコードをこのまま実行した場合,生成される信号の精度がとても悪く,こうなってしまう原因もわかりません.心当たりのある方があれば教えていただきたいです.

def LeakyReLu(x, alpha=0.1):
x = tf.maximum(alpha*x,x)
return x

def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)

with tf.name_scope('Discriminator') as scope:
DW_conv1 = weight_variable([5, 1, 16])
Db_conv1 = bias_variable([16])
DW_conv2 = weight_variable([5, 16, 32])
Db_conv2 = bias_variable([32])
DW_conv3 = weight_variable([5, 32, 64])
Db_conv3 = bias_variable([64])
DW_conv4 = weight_variable([5, 64, 128])
Db_conv4 = bias_variable([128])
DW_conv5 = weight_variable([5, 128, 256])
Db_conv5 = bias_variable([256])

DW = weight_variable([5 * 256, 1])
Db = bias_variable([1])
D_variables = [DW_conv1, Db_conv1, DW_conv2, Db_conv2,
               DW_conv3, Db_conv3, DW_conv4, Db_conv4,
               DW_conv5, Db_conv5, DW, Db]
def D(X):
    X = LeakyReLu(conv1d(X, DW_conv1, 2) + Db_conv1) 
    X = LeakyReLu(conv1d(X, DW_conv2, 5) + Db_conv2) 
    X = LeakyReLu(conv1d(X, DW_conv3, 2) + Db_conv3) 
    X = LeakyReLu(conv1d(X, DW_conv4, 5) + Db_conv4) 
    X = LeakyReLu(conv1d(X, DW_conv5, 2) + Db_conv5) 

    X = tf.reshape(X, [-1, 5 * 256])
    X = X = tf.nn.tanh(tf.matmul(X, DW) + Db)
    return X

W_conv5 = tf.Variable(tf.constant(0.1, shape=[5, 128, 256]), name="W_conv5")
b_conv5 = tf.Variable(tf.constant(0.1, shape=[256]), name="b_conv5")
saver = tf.train.Saver({'W_conv5': W_conv5, 'b_conv5': b_conv5})
saver.restore(sess, FLAGS.extractor_dir)
W_conv5 = tf.reshape(W_conv5[0:5,0,0], [5,1,1])
b_conv5 = tf.reshape(b_conv5[0], [1])
W_conv5 = tf.constant(W_conv5.eval(session=sess))
b_conv5 = tf.constant(b_conv5.eval(session=sess))

def C(X):
 Con = tf.nn.conv1d(X, W_conv5, stride=1, padding='SAME') + b_conv5
 return Con


res = tf.square(C(real_X_shaped) - C(fake_Y_shaped))
res = tf.reshape(res, [11, data_dim])
ploss = tf.reduce_sum(res, 1)*0.00001

D_loss = tf.reduce_mean(D(fake_Y_shaped)) - tf.reduce_mean(D(real_X_shaped) + grad_pen

G_loss = tf.reduce_mean(ploss - D(fake_Y_shaped))