反捲積與反捲積核的初始化問題
阿新 • • 發佈:2018-11-06
導論:
https://blog.csdn.net/qq_30638831/article/details/81532892
https://cv-tricks.com/image-segmentation/transpose-convolution-in-tensorflow/
https://zhuanlan.zhihu.com/p/38964806
tf.nn.conv2d_transpose(
conv, 卷積後的結果 ,假設為 (16,375,250,64)
權重的初始化, 使用線性插值,請參考後面, [3,3,3,64] [kernel,kernel,輸出特徵個數,輸入特徵個數],
輸出的初始化, [16,750,500,3] [batch,height,width,chanel] chanel必須與輸出特徵個數相等
strides=[1,2,2,1],padding='SAME'
)
conts = tf.nn.conv2d_transpose(pool,kernel2,output_shape,strides=[1,2,2,1],padding='SAME')
插值的目的: 把影象更精確的語義分割與得到原畫素
差值等大小的filter:
from math import ceil import numpy as np import tensorflow as tf def __get_deconv_filter(f_shape): """ Compute bilinear filter and return it """ filt_width = f_shape[0] #計算kernel的寬 filt_height = f_shape[1] #計算kernel的長 half_width = ceil(filt_width /2.0) center = (2 * half_width - 1 - half_width % 2) / (2.0 * half_width) # 計算某點的權值 對這個點進行插值 bilinear = np.zeros([filt_width, filt_height]) for x in range(filt_width): for y in range(filt_height): value = (1 - abs(x / half_width - center)) * (1 - abs(y / half_width - center)) bilinear[x, y] = value weights = np.zeros(f_shape) for i in range(f_shape[2]): weights[:, :, i, i] = bilinear print(weights[:, :, i, i]) init = tf.constant_initializer(value=weights, dtype=tf.float32) return tf.get_variable(name="up_filter", initializer=init, shape=weights.shape) a = __get_deconv_filter([3, 3, 3, 3])
差值翻倍的kernel:
def get_kernel_size(factor):
"""
Find the kernel size given the desired factor of upsampling.
"""
#獲取kernel的大小
return 2 * factor - factor % 2
def upsample_filt(size):
"""
Make a 2D bilinear kernel suitable for upsampling of the given (h, w) size.
"""
factor = (size + 1) // 2
if size % 2 == 1:
center = factor - 1
else:
center = factor - 0.5
og = np.ogrid[:size, :size]
return (1 - abs(og[0] - center) / factor) * \
(1 - abs(og[1] - center) / factor)
def bilinear_upsample_weights(factor, number_of_classes):
"""
Create weights matrix for transposed convolution with bilinear filter
initialization.
"""
filter_size = get_kernel_size(factor)
weights = np.zeros((filter_size,
filter_size,
3,
4), dtype=np.float32)
upsample_kernel = upsample_filt(filter_size)
for i in range(3):
weights[:, :, i, i] = upsample_kernel
return weights
print(bilinear_upsample_weights(2,21).shape)
import tensorflow as tf
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from math import ceil
'''
一張圖片的反捲積
'''
im = Image.open('timg.jpg')
images = np.asarray(im)
print(images.shape)
images = np.reshape(images,[1,750,500,3])
img = tf.Variable(images,dtype=tf.float32)
# kernel = tf.get_variable(name='a',shape=[3, 3, 3, 3], dtype=tf.float32,
# initializer=tf.contrib.layers.xavier_initializer())
# 卷積核
kernel = tf.get_variable(name='a',shape=[3, 3, 3, 64], dtype=tf.float32,
initializer=tf.contrib.layers.xavier_initializer())
def __get_deconv_filter(f_shape):
"""
Compute bilinear filter and return it
"""
filt_width = f_shape[0] #計算kernel的寬
filt_height = f_shape[1] #計算kernel的長
half_width = ceil(filt_width /2.0)
center = (2 * half_width - 1 - half_width % 2) / (2.0 * half_width) # 計算某點的權值 對這個點進行插值
bilinear = np.zeros([filt_width, filt_height])
for x in range(filt_width):
for y in range(filt_height):
value = (1 - abs(x / half_width - center)) * (1 - abs(y / half_width - center))
bilinear[x, y] = value
weights = np.zeros(f_shape)
for i in range(f_shape[2]):
weights[:, :, i, i] = bilinear
print(weights[:, :, i, i])
init = tf.constant_initializer(value=weights,
dtype=tf.float32)
return init
# 反捲積核
kernel2 = tf.get_variable(name='a1',shape=[3, 3, 3, 64], dtype=tf.float32,
initializer=__get_deconv_filter([3,3,3,64]))
#tf.nn.conv2d(input=input_op, filter=weights, strides=[1, dh, dw, 1], padding="SAME")
# 卷積
conv1 = tf.nn.conv2d(input=img, filter=kernel,strides=[1, 1, 1, 1], padding="SAME")
# print(conv1)
# 池化
pool = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
shape_ = pool.get_shape().as_list()
print(shape_) #[1, 375, 250, 64]
output_shape = [shape_[0], shape_[1] * 2, shape_[2] * 2, 3]
print('pool:',pool.get_shape())
# 反捲積操作
conts = tf.nn.conv2d_transpose(pool,kernel2,output_shape,strides=[1,2,2,1],padding='SAME')
# print(conv1.get_shape())
a = tf.transpose(conts, [0, 3, 1, 2])
b = tf.transpose(tf.squeeze(a) , [1,2,0])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# conv1_convert = sess.run(tf.transpose(conts, [0, 3, 1, 2]))
# fig6, ax6 = plt.subplots(nrows=3, ncols=8, figsize=(8, 8))
# plt.title('Pool2 32x7x7')
# for i in range(8):
# for j in range(8):
# ax6[i][j].imshow(conv1_convert[0][(i + 1) * j])
# plt.show()
plt.imshow(sess.run(b))
plt.show()