network.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import tensorflow as tf
  2. import tensorflow.contrib.slim as slim
  3. def resblock(inputs, out_channel=32, name='resblock'):
  4. with tf.variable_scope(name):
  5. x = slim.convolution2d(
  6. inputs, out_channel, [3, 3], activation_fn=None, scope='conv1')
  7. x = tf.nn.leaky_relu(x)
  8. x = slim.convolution2d(
  9. x, out_channel, [3, 3], activation_fn=None, scope='conv2')
  10. return x + inputs
  11. def spectral_norm(w, iteration=1):
  12. w_shape = w.shape.as_list()
  13. w = tf.reshape(w, [-1, w_shape[-1]])
  14. u = tf.get_variable(
  15. 'u', [1, w_shape[-1]],
  16. initializer=tf.random_normal_initializer(),
  17. trainable=False)
  18. u_hat = u
  19. v_hat = None
  20. for i in range(iteration):
  21. """
  22. power iteration
  23. Usually iteration = 1 will be enough
  24. """
  25. v_ = tf.matmul(u_hat, tf.transpose(w))
  26. v_hat = tf.nn.l2_normalize(v_)
  27. u_ = tf.matmul(v_hat, w)
  28. u_hat = tf.nn.l2_normalize(u_)
  29. u_hat = tf.stop_gradient(u_hat)
  30. v_hat = tf.stop_gradient(v_hat)
  31. sigma = tf.matmul(tf.matmul(v_hat, w), tf.transpose(u_hat))
  32. with tf.control_dependencies([u.assign(u_hat)]):
  33. w_norm = w / sigma
  34. w_norm = tf.reshape(w_norm, w_shape)
  35. return w_norm
  36. def conv_spectral_norm(x, channel, k_size, stride=1, name='conv_snorm'):
  37. with tf.variable_scope(name):
  38. w = tf.get_variable(
  39. 'kernel', shape=[k_size[0], k_size[1],
  40. x.get_shape()[-1], channel])
  41. b = tf.get_variable(
  42. 'bias', [channel], initializer=tf.constant_initializer(0.0))
  43. x = tf.nn.conv2d(
  44. input=x,
  45. filter=spectral_norm(w),
  46. strides=[1, stride, stride, 1],
  47. padding='SAME') + b
  48. return x
  49. def unet_generator(inputs,
  50. channel=32,
  51. num_blocks=4,
  52. name='generator',
  53. reuse=False):
  54. with tf.variable_scope(name, reuse=reuse):
  55. x0 = slim.convolution2d(inputs, channel, [7, 7], activation_fn=None)
  56. x0 = tf.nn.leaky_relu(x0)
  57. x1 = slim.convolution2d(
  58. x0, channel, [3, 3], stride=2, activation_fn=None)
  59. x1 = tf.nn.leaky_relu(x1)
  60. x1 = slim.convolution2d(x1, channel * 2, [3, 3], activation_fn=None)
  61. x1 = tf.nn.leaky_relu(x1)
  62. x2 = slim.convolution2d(
  63. x1, channel * 2, [3, 3], stride=2, activation_fn=None)
  64. x2 = tf.nn.leaky_relu(x2)
  65. x2 = slim.convolution2d(x2, channel * 4, [3, 3], activation_fn=None)
  66. x2 = tf.nn.leaky_relu(x2)
  67. for idx in range(num_blocks):
  68. x2 = resblock(
  69. x2, out_channel=channel * 4, name='block_{}'.format(idx))
  70. x2 = slim.convolution2d(x2, channel * 2, [3, 3], activation_fn=None)
  71. x2 = tf.nn.leaky_relu(x2)
  72. h1, w1 = tf.shape(x2)[1], tf.shape(x2)[2]
  73. x3 = tf.image.resize_bilinear(x2, (h1 * 2, w1 * 2))
  74. x3 = slim.convolution2d(
  75. x3 + x1, channel * 2, [3, 3], activation_fn=None)
  76. x3 = tf.nn.leaky_relu(x3)
  77. x3 = slim.convolution2d(x3, channel, [3, 3], activation_fn=None)
  78. x3 = tf.nn.leaky_relu(x3)
  79. h2, w2 = tf.shape(x3)[1], tf.shape(x3)[2]
  80. x4 = tf.image.resize_bilinear(x3, (h2 * 2, w2 * 2))
  81. x4 = slim.convolution2d(x4 + x0, channel, [3, 3], activation_fn=None)
  82. x4 = tf.nn.leaky_relu(x4)
  83. x4 = slim.convolution2d(x4, 3, [7, 7], activation_fn=None)
  84. # x4 = tf.clip_by_value(x4, -1, 1)
  85. return x4
  86. def disc_sn(x,
  87. scale=1,
  88. channel=32,
  89. patch=True,
  90. name='discriminator',
  91. reuse=False):
  92. with tf.variable_scope(name, reuse=reuse):
  93. for idx in range(3):
  94. x = conv_spectral_norm(
  95. x,
  96. channel * 2**idx, [3, 3],
  97. stride=2,
  98. name='conv{}_1'.format(idx))
  99. x = tf.nn.leaky_relu(x)
  100. x = conv_spectral_norm(
  101. x, channel * 2**idx, [3, 3], name='conv{}_2'.format(idx))
  102. x = tf.nn.leaky_relu(x)
  103. if patch is True:
  104. x = conv_spectral_norm(x, 1, [1, 1], name='conv_out')
  105. else:
  106. x = tf.reduce_mean(x, axis=[1, 2])
  107. x = slim.fully_connected(x, 1, activation_fn=None)
  108. return x
  109. if __name__ == '__main__':
  110. pass