.pb模型中的Tensorflow Adam优化器

时间:2018-07-24 12:05:19

标签: python tensorflow

我已经开发了一个使用Adam优化器的TensorFlow代码,然后保存了图形并导出了.pb模型并正确加载了它,我的问题是,当我用新的输入图像输入它时,与此代码给出的结果:

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img, array_to_img 

import cv2
import tensorflow as tf
import numpy
import numpy as np




def get_image2(imgSrc):
    img = load_img(imgSrc, True)  # this is a PIL image
    x = img_to_array(img)  # this is a Numpy array with shape (3, 150, 150
    #x = x.reshape((1,) + x.shape)
    x = x.astype(float)
    x *= 1./255.
    #x = cv2.resize(x,(512,512))
    return x


def sobel2(image):


    # Shape = height x width.
    #image = tf.placeholder(tf.float32, shape=[None, None])

    # Shape = 1 x height x width x 1.
    image_resized = image#tf.expand_dims(image, 0)

    Gx = tf.nn.conv2d(image_resized, sobel_x_filter, strides=[1, 1, 1, 1], padding='SAME')
    Gy = tf.nn.conv2d(image_resized, sobel_y_filter,strides=[1, 1, 1, 1], padding='SAME')

    #grad = tf.sqrt(tf.add(tf.pow(Gx,2),tf.pow(Gy,2)))
    #grad = tf.pow(Gx,2) + tf.pow(Gy,2)
    #grad = tf.truediv(grad,3.)

    #grad = tf.reshape(grad, img_shape)

    return Gx, Gy

image = get_image2('1.jpg')

img_shape = image.shape
print img_shape
img_h, img_w,_= img_shape

sobel_x = tf.constant([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], tf.float32)
sobel_x_filter = tf.reshape(sobel_x, [3, 3, 1, 1])
sobel_y_filter = tf.transpose(sobel_x_filter, [1, 0, 2, 3])

input_img  = tf.placeholder(tf.float32, shape=[1,img_shape[0],img_shape[1],img_shape[2]], name="input_img") 
#input_img  = tf.placeholder(tf.float32, [1, 512, 512, 1], name="input_img")


gain   = tf.Variable(tf.constant(1, dtype=tf.float32, shape=[1,img_shape[0],img_shape[1],img_shape[2]]), name="gain")
offset = tf.Variable(tf.constant(0, dtype=tf.float32, shape=[1,img_shape[0],img_shape[1],img_shape[2]]), name="offset")

enhanced_img = tf.add(tf.multiply(input_img, gain), offset, name = "enahnced")


#----------------------------------------------------------
# COST
#----------------------------------------------------------

input_img_deriv_x, input_img_deriv_y    = sobel2(input_img)

enhanced_img_deriv_x, enhanced_img_deriv_y = sobel2(enhanced_img)

white_img = tf.constant(1, dtype=tf.float32, shape=[1,img_shape[0],img_shape[1],img_shape[2]])

image_pixels_count = img_h * img_w

white_cost = tf.reduce_sum(tf.pow(enhanced_img - white_img, 2))
sobel_cost = tf.reduce_sum(tf.pow(enhanced_img_deriv_x - input_img_deriv_x, 2) + 
                            tf.pow(enhanced_img_deriv_y - input_img_deriv_y,2))
cost = tf.add(white_cost, tf.multiply(0.2, sobel_cost), name = "cost") # + tf.reduce_sum(gain - 1) + tf.reduce_sum(offset)


#----------------------------------------------------------
# TRAIN
#----------------------------------------------------------

# Parameters
learning_rate = 0.0001
training_epochs = 100
display_step = 5

optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

# Initialize the variables (i.e. assign their default value)
init = tf.global_variables_initializer()

saver = tf.train.Saver()
image  = image.reshape([-1,img_shape[0],img_shape[1],img_shape[2]])
#print image.shape

#print image.shape
feed = {input_img: image }



# Start training
with tf.Session() as sess:
    #Run the initializer
    print(sess.run(init))

    # Fit all training data
    for epoch in range(training_epochs):
        sess.run([optimizer, cost], feed_dict = feed)
        print(tf.reduce_sum(offset.eval()).eval())


        if (epoch+1) % display_step == 0:
            gen_img = sess.run(enhanced_img, feed_dict = feed)
        gen_img  = np.squeeze(gen_img, axis=0)
            print(gen_img.shape)
            gen_img *= 255
            cv2.imwrite("result/output_2_{0}.png".format(epoch), gen_img)

我注意到,当我保存图形时,还保存了优化器状态,​​因此当我加载模型并向其提供新图像时,他将产生错误的结果,因为他将使用与我所使用的图像有关的保存值当我保存它时。

我如何使模型针对新图像运行优化器,而无需使用先前输入中保存的参数。

1 个答案:

答案 0 :(得分:1)

您了解优化器的实际工作原理吗?

优化器的目标是相对于梯度更新模型权重。关于 Adam ,它具有两个内部变量,它们在训练期间进行了更新,这是adam算法的一部分。因此,此行为完全正常。如果您想“重置”亚当变量,那是完全可行的,但是我非常怀疑这是您想要做的……非常罕见的情况要求您这样做。顺便说一句。如果重置亚当状态,则会破坏优化器的整个逻辑。

如果尝试在推断时评估新图像,则不应运行优化器,因此模型输出不应受到Adam或任何其他优化器的影响。

如果您尝试从以前保存的检查点继续进行训练,我建议您在数据集相同的情况下保持Adam状态(不是转移学习方法),因此不应重置adam的变量。

顺便说一句。如果您真的要重设亚当,您将按照以下方式进行操作:

optimizer_reset_op = tf.variables_initializer(optimizer.variables())
sess.run(optimizer_reset_op)