Tensorflow gradient is always zero

时间秒杀一切 提交于 2019-12-08 08:56:09

问题


I have written a small Tensorflow program which convolves an image patch by the same convolution kernel num_unrollings times in a row, and then attempts to minimize the mean squared difference between the resulting values and a target output.

However, when I run the model with num_unrollings greater than 1, the gradient of my my loss (tf_loss) term with respect to the convolution kernel (tf_kernel) is zero, so no learning occurs.

Here is the smallest code (python 3) I can come up with which reproduces the problem, sorry about the length:

import tensorflow as tf
import numpy as np

batch_size = 1
kernel_size = 3
num_unrollings = 2

input_image_size = (kernel_size//2 * num_unrollings)*2 + 1

graph = tf.Graph()

with graph.as_default():
    # Input data
    tf_input_images = tf.random_normal(
        [batch_size, input_image_size, input_image_size, 1]
    )

    tf_outputs = tf.random_normal(
        [batch_size]
    )

    # Convolution kernel
    tf_kernel = tf.Variable(
        tf.zeros([kernel_size, kernel_size, 1, 1])
    )

    # Perform convolution(s)
    _convolved_input = tf_input_images
    for _ in range(num_unrollings):
        _convolved_input = tf.nn.conv2d(
            _convolved_input, 
            tf_kernel, 
            [1, 1, 1, 1], 
            padding="VALID"
        )

    tf_prediction = tf.reshape(_convolved_input, shape=[batch_size])

    tf_loss = tf.reduce_mean(
        tf.squared_difference(
            tf_prediction,
            tf_outputs
        )
    )

    # FIXME: why is this gradient zero when num_unrollings > 1??
    tf_gradient = tf.concat(0, tf.gradients(tf_loss, tf_kernel))

# Calculate and report gradient
with tf.Session(graph=graph) as session:

    tf.initialize_all_variables().run()

    gradient = session.run(tf_gradient)

    print(gradient.reshape(kernel_size**2))
    #prints [ 0.  0.  0.  0.  0.  0.  0.  0.  0.]

Thank you for your help!


回答1:


Try replacing

# Convolution kernel
tf_kernel = tf.Variable(
    tf.zeros([kernel_size, kernel_size, 1, 1])
)

with something like:

# Convolution kernel
tf_kernel = tf.Variable(
    tf.random_normal([kernel_size, kernel_size, 1, 1])
)


来源:https://stackoverflow.com/questions/37265070/tensorflow-gradient-is-always-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!