ValueError: для любой переменной между переменными не предусмотрено градиентов ... и tf.stop_gradient () - PullRequest
0 голосов
/ 05 февраля 2020

Я новичок в Tensorflow с Python, и я пытаюсь построить свой собственный Con vNet с нуля:

net берет 2 изображения, выводит матрицу, которая затем обрабатывается с недифференцируемыми функциями для выходного изображения

В конце концов, вычисляется сходство выходного изображения с изображением моей метки, и это сходство должно быть моей потерей.

Я знаю, что ошибка из-за моей недифференцированной обработки, но я попытался остановить градиент от вычисления этой части кода с помощью tf.stop_gradient (). Насколько я понял, tf.stop_gradient () не позволяет учитывать его входные данные при расчете градиента при обратном распространении.

Но я полагаю, что с моей стороны есть некоторое недопонимание, иначе это не дало бы мне ошибка:

ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables ["<tf.Variable 'W1:0' shape=(5, 5, 3, 600) dtype=float32_ref>", "<tf.Variable 'W2:0' shape=(5, 5, 600, 1200) dtype=float32_ref>", "<tf.Variable 'W3:0' shape=(5, 5, 1200, 1) dtype=float32_ref>", "<tf.Variable 'B1:0' shape=(600,) dtype=float32_ref>", "<tf.Variable 'B2:0' shape=(1200,) dtype=float32_ref>", "<tf.Variable 'B3:0' shape=(1,) dtype=float32_ref>"] and loss Tensor("Const_6:0", shape=(), dtype=float32).

Вот мой код:


img_width = 320
img_height = 240
# 320 x 240 = 76'800

# W = input height
# K = filter size
# P = padding
# S = stride
# output height = ((W - K + 2 * P) / S) + 1
# same applies for width but W must be = input width

weights = {
    'w_1': tf.compat.v1.get_variable('W1', shape=(5, 5, 3, 600), initializer=tf.contrib.layers.xavier_initializer()),
    'w_2': tf.compat.v1.get_variable('W2', shape=(5, 5, 600, 1200), initializer=tf.contrib.layers.xavier_initializer()),
    'w_3': tf.compat.v1.get_variable('W3', shape=(5, 5, 1200, 1), initializer=tf.contrib.layers.xavier_initializer()),
}

biases = {
    'b_1': tf.compat.v1.get_variable('B1', shape=(600), initializer=tf.contrib.layers.xavier_initializer()),
    'b_2': tf.compat.v1.get_variable('B2', shape=(1200), initializer=tf.contrib.layers.xavier_initializer()),
    'b_3': tf.compat.v1.get_variable('B3', shape=(1), initializer=tf.contrib.layers.xavier_initializer()),
}


# input: input_nodes, weights, biases, strides
def conv2d(x_arg, W, b, strides=1):
    x_temp = tf.nn.conv2d(x_arg, W, strides=[1, strides, strides, 1], padding='SAME')
    x_temp = tf.nn.bias_add(x_temp, b)
    return tf.nn.relu(x_temp)


# input: input_nodes, kernel_size
def maxpool2d(x_arg, k=2, s1=1, s2=1):
    return tf.nn.max_pool2d(x_arg, ksize=[1, k, k, 1], strides=[1, s1, s2, 1], padding='SAME')


def conv_net(x_arg):

    ws = weights
    bs = biases

    conv1 = conv2d(x_arg, ws['w_1'], bs['b_1'])
    conv1 = maxpool2d(conv1, k=2)

    conv2 = conv2d(conv1, ws['w_2'], bs['b_2'])
    conv2 = maxpool2d(conv2, k=2)

    conv3 = conv2d(conv2, ws['w_3'], bs['b_3'])
    conv3 = maxpool2d(conv3, k=2, s2=2)

    fc1 = tf.reshape(conv3, [-1, img_height, img_width])
    return fc1


def convert_to_int_value(value):
    int_value = tf.floor(value * (img_width-1))
    return int_value


def move_pixels(matrix, original_img):
    # matrix is looped over and blank img gets filled
    return blank_img


# wrapper that wraps move_pixels() for tensorflow
def wrapper(matrix, original_img):
    return tf.py_function(move_pixels, [matrix, original_img], tf.float32)


def process(matrix_plcehldr, y):
    input = tf.map_fn(convert_to_int_value, matrix_plcehldr)
    dims = tf.shape(input)
    input_reshaped = tf.reshape(input, shape=(dims[0], img_height, img_width))
    image_generated = wrapper(input_reshaped, x_left)
    image_generated = tf.convert_to_tensor(image_generated)
    img_y = tf.convert_to_tensor(y)
    ssim = tf.image.ssim(image_generated, img_y, max_val=1.0)
    dssim = tf.divide(tf.subtract(1.0, tf.reduce_mean(ssim)), 2.0)
    return dssim


# loading images

x = tf.compat.v1.placeholder(tf.float32, [None, img_height, 2 * img_width, 3])      # input img
x_left = tf.compat.v1.placeholder(tf.float64, [img_height, img_width, 3])
x_gen = tf.compat.v1.placeholder(tf.float64, [img_height, img_width, 3])
y = tf.compat.v1.placeholder(tf.float32, [img_height, img_width, 3])

matrix_plcehldr = tf.compat.v1.placeholder(tf.float64, [None, img_height, img_width])

matrix_pred = conv_net(x)
loss_calc = tf.stop_gradient(process(matrix_plcehldr, y))

optimizer = tf.train.AdamOptimizer(0.01)


init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
    res = sess.run(init)

    image_x = sess.run(image_x)
    image_y = sess.run(image_y)
    image_x_left = sess.run(image_x_left)
    disparities_pred = sess.run(disparities_pred, feed_dict={x: [image_x]})

    # I'm working with a single image at the moment
    loss = sess.run(loss_calc, feed_dict={matrix_plcehldr: matrix_pred, x_left: image_x_left, y: image_y})
    print(loss)
    train = optimizer.minimize(tf.convert_to_tensor(loss))

    sess.close()

Любая помощь / совет будет высоко ценится!

...