一括画像検証モデルエラー:OP_REQUIRES failed at save_restore_v2_ops.cc:184 : Not found: Key conv1_1/bias not found

25582 ワード

最近、Alexnetモデルをテストするときに問題が発生しました.トレーニングが完了したら、複数のピクチャを検出したいのですが、モデルが最初のピクチャを計算した後、2番目のピクチャを計算するとエラーが発生します(モデルトレーニングおよびテストコード参照:https://github.com/stephen-v/tensorflow_alexnet_classify):
OP_REQUIRES failed at save_restore_v2_ops.cc:184 : Not found: Key conv1_1/bias not found in checkpoint
ネットで言ったように、tfを増やします.reset_default_graph()(tf.reset_default_graph関数は、デフォルトのグラフィックスタックをクリアするグローバルデフォルトのグラフィックをリセットするために使用されます)しかし、エラーが発生し、Alexnetネットワークのwith tfを定義していることがわかりました.name_scope(‘xxx’)as scopeによるもの.with...as...構造を削除し、tfを加える.reset_default_graph()は、再訓練後に画像を一括テストすれば問題ありません.
元のAlexnetモデルコード部分のサンプルコード:
import tensorflow as tf

def alexnet(x, keep_prob, num_classes):
    # conv1
    with tf.name_scope('conv1') as scope:
        kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 96], dtype=tf.float32,
                                             stddev=1e-1), name='weights')
        conv = tf.nn.conv2d(x, kernel, [1, 4, 4, 1], padding='SAME')
        biases = tf.Variable(tf.constant(0.0, shape=[96], dtype=tf.float32),
                             trainable=True, name='biases')
        bias = tf.nn.bias_add(conv, biases)
        conv1 = tf.nn.relu(bias, name=scope)

    # lrn1
    with tf.name_scope('lrn1') as scope:
        lrn1 = tf.nn.local_response_normalization(conv1,
                                                  alpha=1e-4,
                                                  beta=0.75,
                                                  depth_radius=2,
                                                  bias=2.0)
	# pool1
    with tf.name_scope('pool1') as scope:
    	pool1 = tf.nn.max_pool(lrn1, 
    						 ksize=[1, 3, 3, 1],
                             strides=[1, 2, 2, 1],
                             padding='VALID')
   #  ...

修正後のコードは(with tf.name_scope(‘xxx’)as scopeをすべて削除):
import tensorflow as tf

def alexnet(x, keep_prob, num_classes):
    # conv1
    kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 96], dtype=tf.float32,
                                         stddev=1e-1), name='weights')
    conv = tf.nn.conv2d(x, kernel, [1, 4, 4, 1], padding='SAME')
    biases = tf.Variable(tf.constant(0.0, shape=[96], dtype=tf.float32),
                         trainable=True, name='biases')
    bias = tf.nn.bias_add(conv, biases)
    conv1 = tf.nn.relu(bias, name = 'conv1')

    # lrn1
    # with tf.name_scope('lrn1') as scope:
    lrn1 = tf.nn.local_response_normalization(conv1,
                                                  alpha=1e-4,
                                                  beta=0.75,
                                                  depth_radius=2,
                                                  bias=2.0)

    # pool1
    # with tf.name_scope('pool1') as scope:
    pool1 = tf.nn.max_pool(lrn1, 
    						 ksize=[1, 3, 3, 1],
                             strides=[1, 2, 2, 1],
                             padding='VALID')

    #  ...

バッチ・テスト・コードは次のとおりです.
import tensorflow as tf
from alexnet import alexnet
import matplotlib.pyplot as plt
from os import walk, path
VGG_MEAN = tf.constant([123.68, 116.779, 103.939], dtype=tf.float32)

class_name = ['dog', 'cat']

def test_image(path_image, num_class):
    img_string = tf.read_file(path_image)
    img_decoded = tf.image.decode_png(img_string, channels=3)
    img_resized = tf.image.resize_images(img_decoded, [224, 224])
    # img_centered = tf.subtract(img_resized, VGG_MEAN)
    img_resized = tf.reshape(img_resized, shape=[1, 224, 224, 3])
    # img_bgr = img_centered[:, :, ::-1]
    fc8 = alexnet(img_resized, 1, num_class)
    score = tf.nn.softmax(fc8)
    max = tf.argmax(score, 1)
    saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver.restore(sess, "./checkpoints/model_epoch80.ckpt")
        print(sess.run(fc8))
        prob = sess.run(max)[0]
        output = class_name[prob]
        plt.imshow(img_decoded.eval())
        plt.title("Class:" + class_name[prob])
        plt.show(2)

def get_path_prex(rootdir):
    data_path = []
    prefixs = []
    for root, dirs, files in walk(rootdir, topdown=True):
        for name in files:
            pre, ending = path.splitext(name)
            if ending != ".jpg" and ending != ".png":
                continue
            else:
                data_path.append(path.join(root, name))
                prefixs.append(pre)

    return data_path, prefixs

img_path, prefix = get_path_prex('./Datasets/dog_cat/test/')
cnt_fire = 0
for i in range(len(img_path)):
    tf.reset_default_graph() # , 
    output = test_image(img_path[i], num_class=2)

ここでtf.reset_default_graph()は増やさなければなりません.
まとめ:(1)訓練コードにwith tfが含まれているため.name_scope(‘xxx’)as scopeが除去され、直接tfが増加する.reset_default_graph()も上記のエラーを報告します(参考:https://blog.csdn.net/LeeGe666/article/details/85806790)(2)コードのwith tf.name_scope(‘xxx’)as scopeは除去後モデルを再訓練し、テストコードにtfを追加する.reset_default_graph()エラー解決.
参照リンク:
  • https://blog.csdn.net/bc521bc/article/details/84038471
  • tf.name_scope()は何に使いますか.https://www.jianshu.com/p/635d95b34e14
  • tf.reset_default_graph()関数:https://blog.csdn.net/duanlianvip/article/details/98626111