我正在研究可处理输入形状为(None, None, None, 1)
的单通道图像的超分辨率(5x)CNN
假设图像的顶行为
[x, x, x, x, x, y, y, y, y, y]
缩小为5倍的
[x, y]
请考虑一个网络,该网络由步幅为5x5的单个Conv2DTranspose
层和一个常数为9x9的常数矩阵组成。将其应用于[x, y]
会产生
[x, x, x, x, X, x+y, x+y, x+y, x+y, Y, y, y, y, y]
(此处X
,Y
表示从x
,y
生成的像素集的中心)
所以我们已经从2列矩阵变成了14列矩阵。
将此放大后的输出与原始图像进行比较的一种方法是,在原始图像的两边填充(filter_size - stride_size)/2 = (9-5)/2 =2
个条目
[0, 0, x, x, x, x, x, y, y, y, y, y, 0, 0]
然后与我们的降级图像的升级版本很好地吻合
[x, x, x, x, X, x+y, x+y, x+y, x+y, Y, y, y, y, y]
此时,我准备好计算这两行之间的差并计算损失。
但是,人为的4个边界点会造成损失。我显然不在乎这个人为边界区域中的错误。我如何确保这些价值不包括在损失中?
我已经考虑了自定义损失,切片和遮罩层,但是问题是输入的大小可变。如果输入的大小固定,则可以创建一个掩盖张量或根据固定的大小更新值,但是在输入大小可变的情况下,我需要创建一个可变的掩盖张量。
import keras
import numpy as np
model = keras.Sequential()
model.add(keras.layers.Conv2DTranspose(1, (9,9), strides=(5,5), input_shape=(None, None, 1),
kernel_initializer='ones', bias_initializer='zeros'))
#x is downscaled image
x = np.zeros([1,2,2,1])
x[0,0,0,0] = 1
x[0,0,-1,0] = .5
#y is original image
y = np.zeros([1,10,10,1])
y[0,0,:,0]= [1,1,1,1,1,.5,.5,.5,.5,.5]
y_pred = model.predict(x)
paddings = ((0,0),(2,2),(2,2),(0,0))
y_pad = np.pad(y, paddings, mode='constant')
# want keras to calculate loss of
# y_pad[:,2:-2,2:-2,:] - y_pred[:,2:-2,2:-2,:]```
答案 0 :(得分:0)
看起来最简单的修剪填充层的方法是使用具有固定内核和偏移且没有填充的Conv2D层。
depad_kernel = np.zeros([2*padding+1,2*padding+1])
depad_kernel[padding, padding,0,0] = 1
depad_bias = np.zeros([1])
depadded_output = model.add_layer(
keras.layers.Conv2D(1, (2*padding+1, 2*padding+1), strides=(1,1),
weights=[depad_kernel, depad_bias], trainable=False))