Python 根据现有检查点定义TensorFlow网络密钥名称

Python 根据现有检查点定义TensorFlow网络密钥名称,python,tensorflow,nvidia-digits,Python,Tensorflow,Nvidia Digits,我使用Nvidia数字训练了一个LeNet-gray-28x28图像检测Tensorflow模型,给出了我期望的结果。 现在,我必须对一些数字以外的图像进行分类,我想使用我训练过的模型 所以我得到了DIGITS使用的LeNet模型,并创建了一个类来使用它: import tensorflow as tf import tensorflow.contrib.slim as slim import tflearn from tflearn.layers.core import input_data

我使用Nvidia数字训练了一个LeNet-gray-28x28图像检测Tensorflow模型,给出了我期望的结果。 现在,我必须对一些数字以外的图像进行分类,我想使用我训练过的模型

所以我得到了DIGITS使用的LeNet模型,并创建了一个类来使用它:

import tensorflow as tf
import tensorflow.contrib.slim as slim
import tflearn
from tflearn.layers.core import input_data


class LeNetModel():

    def gray28(self, nclasses):
        x = input_data(shape=[None, 28, 28, 1])
        # scale (divide by MNIST std)
        # x = x * 0.0125
        with slim.arg_scope([slim.conv2d, slim.fully_connected],
                            weights_initializer=tf.contrib.layers.xavier_initializer(),
                            weights_regularizer=slim.l2_regularizer(0.0005)):
            model = slim.conv2d(x, 20, [5, 5], padding='VALID', scope='conv1')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool1')
            model = slim.conv2d(model, 50, [5, 5], padding='VALID', scope='conv2')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool2')
            model = slim.flatten(model)
            model = slim.fully_connected(model, 500, scope='fc1')
            model = slim.dropout(model, 0.5, is_training=False, scope='do1')
            model = slim.fully_connected(model, nclasses, activation_fn=None, scope='fc2')

            return tflearn.DNN(model)
我从DIGITS下载了我的模型,并使用(在另一个文件中)实例化它:

但是,当我启动脚本时,会出现以下异常:

2017-11-26 14:55:50.330524: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key conv1/biases not found in checkpoint
2017-11-26 14:55:50.330948: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key Global_Step not found in checkpoint
2017-11-26 14:55:50.331270: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key is_training not found in checkpoint
2017-11-26 14:55:50.331564: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key conv2/weights not found in checkpoint
2017-11-26 14:55:50.332823: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key conv1/weights not found in checkpoint
2017-11-26 14:55:50.332891: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key conv2/biases not found in checkpoint
2017-11-26 14:55:50.333620: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key fc2/weights not found in checkpoint
2017-11-26 14:55:50.334021: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key fc1/weights not found in checkpoint
2017-11-26 14:55:50.334173: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key fc1/biases not found in checkpoint
2017-11-26 14:55:50.334431: W tensorflow/core/framework/op_kernel.cc:1192] Not found: Key fc2/biases not found in checkpoint
...
raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.NotFoundError: Key conv1/biases not found in checkpoint
         [[Node: save_1/RestoreV2_1 = RestoreV2[dtypes=[DT_FLOAT], _device="/job:localhost/replica:0/task:0/cpu:0"](_arg_save_1/Const_0_0, save_1/RestoreV2_1/tensor_names, save_1/RestoreV2_1/shape_and_slices)]]
         [[Node: save_1/RestoreV2_1/_19 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/gpu:0", send_device="/job:localhost/replica:0/task:0/cpu:0", send_device_incarnation=1, tensor_name="edge_38_save_1/RestoreV2_1", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
因此,我使用脚本检查检查点包含的密钥名称,得到如下结果:

model/conv1/biases
model/conv2/weights
...
因此,我重写了我的网络,手动添加模型/前缀:

                model = slim.conv2d(x, 20, [5, 5], padding='VALID', scope='model/conv1')
                model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='model/pool1')
                model = slim.conv2d(model, 50, [5, 5], padding='VALID', scope='model/conv2')
                model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='model/pool2')
                model = slim.flatten(model)
                model = slim.fully_connected(model, 500, scope='model/fc1')
                model = slim.dropout(model, 0.5, is_training=False, scope='model/do1')
                model = slim.fully_connected(model, nclasses, 
它修复了一些丢失的按键警告,但:

  • 我觉得这不是解决问题的正确方法
  • 我修不好两把钥匙:
  • 全局步骤(我的检查点中有全局步骤键)
  • 正在接受培训(我不知道是什么)

因此,我的问题是:如何在我的网络中重新定义这些关键名称,以匹配我在检查点中找到的名称?

因为我的问题主要是因为我对TensorFlow的理解不好,所以我在官方文档中进行了一次访问,并找到了一些答案

首先,我将contrib/slim和contrib/tflearn的使用结合起来,即使有可能,也没有实际意义。因此,我仅使用slim重写网络:

import tensorflow as tf
import tensorflow.contrib.slim as slim


class LeNetModel():

    def gray28(self, nclasses):
        # x = input_data(shape=[None, 28, 28, 1])
        x = tf.placeholder(tf.float32, shape=[1, 28, 28], name="x")
        rs = tf.reshape(x, shape=[-1, 28, 28, 1])
        # scale (divide by MNIST std)
        # x = x * 0.0125
        with slim.arg_scope([slim.conv2d, slim.fully_connected],
                            weights_initializer=tf.contrib.layers.xavier_initializer(),
                            weights_regularizer=slim.l2_regularizer(0.0005)):
            model = slim.conv2d(rs, 20, [5, 5], padding='VALID', scope='conv1')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool1')
            model = slim.conv2d(model, 50, [5, 5], padding='VALID', scope='conv2')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool2')
            model = slim.flatten(model)
            model = slim.fully_connected(model, 500, scope='fc1')
            model = slim.dropout(model, 0.5, is_training=True, scope='do1')
            model = slim.fully_connected(model, nclasses, activation_fn=None, scope='fc2')

            return x, model
我返回x占位符和模型,并使用它加载数字预训练模型(检查点):

而且它有效

import tensorflow as tf
import tensorflow.contrib.slim as slim


class LeNetModel():

    def gray28(self, nclasses):
        # x = input_data(shape=[None, 28, 28, 1])
        x = tf.placeholder(tf.float32, shape=[1, 28, 28], name="x")
        rs = tf.reshape(x, shape=[-1, 28, 28, 1])
        # scale (divide by MNIST std)
        # x = x * 0.0125
        with slim.arg_scope([slim.conv2d, slim.fully_connected],
                            weights_initializer=tf.contrib.layers.xavier_initializer(),
                            weights_regularizer=slim.l2_regularizer(0.0005)):
            model = slim.conv2d(rs, 20, [5, 5], padding='VALID', scope='conv1')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool1')
            model = slim.conv2d(model, 50, [5, 5], padding='VALID', scope='conv2')
            model = slim.max_pool2d(model, [2, 2], padding='VALID', scope='pool2')
            model = slim.flatten(model)
            model = slim.fully_connected(model, 500, scope='fc1')
            model = slim.dropout(model, 0.5, is_training=True, scope='do1')
            model = slim.fully_connected(model, nclasses, activation_fn=None, scope='fc2')

            return x, model
import tensorflow as tf
import tensorflow.contrib.slim as slim
import cv2
from models.lenet import LeNetModel

# Helper function to load/resize images
def image(path):
    img = cv2.imread(path, 0)
    return cv2.resize(img, dsize=(28,28))

# Define a function that adds the model/ prefix to all variables :
def name_in_checkpoint(var):
  return 'model/' + var.op.name

#Instantiate the model
x, model = LeNetModel().gray28(2)

# Define the variables to restore :
# Exclude the "is_training" that I don't care about
variables_to_restore = slim.get_variables_to_restore(exclude=["is_training"])
# Rename the other variables with the function name_in_checkpoint
variables_to_restore = {name_in_checkpoint(var):var for var in variables_to_restore}

# Create a Saver to restore the checkpoint, given the variables
restorer = tf.train.Saver(variables_to_restore)

#Launch a session to restore the checkpoint and try to infer some images :
with tf.Session() as sess:
    # Restore variables from disk.
    restorer.restore(sess, "src/prototype/models/snapshot_5.ckpt")
    print("Model restored.")
    print(sess.run(model, feed_dict={x:[image("/home/damien/Vidéos/1/positives/img/1-img143.jpg")]}))
    print(sess.run(model, feed_dict={x:[image("/home/damien/Vidéos/0/positives/img/1-img1.jpg")]}))