1. tf.nn.moments(x, axes=[0, 1, 2])  # 对前三个维度求平均值和标准差,结果为最后一个维度,即对每个feature_map求平均值和标准差

参数说明:x为输入的feature_map, axes=[0, 1, 2] 对三个维度求平均,即每一个feature_map都获得一个平均值和标准差

2.with tf.control_dependencies([train_mean, train_var]): 即执行with里面的操作时,会先执行train_mean 和 train_var

参数说明:train_mean表示对pop_mean进行赋值的操作,train_var表示对pop_var进行赋值的操作

3.tf.cond(is_training, bn_train, bn_inference)  # 如果is_training为真,执行bn_train函数操作,如果为假,执行bn_inference操作

参数说明:is_training 为真和假,bn_train表示训练的normalize, bn_inference表示测试的normalize

4. tf.nn.atrous_conv2d(x, filters, dilated, padding) # 进行空洞卷积操作,用于增加卷积的感受野

参数说明:x表示输入样本,filter表示卷积核,dilated表示卷积核的补零个数,padding表示对feature进行补零操作

5. tf.nn.conv2d_transpose(x, filters, output_size, strides) # 进行反卷积操作

参数说明:x表示输入样本,filter表示卷积核,output_size表示输出的维度, strides表示图像扩大的倍数

6.tf.nn.batch_normalization(x, mean, var, beta, scale, episilon) # 进行归一化操作

参数说明: x表示输入样本,mean表示卷积的平均值,var表示卷积的标准差,beta表示偏差,scale表示标准化后的范围,episilon防止分母为0

7.tf.train.get_checkpoint_state('./backup') # 判断用于进行model保存的文件中是否有checkpoint,即是否之前已经有过保存的sess

参数说明:'./backup'进行sess保存的文件名

原理的话,使用论文中的图进行说明, 这是论文中的效果图,我们可以看出不管是场景还是人脸都有较好的复原效果

下面是论文的结构图, 主要是有2个结构组成,

第一个结构是全卷机填充网络:首先使用一个mask和图片进行组合,构成了具有空缺的图片,将空缺图片输入到全卷积中,经过stride等于2,做两次的向下卷积,然后经过4个dilated_conv(空洞卷积),为了在不损失维度的情况下,增加卷积核的视野,最后使用补零的反转卷积进行维度的升高,再经过最后两层卷积构成了图片。

第二个结构是global_discrimanator 和 local_discimanator

对于global_x输入的大小为全图的大小,而local_x的输入大小为全图大小的一半,上图的mask的大小为96-128且在local_x的内部,取值的范围为随机值

global_x 和 local_x经过卷积后,输出1024的输出,我们将输出进行串接tf.concat,对最后的输出结果[1]进行预测,判别图片为实际图片(真)还是经过填充的图片(假)

网络系数的展示

      

填充网络(卷积-空洞卷积-反卷积)                     全局判别网络(卷积-全连接)                                局部判别网络(卷积-全连接)               串接网络(全连接)

训练步骤:为了使得对抗网络训练更加的有效,我们需要先对填充网络进行预训练,然后是对判别网络进行训练,最后将生成网络和判别网络放在一起进行训练

这里说明一下,填充 网络的损失值是mse,即tf.l2_loss()  判别网络的损失值是tf.reduce_mean(tf.nn.softmax...logits)

代码:代码主要由五个.py文件构建,

1.to_npy进行图片的预处理,并将数据保存为.npy文件,

2.load.py 使用np.load进行x_train和x_test数据的读取

3.train.py 主要进行参数的训练,并且构造出mask_batch, local_x和local_complement

4.network用于进行模型结构的搭建,构建生成网络和判别网络,同时获得生成网络和判别网络的损失值

5.layer 用于卷积,反卷积,全连接,空洞卷积等函数的构建

数据的准备:to_npy

  1. import numpy as np
  2. import tensorflow as tf
  3. import glob
  4. import cv2
  5. import os
  6.  
  7. # 将处理好的图片进行保存,为了防止经常需要处理图片
  8. # 进行数据的压缩
  9. IMAGE_SIZE = 128
  10. # 训练集的比例
  11. train_ep = 0.9
  12. x = []
  13. # 循环文件中的所有图片的地址
  14. pathes = glob.glob('/data/*jpg')
  15. # 循环前500个图片的地址
  16. for path in pathes[:500]:
  17. # 使用cv2.imread读取图片
  18. img = cv2.imread(path)
  19. # 将图片进行维度的变换
  20. img = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE))
  21. # 将读入的图片从BGR转换为RGB
  22. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  23. # 将图片添加到列表中
  24. x.append(img)
  25. # 如果不存在./npy文件
  26. if not os.path.exists('./npy'):
  27. # 使用os.makedirs进行创建文件npy
  28. os.makedirs('./npy')
  29.  
  30. # 获得train的索引
  31. p = len(x) * train_ep
  32. # 训练集x
  33. train_x = x[:p]
  34. # 测试集x
  35. test_x = x[p:]
  36. # 将预处理好的图片保存为.npy文件
  37. np.save('./npy/x_train.npy', train_x)
  38. np.save('./npy/x_test.npy', test_x)

train.py

  1. import numpy as np
  2. import tensorflow as tf
  3. import os
  4. from network import *
  5. import load
  6. import tqdm
  7. import cv2
  8.  
  9. # 第一步:定义超参数
  10. IMAGE_SIZE = 128 # 输入图片的大小
  11. LOCAL_SIZE = 64 # local的大小
  12. HOL_MIN = 24 # 洞的最小值
  13. HOL_MAX = 48 # 洞的最大值
  14. LEARNING_RATE = 1e-3 # 学习率
  15. BATCH_SIZE = 1 # batch_size大小
  16. PRETRAIN_NUM = 100 # 对生成网络预训练的次数
  17.  
  18. def train():
  19. # 第二步:构造输入的初始化参数
  20. x = tf.placeholder(tf.float32, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3]) # 图片x,维度为1, 128, 128, 3
  21. mask = tf.placeholder(tf.float32, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 1]) # 掩模mask, 1, 128, 128, 1用于生成图片空白区域
  22. x_local = tf.placeholder(tf.float32, [BATCH_SIZE, LOCAL_SIZE, LOCAL_SIZE, 3]) # 图片x部分图像,维度为1, 64, 64, 3
  23. completion_global = tf.placeholder(tf.float32, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3]) # 生成图像的维度,1, 128,128,3
  24. completion_local = tf.placeholder(tf.float32, [BATCH_SIZE, LOCAL_SIZE, LOCAL_SIZE, 3]) # 生成图像部分图像,1, 64, 64, 3
  25. is_training = tf.placeholder(tf.bool, []) # 是够进行训练,在batch_normalize中使用
  26.  
  27. # 第三步:调用network,构造网络框架,包括生成网络,判别网络,以及其生成和判别的损失值
  28. model = Network(x, mask, x_local, completion_global, completion_local, is_training, BATCH_SIZE)
  29.  
  30. # 第四步:使用tf.session 构造sess
  31. sess = tf.Session()
  32.  
  33. # 第五步:初始化global_step和epoch
  34. global_step = tf.Variable(0, name='global_step', trainable=False)
  35. epoch = tf.Variable(0, name='epoch', trainable=False)
  36. # 第六步:构造自适应梯度下降器,获得生成网络和判别网络损失值下降操作
  37. opt = tf.train.AdamOptimizer(LEARNING_RATE)
  38. g_loss_op = opt.minimize(model.g_loss, global_step=global_step)
  39. d_loss_op = opt.minimize(model.d_loss, global_step=global_step)
  40. # 第七步:使用sess.run进行初始化操作
  41. init = tf.global_variables_initializer()
  42. sess.run(init)
  43. # 第八步:如果存在./backup文件,就使用saver.restore()加载sess
  44. if tf.train.get_checkpoint_state('./backup'):
  45. saver = tf.train.Saver()
  46. saver.restore(sess, './backup/latest')
  47. # 第九步:获得训练集和测试集,使用load中定义的load函数, 并对读取的图片做归一化操作
  48. x_train, x_test = load.load()
  49. x_train = np.array([a/127.5 - 1 for a in x_train])
  50. x_test = np.array([a/127.5 - 1 for a in x_test])
  51. # 定义一个epoch迭代的次数
  52. step_num = int(len(x_train)/BATCH_SIZE)
  53.  
  54. while True:
  55. # 第十步:将epoch值进行+1操作
  56. sess.run(tf.assign_add(epoch, 1))
  57. # 对输入的x_train进行洗牌操作,每次迭代
  58. np.random.shuffle(x_train)
  59. # 第十一步:如果当前迭代的次数小于预训练,进行生成网络的训练
  60. if sess.run(epoch) <= PRETRAIN_NUM:
  61. # 迭代每个epoch,每次迭代的大小为一个batch_size
  62. for i in tqdm.tqdm(range(step_num)):
  63. # 获得一个batch_size的图片
  64. x_batch = x_train[BATCH_SIZE*i:(i+1)*BATCH_SIZE]
  65. # 获得points_batch, 和一个batch_size的掩模
  66. points_batch, masks_batch = get_points()
  67. # 将x和mask_batch,is_training 传入,进行g_loss_op即损失值的降低
  68. _, _g_loss = sess.run([g_loss_op, model.g_loss], feed_dict={x:x_batch, mask:masks_batch, is_training:True})
  69. # 进行验证操作
  70. # 对x_test进行洗牌操作
  71. np.random.shuffle(x_test)
  72. # 获得一个BATHC_SIZE的大小
  73. x_batch = x_test[:BATCH_SIZE]
  74. # 获得一个batch_size 的生成图片,执行model.completion
  75. completion = sess.run([model.completion], feed_dict={x:x_batch, mask:masks_batch, is_training:False})
  76. # 取出其中一张图片,做归一化的反操作,还原回原始图片
  77. sample = np.array((completion[0] + 1) * 127.5, dtype=np.uint8)
  78. # 将图片进行保存,使用cv2.imwrite
  79. cv2.imwrite('{}_epoch.jpg'.format('{0:06d}'.format(epoch)), cv2.cvtColor(sample, cv2.COLOR_RGB2BGR))
  80. # 将参数保存在./backup/latest
  81. saver = tf.train.Saver()
  82. saver.save(sess, './backup/latest', write_meta_graph=False)
  83. # 如果次数为100次,就将参数保存在/backup/pre_train
  84. if sess.run(epoch) == PRETRAIN_NUM:
  85. saver.save(sess, './backup/pre_train', write_meta_graph=False)
  86.  
  87. # 第十二步:如果epoch大于预训练的次数,就对生成网络和判别网络进行同时的训练
  88. else:
  89. # 循环一个epoch
  90. for i in tqdm.tqdm(range(step_num)):
  91. # 获得一个batch的图片
  92. x_batch = x_train[BATCH_SIZE*i:(i+1)*BATCH_SIZE]
  93. # 获得一个batch的点坐标,和一个batch的掩模
  94. points_batch, masks_batch = get_points()
  95. # 初始化g_loss
  96. g_loss_value = 0
  97. # 初始化d_loss
  98. d_loss_value = 0
  99. # 执行g_loss_op降低g_loss损失值,同时执行self.completion,获得生成图片completion
  100. _, completion, g_loss = sess.run([g_loss_op, model.completion, model.g_loss], feed_dict={x:x_batch, mask:masks_batch, is_training:True})
  101. # 将g_loss添加到g_loss_value
  102. g_loss_value += g_loss
  103. # 构造一个batch的x_local
  104. x_local_batch = []
  105. # 构造一个batch的completion_batch
  106. completion_local_batch = []
  107. # 循环batch_size
  108. for i in range(BATCH_SIZE):
  109. # 获得point_batch中一个点坐标
  110. x1, y1, x2, y2 = points_batch[i]
  111. # 构造一个x_local, 添加到x_local_batch
  112. x_local_batch.append(x_batch[i][y1:y2, x1:x2, :])
  113. # 构造一个completion_local, 添加到completion_local_batch
  114. completion_local_batch.append(completion[i][y1:y2, x1:x2])
  115. # 执行d_loss_op,降低d_loss的损失值
  116. _, d_loss = sess.run([d_loss_op, model.d_loss], feed_dict={x:x_batch, mask:masks_batch, x_local:x_local_batch, completion_global:completion,
  117. completion_local:completion_local_batch, is_training:True})
  118. # 将损失值进行添加
  119. d_loss_value += d_loss
  120. # 清洗x_test
  121. np.random.shuffle(x_test)
  122. # 获得一个x_batch
  123. x_batch = x_test[:BATCH_SIZE]
  124. # 输入测试图片获得生成图片
  125. completion = sess.run([model.completion], feed_dict={x:x_batch, mask:masks_batch, is_training:False})
  126. # 取生成图片的第一张图片,进行反归一化
  127. sample = np.array((completion[0] + 1) * 127.5, dtype=np.uint8)
  128. # 使用cv2.imwrite保存图片
  129. cv2.imwrite('{}.epoch'.format('{0:06d}'.format(epoch)), cv2.cvtColor(sample, cv2.COLOR_RGB2BGR))
  130. # 构造tf.train.Saver() 进行sess的保存操作
  131. saver = tf.train.Saver()
  132. saver.save(sess, './backup/latest', write_meta_graph=False)
  133.  
  134. def get_points():
  135. # 构造点列表,用于构建局部图像
  136. points = []
    # 构造掩模列表,用于构造残缺的原始图像
  137. maskes = []
  138. for i in range(BATCH_SIZE):
    # 获得左上角两个点,范围为[0, IMAGE_SIZE-LOCAL_SIZE]
  139. x1, y1 = np.random.randint(0, IMAGE_SIZE-LOCAL_SIZE, 2)
    # 获得右下角的两个点,分别进行相加操作
  140. x2, y2 = np.array([x1, y1]) + LOCAL_SIZE
    # 将坐标添加到points
  141. points.append([x1, y1, x2, y2])
  142. # 在H0L_MIN和HOL_MAX范围内构造w,h
  143. w, h = np.random.randint(HOL_MIN, HOL_MAX, 2)
    # 左上角x轴的坐标为x1+(0, LOCAL_SIZE-w)的范围内
  144. p1 = x1 + np.random.randint(0, LOCAL_SIZE-w)
    # 左上角y轴的坐标为y1+(0, LOCAL_SIZE-h)的范围内
  145. q1 = y1 + np.random.randint(0, LOCAL_SIZE-h)
  146. # 右边的x坐标为p1+w
  147. p2 = p1 + w
    # 右边的y坐标为q1+h
  148. q2 = q1 + h
    # 构造全为0的3维矩阵
  149. m = np.zeros(shape=[IMAGE_SIZE, IMAGE_SIZE, 1])
    # 在该范围内的值为1, 并进行添加
  150. m[q1:q2, p1:p2, :] = 1
  151. maskes.append(m)
  152. # 返回points和掩模的数组
  153. return np.array(points), np.array(maskes)
  154.  
  155. if __name__ == '__main__':
  156. train()

代码:network.py: 构建Network类,构造生成网络,生成self.completion, 构造判别网络,获得x,x_local的输出结果self.real,获得global_completion, local_completion的输出结果self.fake, 使用l2_loss构造生成网络的损失值g_loss, 使用交叉熵构造判别网络的损失值d_loss

第一步:使用self.generator构造生成网络, 输入为x*(1-mask), is_training

第二步:使用self.imition * mask + x * (1-mask) 构造self.completion 即生成的图片

第三步:使用self.discrimator, 输入为x, x_local, is_training, reuse=False, 用于真实样本的判别self.real

第四步:使用self.discrimator, 输入为global_complement, local_complement, is_training, reuse=True, 用于生成样本的判别self.fake

第五步:使用tf.nn.l2_loss生成mse的损失值,用于生成网络的损失值,self.g_loss

第六步:使用tf.reduce_mean(tf.sotfmax..logits(labels=tf.ones_like(real), logits=real)) 获得真实的交叉熵,同理获得生成样本的交叉熵,将两者进行加和乘以系数,获得最终的损失值即self.d_loss。

第七步:使用tf.get_collection(tf.GraphKey.TRAINABEL_VARIABLES, scope=‘generator’) 和scope = ‘discrimator’获得生成网络和判别网络的参数

  1. import tensorflow as tf
  2. import numpy as np
  3. from layer import *
  4.  
  5. class Network:
  6.  
  7. def __init__(self, x, mask, x_local, completion_global, completion_local, is_training, batch_size):
  8. self.batch_size = batch_size
  9. # 第一步: 构造生成网络,获得生成的图片,(1-mask) * x 构成残缺空白的输入图片
  10. self.imition = self.generator((1-mask)*x, is_training)
  11. # 第二步:将生成图片部分区域与残缺空白的输入图片进行拼接,获得最终的图片
  12. self.completion = mask * self.imition + (1-mask)*x
  13. # 第三步:定义discriminator,对x和x_local判断real结果
  14. self.real = self.discrimator(x, x_local, is_training, reuse=False)
  15. # 第四步:使用discrimanator,对completion_global 和 completion_local判断fake结果
  16. self.fake = self.discrimator(completion_global, completion_local, is_training, reuse=True)
  17. # 第五步:定义生成网络的损失值,使用mse
  18. self.g_loss = self.cal_g_loss(x, self.completion)
  19. # 第六步:定义判别网络的损失值,使用交叉熵, 即real判别为1,fake判别为0
  20. self.d_loss = self.cal_d_loss(self.real, self.fake)
  21. # 第七步:获得生成网络的参数
  22. g_variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='generator')
  23. d_variables = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='discrimator')
  24.  
  25. # 判别网络的损失值,输入为
  26. def cal_d_loss(self, real, fake):
  27. # 损失值系数
  28. epsilon = 4e-4
  29. # 真实样本的交叉熵损失值, 标签为1
  30. real_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=real, labels=tf.ones_like(real)))
  31. # 生成样本的交叉熵损失值,标签为0
  32. fake_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=fake, labels=tf.zeros_like(fake)))
  33. # 将真实样本和生成样本的损失值进行加和,并进行损失系数的乘积
  34. return tf.add(real_loss, fake_loss) * epsilon
  35.  
  36. # 生成网络的损失值计算,使用的是mse
  37. def cal_g_loss(self, x, completion):
  38. # 使用l2_loss损失值计算
  39. return tf.nn.l2_loss(x - completion)
  40.  
  41. # 构建判别网络
  42. def discrimator(self, x, x_local, is_training, reuse):
  43. # 构建完整图片的判别网络
  44. def global_discrimator(x):
  45. # 设置完整图片判别网络参数的范围
  46. with tf.variable_scope('global'):
  47. # 第一层卷积,卷积大小为5*5*3*64,步长为2
  48. with tf.variable_scope('conv1'):
  49. x = conv_layer(x, [5, 5, 3, 64], 2)
  50. x = batch_normalize(x, is_training)
  51. x = tf.nn.relu(x)
  52. # 第二层卷积,卷积大小为5*5*3*64,步长为2
  53. with tf.variable_scope('conv2'):
  54. x = conv_layer(x, [5, 5, 64, 128], 2)
  55. x = batch_normalize(x, is_training)
  56. x = tf.nn.relu(x)
  57. # 第三层卷积,卷积大小为5*5*3*64,步长为2
  58. with tf.variable_scope('conv3'):
  59. x = conv_layer(x, [5, 5, 128, 256], 2)
  60. x = batch_normalize(x, is_training)
  61. x = tf.nn.relu(x)
  62. # 第四层卷积,卷积大小为5*5*3*64,步长为2
  63. with tf.variable_scope('conv4'):
  64. x = conv_layer(x, [5, 5, 256, 512], 2)
  65. x = batch_normalize(x, is_training)
  66. x = tf.nn.relu(x)
  67. # 第五层卷积,卷积大小为5*5*3*64,步长为2
  68. with tf.variable_scope('conv5'):
  69. x = conv_layer(x, [5, 5, 512, 512], 2)
  70. x = batch_normalize(x, is_training)
  71. x = tf.nn.relu(x)
  72. # 构建全连接层,输出为1024
  73. with tf.variable_scope('fc'):
  74. # 对卷积层的输出进行维度变换
  75. x = flatten_conv(x)
  76. # 进行全连接操作,输出的维度为1024
  77. x = fc_layer(x, 1024)
  78.  
  79. return x
  80. # 构造局部图像的判别网络
  81. def local_discrimator(x):
  82. # 设置局部网络判别的参数范围
  83. with tf.variable_scope('local'):
  84. # 第一层卷积,卷积大小为5*5*3*64,步长为2
  85. with tf.variable_scope('conv1'):
  86. x = conv_layer(x, [5, 5, 3, 64], 2)
  87. x = batch_normalize(x, is_training)
  88. x = tf.nn.relu(x)
  89. # 第二层卷积,卷积大小为5*5*3*64,步长为2
  90. with tf.variable_scope('conv2'):
  91. x = conv_layer(x, [5, 5, 64, 128], 2)
  92. x = batch_normalize(x, is_training)
  93. x = tf.nn.relu(x)
  94. # 第三层卷积,卷积大小为5*5*3*64,步长为2
  95. with tf.variable_scope('conv3'):
  96. x = conv_layer(x, [5, 5, 128, 256], 2)
  97. x = batch_normalize(x, is_training)
  98. x = tf.nn.relu(x)
  99. # 第四层卷积,卷积大小为5*5*3*64,步长为2
  100. with tf.variable_scope('conv4'):
  101. x = conv_layer(x, [5, 5, 256, 512], 2)
  102. x = batch_normalize(x, is_training)
  103. x = tf.nn.relu(x)
  104. # 构造全连接网络,输出结构为1024
  105. with tf.variable_scope('fc'):
  106. x = flatten_conv(x)
  107. x = fc_layer(x, 1024)
  108.  
  109. return x
  110. # 设置判别网络的参数范围
  111. with tf.variable_scope('discrimator', reuse=reuse):
  112. # 带入x_local获得局部图像的判别输出值
  113. local_disc = local_discrimator(x_local)
  114. # 带入x获得完整图像的判别输出值
  115. global_disc = global_discrimator(x)
  116. with tf.variable_scope('concatenation'):
  117. # 将局部图像输出值与全局图像进行串接,维度为[batch_size, 2048]
  118. output = tf.concat((local_disc, global_disc), axis=1)
  119. # 接上一个全连接,最后的输出值维度为1
  120. output = fc_layer(output, 1)
  121. # 返回判别结果
  122. return output
  123.  
  124. # 用于进行生成网络,输入为拥有空白区域的图片,is_training表示是否是在训练
  125. def generator(self, x, is_training):
  126. # 定义参数的范围为'generator'
  127. with tf.variable_scope('generator'):
  128. # 第一层卷积层
  129. with tf.variable_scope('conv1'):
  130. # 卷积核的大小为[5, 5, 3, 64],步长为1
  131. x = conv_layer(x, [5, 5, 3, 64], 1)
  132. # 归一化操作
  133. x = batch_normalize(x, is_training)
  134. # 非线性激活
  135. x = tf.nn.relu(x)
  136. # 第二层卷积
  137. with tf.variable_scope('conv2'):
  138. # 卷积核的大小为[3, 3, 64, 128], 步长为2, 维度变为原来的1/2
  139. x = conv_layer(x, [3, 3, 64, 128], 2)
  140. # 归一化操作
  141. x = batch_normalize(x, is_training)
  142. # 非线性激活
  143. x = tf.nn.relu(x)
  144. # 第三层卷积操作
  145. with tf.variable_scope('conv3'):
  146. # 卷积核的大小为[3, 3, 128, 128], 步长为1
  147. x = conv_layer(x, [3, 3, 128, 128], 1)
  148. # 归一化操作
  149. x = batch_normalize(x, is_training)
  150. # 非线性激活
  151. x = tf.nn.relu(x)
  152. # 第四层卷积操作
  153. with tf.variable_scope('conv4'):
  154. # 卷积核的大小为[3, 3, 128, 256], 步长为2
  155. x = conv_layer(x, [3, 3, 128, 256], 2)
  156. # 归一化操作
  157. x = batch_normalize(x, is_training)
  158. # 非线性激活
  159. x = tf.nn.relu(x)
  160. # 第五层卷积操作
  161. with tf.variable_scope('conv5'):
  162. # 卷积核的大小为[3, 3, 256, 256], 步长为1
  163. x = conv_layer(x, [3, 3, 256, 256], 1)
  164. # 归一化操作
  165. x = batch_normalize(x, is_training)
  166. # 非线性激活
  167. x = tf.nn.relu(x)
  168. # 第六层卷积操作
  169. with tf.variable_scope('conv6'):
  170. # 卷积核的大小为[3, 3, 256, 256], 步长为1
  171. x = conv_layer(x, [3, 3, 256, 256], 1)
  172. # 归一化操作
  173. x = batch_normalize(x, is_training)
  174. # 非线性激活
  175. x = tf.nn.relu(x)
  176. # 第一层空洞卷积
  177. with tf.variable_scope('dilated1'):
  178. # 卷积核的大小为[3, 3, 256, 256], 卷积补零的个数为1
  179. x = dilated_conv_layer(x, [3, 3, 256, 256], 2)
  180. # 归一化操作
  181. x = batch_normalize(x, is_training)
  182. # 非线性激活
  183. x = tf.nn.relu(x)
  184. # 第二层空洞卷积
  185. with tf.variable_scope('dilated2'):
  186. # 卷积核的大小为[3, 3, 256, 256], 卷积补零的个数为3
  187. x = dilated_conv_layer(x, [3, 3, 256, 256], 4)
  188. # 归一化
  189. x = batch_normalize(x, is_training)
  190. # 非线性激活
  191. x = tf.nn.relu(x)
  192. # 第三层空洞卷积
  193. with tf.variable_scope('dilated3'):
  194. # 卷积核的大小为[3, 3, 256, 256], 卷积补零的个数为7
  195. x = dilated_conv_layer(x, [3, 3, 256, 256], 8)
  196. # 归一化操作
  197. x = batch_normalize(x, is_training)
  198. # 非线性激活
  199. x = tf.nn.relu(x)
  200. # 第四层空洞卷积
  201. with tf.variable_scope('dilated4'):
  202. # 卷积核的大小为[3, 3, 256, 256], 卷积补零的个数为15
  203. x = dilated_conv_layer(x, [3, 3, 256, 256], 16)
  204. # 归一化操作
  205. x = batch_normalize(x, is_training)
  206. # 非线性激活
  207. x = tf.nn.relu(x)
  208. # 第七层卷积
  209. with tf.variable_scope('conv7'):
  210. # 卷积的维度为[3, 3, 256, 256], 步长为1
  211. x = conv_layer(x, [3, 3, 256, 256], 1)
  212. # 归一化操作
  213. x = batch_normalize(x, is_training)
  214. # 激活
  215. x = tf.nn.relu(x)
  216. # 第八层卷积
  217. with tf.variable_scope('conv8'):
  218. # 卷积的维度为[3, 3, 256, 256], 步长为1
  219. x = conv_layer(x, [3, 3, 256, 256], 1)
  220. # 归一化操作
  221. x = batch_normalize(x, is_training)
  222. # 激活操作
  223. x = tf.nn.relu(x)
  224. # 第一层反卷积,将维度提升为原来的2倍,即从32,32变为64,64
  225. with tf.variable_scope('deconv1'):
  226. # 反卷积,[4, 4, 128, 256] 4 和 4表示卷积的大小,256表示输入维度,128表示输出维度,[self.batch_size, 64, 64, 128]表示输出的大小,2表示扩张的倍数
  227. x = deconv_layer(x, [4, 4, 128, 256], [self.batch_size, 64, 64, 128], 2)
  228. # 归一化操作
  229. x = batch_normalize(x, is_training)
  230. # 激活操作
  231. x = tf.nn.relu(x)
  232.  
  233. with tf.variable_scope('conv9'):
  234. # 第九层卷积,卷积核大小为[3, 3, 128, 128], 步长为1
  235. x = conv_layer(x, [3, 3, 128, 128], 1)
  236. # 归一化操作
  237. x = batch_normalize(x, is_training)
  238. # 激活操作
  239. x = tf.nn.relu(x)
  240.  
  241. with tf.variable_scope('deconv2'):
  242. # 进行反卷积,将维度变为[128, 128]
  243. x = deconv_layer(x, [4, 4, 64, 128], [self.batch_size, 128, 128, 64], 2)
  244. # 归一化操作
  245. x = batch_normalize(x, is_training)
  246. # 激活
  247. x = tf.nn.relu(x)
  248.  
  249. with tf.variable_scope('conv10'):
  250. # 第十层卷积,进行维度的降低,即把64降维32
  251. x = conv_layer(x, [3, 3, 64, 32], 1)
  252. x = batch_normalize(x, is_training)
  253. x = tf.nn.relu(x)
  254.  
  255. with tf.variable_scope('conv11'):
  256. # 第十一层,进行维度的降低,把32层的维度转换为3层的维度,即图像的维度值
  257. x = conv_layer(x, [3, 3, 32, 3], 1)
  258. x = batch_normalize(x, is_training)
  259. x = tf.nn.relu(x)
  260.  
  261. return x

layer.py 用于构建一些基础的网络结构,如卷积层,全连接层,反卷积层,空洞卷积层,归一化层,维度变化层,

  1. import tensorflow as tf
  2.  
  3. # 构造卷积层, 使用的是tf.nn.conv2d
  4. def conv_layer(x, shape, stride):
  5. # 构造卷积核,大小为shape,进行参数更新
  6. filter = tf.get_variable('weight',
  7. shape=shape,
  8. dtype=tf.float32,
  9. initializer=tf.contrib.layers.xavier_initializer(),
  10. trainable=True)
  11. # 进行卷积操作
  12. return tf.nn.conv2d(x, filter, strides=[1, stride, stride, 1], padding='SAME')
  13.  
  14. # 构造归一化操作,测试阶段使用的mean和var为训练阶段的动量平均的mean和var
  15. def batch_normalize(x, is_training, decay=0.99, epsilon=0.001):
  16. # 进行训练时的归一化
  17. def bn_train():
  18. # batch的mean和batch的var, 使用tf.nn.moments获得标准差和均值
  19. batch_mean, batch_var = tf.nn.moments(x, axes=[0, 1, 2])
  20. # 将pop_mean 使用tf.assign进行更新操作,为动量梯度的平均值
  21. train_mean = tf.assign(pop_mean, pop_mean * decay + batch_mean * (1-decay))
  22. # 将pop_var 使用tf.assign进行更新操作,为动量梯度的标准差
  23. train_var = tf.assign(pop_var, pop_var * decay + batch_var * (1-decay))
  24. # 使用tf.control_dependencies,先执行更新操作
  25. with tf.control_dependencies([train_mean, train_var]):
  26. # 进行归一化操作,使用的平均值为当前的batch_mean 和 batch_var, beta和scale需要进行参数更新
  27. return tf.nn.batch_normalization(x, batch_mean, batch_var, beta, scale, epsilon)
  28.  
  29. def bn_inference():
  30. # 测试时的归一化操作,pop_mean和pop_var表示训练时动量梯度的平均值和标准差, beta为偏度,scale为范围
  31. return tf.nn.batch_normalization(x, pop_mean, pop_var, beta, scale, epsilon)
  32.  
  33. # 获得最后一个维度
  34. dim = x.get_shape().as_list()[-1]
  35. # 构造训练过程中的偏度bata
  36. beta = tf.get_variable(
  37. name='beta',
  38. shape=[dim],
  39. dtype=tf.float32,
  40. initializer=tf.truncated_normal_initializer(stddev=0.0),
  41. trainable=True
  42. )
  43. # 构造训练过程中的范围scale
  44. scale = tf.get_variable(
  45. name='scale',
  46. shape=[dim],
  47. dtype=tf.float32,
  48. initializer=tf.truncated_normal_initializer(stddev=0.1),
  49. trainable=True
  50. )
  51. # 构造动量平均的平均值的初始值
  52. pop_mean = tf.get_variable(
  53. name = 'pop_mean',
  54. shape=[dim],
  55. dtype=tf.float32,
  56. initializer=tf.constant_initializer(0.0),
  57. trainable=False
  58. )
  59. # 构造动量平均的标准差的初始值
  60. pop_var = tf.get_variable(
  61. name='pop_var',
  62. shape=[dim],
  63. dtype=tf.float32,
  64. initializer=tf.constant_initializer(1.0),
  65. trainable=False)
  66. # 如果is_training为true执行bn_train, 否者执行bn_inference
  67. return tf.cond(is_training, bn_train, bn_inference)
  68.  
  69. # 构造空洞卷积,dilation表示卷积补零的个数
  70. def dilated_conv_layer(x, shape, dilation):
  71. # filter表示卷积核的构造
  72. filters = tf.get_variable('filters',
  73. shape=shape,
  74. dtype=tf.float32,
  75. initializer=tf.contrib.layers.xavier_initializer(),
  76. trainable=True)
  77. # 进行空洞卷积,dilation表示卷积核补零的大小
  78. return tf.nn.atrous_conv2d(x, filters, dilation, padding='SAME')
  79.  
  80. # 构造反卷积,output_shape表示输出的维度,stride表示扩大的倍数
  81. def deconv_layer(x, filter_shape, output_shape, stride):
  82. # 构造卷积
  83. filters = tf.get_variable(
  84. name = 'weight',
  85. shape=filter_shape,
  86. dtype=tf.float32,
  87. initializer=tf.truncated_normal_initializer(stddev=0.1),
  88. trainable=True
  89. )
  90. return tf.nn.conv2d_transpose(x, filters, output_shape, [1, stride, stride, 1])
  91.  
  92. # 进行维度的变化,用于进行全连接
  93. def flatten_conv(x):
  94. num = x.shape[0]
  95. return tf.reshape(x, [num, -1])
  96.  
  97. # 构造全连接函数
  98. def fc_layer(x, output_dim):
  99. # 获得输入的最后一个维度,用于构造w
  100. input_dim = x.get_shape().as_list()[-1]
  101. # w的维度为input_dim, output_dim
  102. w = tf.get_variable(
  103. name='w',
  104. shape=[input_dim, output_dim],
  105. dtype=tf.float32,
  106. initializer=tf.truncated_normal_initializer(stddev=0.1),
  107. trainable=True
  108. )
  109. # b的维度为output_dim
  110. b = tf.get_variable(
  111. name='b',
  112. shape=[output_dim],
  113. dtype=tf.float32,
  114. initializer=tf.truncated_normal_initializer(stddev=0.0),
  115. trainable=True
  116. )
  117. # 进行点乘操作
  118. return tf.add(tf.matmul(x, w), b)

load.py 进行.npy数据的载入操作

  1. import numpy as np
  2. import tensorflow as tf
  3. import os
  4.  
  5. # dir为data的路径
  6. def load(dir='../data/npy'):
  7. # 使用np.load获得存储好的数据
  8. # 加载训练集
  9. train_x = np.load(os.path.join(dir, 'x_train.npy'))
  10. # 加载验证集
  11. test_x = np.load(os.path.join(dir, 'x_test.npy'))
  12. # 返回训练集和验证集
  13. return train_x, test_x

深度学习原理与框架-图像补全(原理与代码) 1.tf.nn.moments(求平均值和标准差) 2.tf.control_dependencies(先执行内部操作) 3.tf.cond(判别执行前或后函数) 4.tf.nn.atrous_conv2d 5.tf.nn.conv2d_transpose(反卷积) 7.tf.train.get_checkpoint_state(判断sess是否存在的更多相关文章

  1. 深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全

    深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全 原文地址:Image Completion with Deep Learning in TensorFlow by Bra ...

  2. [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练

    [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 目录 [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 0x00 摘要 0 ...

  3. [源码解析] 深度学习分布式训练框架 Horovod (1) --- 基础知识

    [源码解析] 深度学习分布式训练框架 Horovod --- (1) 基础知识 目录 [源码解析] 深度学习分布式训练框架 Horovod --- (1) 基础知识 0x00 摘要 0x01 分布式并 ...

  4. [源码解析] 深度学习分布式训练框架 horovod (2) --- 从使用者角度切入

    [源码解析] 深度学习分布式训练框架 horovod (2) --- 从使用者角度切入 目录 [源码解析] 深度学习分布式训练框架 horovod (2) --- 从使用者角度切入 0x00 摘要 0 ...

  5. 对比深度学习十大框架:TensorFlow 并非最好?

    http://www.oschina.net/news/80593/deep-learning-frameworks-a-review-before-finishing-2016 TensorFlow ...

  6. 作为深度学习最强框架的TensorFlow如何进行时序预测!(转)

    作为深度学习最强框架的TensorFlow如何进行时序预测! BigQuant 2 个月前 摘要: 2017年深度学习框架关注度排名tensorflow以绝对的优势占领榜首,本文通过一个小例子介绍了T ...

  7. 模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理、分类及应用

    模型汇总24 - 深度学习中Attention Mechanism详细介绍:原理.分类及应用 lqfarmer 深度学习研究员.欢迎扫描头像二维码,获取更多精彩内容. 946 人赞同了该文章 Atte ...

  8. [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver

    [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver 目录 [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & ...

  9. [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun背后做了什么

    [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun背后做了什么 目录 [源码解析] 深度学习分布式训练框架 horovod (3) --- Horovodrun ...

随机推荐

  1. React 组件间通信介绍

    React 组件间通信方式简介 React 组件间通信主要分为以下四种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面对这四种情况分别进行介绍:   父组件向子 ...

  2. java web(一):tomcat服务器的安装和简单介绍,与eclipse关联

    一:下载tomcat安装包和安装 这个百度一下就可以了. 安装完以后进入tomcat的安装路径查看 如图所示:有几个目录简单介绍下 bin目录:   存放运行tomcat服务器的相关命令. conf目 ...

  3. UCenter通信原理

    https://www.jb51.net/article/59666.htm 1.用户登录discuz,通过logging.php文件中的函数uc_user_login对post过来的数据进行验证,也 ...

  4. Linux 连接mysql

    连接MYSQL: 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL 找到mysql的安装目录,一般可以直接键入命令mysql -uroot -p,回车后提 ...

  5. Elasticsearch(单节点)

    1 Elasticsearch搭建 1.1 通过Wget下载ElasticSearch安装包wget https://artifacts.elastic.co/downloads/elasticsea ...

  6. docker 创建docker用户组,应用用户加入用户组

    在Linux系统下使用docker,为了避免每次输入命令都需要sudo,可以把用户加入docker用户组 创建docker用户组 sudo groupadd docker 普通用户加入docker用户 ...

  7. httpd2.4.6配置文件解释说明

    本文httpd版本为:2.4.6 ServerRoot 先来看一下httpd.conf配置文件中的ServerRoot默认定义: # cat /etc/httpd/conf/httpd.conf |e ...

  8. VS2015 IIS Express 无法启动 解决办法

    VS2015启动调试时,总是提示“IIS Web Express 无法启动”的错误, 因为其他项目都可以,就这么一个不行,基本就是配置问题,网上的办法都试了,试了都没用,试试以下解决方案: 用记事本或 ...

  9. mac mongodb安装

    1.前往官网下载.tgz文件 2.解压 tar zxf mongo压缩文件 3.配置环境变量:MAVEN_HOME & bin路径 4.创建data & log文件夹 5.执行安装命令 ...

  10. CSS Core Technology

    1. Selector Different types of selectors: Selectors can be divided into the following categories: Si ...