Keras Neural Style Transfer:backend.gradients返回None

时间:2018-02-10 22:02:20

标签: python-3.x deep-learning keras conv-neural-network

我正在尝试使用Keras实现神经样式传输,并尽量保持简单。在尝试使用keras的backend.gradients()函数查找渐变时,它返回[None]。我的代码如下:

content_image = cv2.imread("C:/Users/Max/Desktop/IMG_20170331_103755.jpg") 
content_image = cv2.resize(content_image, (512,512))
style_image = cv2.imread("C:/Users/Max/Desktop/starry.jpg")
style_image = cv2.resize(style_image, (512,512))

content_array = np.asarray(content_image, dtype=np.float32)
content_array = np.expand_dims(content_array, axis=0)

style_array = np.asarray(style_image, dtype=np.float32)
style_array = np.expand_dims(style_array, axis=0)

# Constants:

epochs = 1
height = 512
width = 512
num_channels = 3
step_size = 10

content_layer = ['block2_conv2']
style_layer = ['block1_conv2', 'block2_conv2', 'block3_conv3','block4_conv3', 'block5_conv3']

loss_total = backend.variable(0.0)

# VGG16 Model:

model = VGG16(input_shape = [height, width, num_channels],weights='imagenet', include_top=False)

# Defining losses:

def content_loss(Content, Mixed):
    content_loss = backend.mean(backend.square(Mixed - Content))
    return content_loss

def gram(layer):
    flat = backend.reshape(layer, shape=[1, -1])
    gram = backend.dot(flat, backend.transpose(flat))
    return gram

def style_loss(Style, Mixed):
    S_G = gram(Style)
    M_G = gram(Mixed)
    size = height*width
    return backend.sum(backend.square(S_G - M_G)) / (4. * (num_channels ** 2) * (size ** 2))
'''
def denoise(Image):
    loss = backend.mean(backend.abs(Image[:,1:,:,:] - Image[:,:-1,:,:]) +     backend.abs(Image[:,:,1:,:] - Image[:,:,:-1,:]))
    return loss
'''
# Backend Functions:

output_c = backend.function(inputs = [model.layers[0].input] , outputs = [model.get_layer(content_layer[0]).output])
output_s = backend.function(inputs = [model.layers[0].input] , outputs = [model.get_layer(layer).output for layer in style_layer])

content_output = output_c([content_array])
style_output = output_s([style_array])

# Randomly generated image:

Mixed = np.random.uniform(0, 255, [1, height, width, 3]) - 128

# Loop:

for i in range(epochs):

    mixed_c = output_c([Mixed])
    mixed_c = mixed_c[0]

    loss_c = content_loss(content_output[0], mixed_c)

    total = []
    mixed_s = output_s([Mixed])
    for i in range(len(style_layer)):
        style = style_loss(style_output[i], mixed_s[i])
        total.append(style)
        loss_s = backend.sum(total)
    #loss_d = denoise(Mixed)
    loss_total = w_c * loss_c + w_s * loss_s #+ w_d * loss_d
    gradient = backend.gradients(loss_total, Mixed)
    gradient = np.squeeze(gradient)
    step_size = step_size / (np.std(gradient) + 1e-8)
    Mixed -= gradient * step_size

我应该做些什么改变才能使渐变正常工作。我对于出了什么问题一无所知。

谢谢!

1 个答案:

答案 0 :(得分:0)

您正在采用Mixed的渐变,这是一个numpy数组,而不是变量。您需要定义一个张量,其值为Mixed

来自Keras文档:

  

梯度

     

keras.backend.gradients(loss, variables)

     

返回variables w.r.t的渐变。 loss

     

参数

     
      
  • 损失:标量张量最小化。

  •   
  • 变量:变量列表。

  •