gan.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import tensorflow as tf
  2. from tensorflow import keras
  3. from tensorflow.keras import layers
  4. class Generator(keras.Model):
  5. # 生成器网络
  6. def __init__(self):
  7. super(Generator, self).__init__()
  8. filter = 64
  9. # 转置卷积层1,输出channel为filter*8,核大小4,步长1,不使用padding,不使用偏置
  10. self.conv1 = layers.Conv2DTranspose(filter*8, 4,1, 'valid', use_bias=False)
  11. self.bn1 = layers.BatchNormalization()
  12. # 转置卷积层2
  13. self.conv2 = layers.Conv2DTranspose(filter*4, 4,2, 'same', use_bias=False)
  14. self.bn2 = layers.BatchNormalization()
  15. # 转置卷积层3
  16. self.conv3 = layers.Conv2DTranspose(filter*2, 4,2, 'same', use_bias=False)
  17. self.bn3 = layers.BatchNormalization()
  18. # 转置卷积层4
  19. self.conv4 = layers.Conv2DTranspose(filter*1, 4,2, 'same', use_bias=False)
  20. self.bn4 = layers.BatchNormalization()
  21. # 转置卷积层5
  22. self.conv5 = layers.Conv2DTranspose(3, 4,2, 'same', use_bias=False)
  23. def call(self, inputs, training=None):
  24. x = inputs # [z, 100]
  25. # Reshape乘4D张量,方便后续转置卷积运算:(b, 1, 1, 100)
  26. x = tf.reshape(x, (x.shape[0], 1, 1, x.shape[1]))
  27. x = tf.nn.relu(x) # 激活函数
  28. # 转置卷积-BN-激活函数:(b, 4, 4, 512)
  29. x = tf.nn.relu(self.bn1(self.conv1(x), training=training))
  30. # 转置卷积-BN-激活函数:(b, 8, 8, 256)
  31. x = tf.nn.relu(self.bn2(self.conv2(x), training=training))
  32. # 转置卷积-BN-激活函数:(b, 16, 16, 128)
  33. x = tf.nn.relu(self.bn3(self.conv3(x), training=training))
  34. # 转置卷积-BN-激活函数:(b, 32, 32, 64)
  35. x = tf.nn.relu(self.bn4(self.conv4(x), training=training))
  36. # 转置卷积-激活函数:(b, 64, 64, 3)
  37. x = self.conv5(x)
  38. x = tf.tanh(x) # 输出x范围-1~1,与预处理一致
  39. return x
  40. class Discriminator(keras.Model):
  41. # 判别器
  42. def __init__(self):
  43. super(Discriminator, self).__init__()
  44. filter = 64
  45. # 卷积层
  46. self.conv1 = layers.Conv2D(filter, 4, 2, 'valid', use_bias=False)
  47. self.bn1 = layers.BatchNormalization()
  48. # 卷积层
  49. self.conv2 = layers.Conv2D(filter*2, 4, 2, 'valid', use_bias=False)
  50. self.bn2 = layers.BatchNormalization()
  51. # 卷积层
  52. self.conv3 = layers.Conv2D(filter*4, 4, 2, 'valid', use_bias=False)
  53. self.bn3 = layers.BatchNormalization()
  54. # 卷积层
  55. self.conv4 = layers.Conv2D(filter*8, 3, 1, 'valid', use_bias=False)
  56. self.bn4 = layers.BatchNormalization()
  57. # 卷积层
  58. self.conv5 = layers.Conv2D(filter*16, 3, 1, 'valid', use_bias=False)
  59. self.bn5 = layers.BatchNormalization()
  60. # 全局池化层
  61. self.pool = layers.GlobalAveragePooling2D()
  62. # 特征打平
  63. self.flatten = layers.Flatten()
  64. # 2分类全连接层
  65. self.fc = layers.Dense(1)
  66. def call(self, inputs, training=None):
  67. # 卷积-BN-激活函数:(4, 31, 31, 64)
  68. x = tf.nn.leaky_relu(self.bn1(self.conv1(inputs), training=training))
  69. # 卷积-BN-激活函数:(4, 14, 14, 128)
  70. x = tf.nn.leaky_relu(self.bn2(self.conv2(x), training=training))
  71. # 卷积-BN-激活函数:(4, 6, 6, 256)
  72. x = tf.nn.leaky_relu(self.bn3(self.conv3(x), training=training))
  73. # 卷积-BN-激活函数:(4, 4, 4, 512)
  74. x = tf.nn.leaky_relu(self.bn4(self.conv4(x), training=training))
  75. # 卷积-BN-激活函数:(4, 2, 2, 1024)
  76. x = tf.nn.leaky_relu(self.bn5(self.conv5(x), training=training))
  77. # 卷积-BN-激活函数:(4, 1024)
  78. x = self.pool(x)
  79. # 打平
  80. x = self.flatten(x)
  81. # 输出,[b, 1024] => [b, 1]
  82. logits = self.fc(x)
  83. return logits
  84. def main():
  85. d = Discriminator()
  86. g = Generator()
  87. x = tf.random.normal([2, 64, 64, 3])
  88. z = tf.random.normal([2, 100])
  89. prob = d(x)
  90. print(prob)
  91. x_hat = g(z)
  92. print(x_hat.shape)
  93. if __name__ == '__main__':
  94. main()