首页 > 解决方案 > 如何修复错误“tensorflow.python.framework.errors_impl.InvalidArgumentError:分配需要两个张量的形状匹配。”

问题描述

我已经训练了两个简单的 CNN 模型来识别许可证号并将它们转换为两个函数:predict_provinces.py 和 predict_digits.py。它们可以单独运行并返回真实数字。但是,当它们一起运行时,错误显示为“tensorflow.python.framework.errors_impl.InvalidArgumentError:分配需要两个张量的形状匹配。”

我试图使用这个论点

saver = tf.train.import_meta_graph(os.path.join(SAVER_DIR, 'model.ckpt.meta'),clear_devices=True), but it doesn't help.

predict_provinces.py

import tensorflow as tf
import os
import PlateNumberRecognition.config as config
import cv2
import numpy as np

NUM_CLASSES = config.DIGITS_NUM_CLASSES
SAVER_DIR = config.DIGITS_SAVER_DIR
HEIGHT = config.HEIGHT
WIDTH = config.WIDTH
CHANNEL_NUM = config.CHANNEL_NUM
LETTERS_DIGITS=config.LETTERS_DIGITS
def digit_predict(digit_arr):
    saver = tf.train.import_meta_graph(os.path.join(SAVER_DIR, 'model.ckpt.meta'))
    x = tf.placeholder(tf.float32, shape=[None, HEIGHT, WIDTH, CHANNEL_NUM])
    with tf.Session() as sess:
        model_file = tf.train.latest_checkpoint(SAVER_DIR)
        saver.restore(sess, model_file)
        conv1_w = sess.graph.get_tensor_by_name('layer1-conv1/weight:0')
        conv1_b = sess.graph.get_tensor_by_name('layer1-conv1/bias:0')
        conv1 = tf.nn.conv2d(x, conv1_w, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_b))
        pool1 = tf.nn.max_pool(relu1, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')


        conv2_w = sess.graph.get_tensor_by_name('layer3-conv2/weight:0')
        conv2_b = sess.graph.get_tensor_by_name('layer3-conv2/bias:0')
        conv2 = tf.nn.conv2d(pool1, conv2_w, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_b))
        pool2 = tf.nn.max_pool(relu2, [1, 1, 1, 1], [1, 1, 1, 1], padding='SAME')


        fc1_w = sess.graph.get_tensor_by_name('layer5-fc1/weight:0')
        fc1_b = sess.graph.get_tensor_by_name('layer5-fc1/bias:0')
        pool_shape = pool2.get_shape().as_list()
        nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]

        reshaped = tf.reshape(pool2, [-1, nodes])
        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_w) + fc1_b)

        fc2_w = sess.graph.get_tensor_by_name('layer6-fc2/weight:0')
        fc2_b = sess.graph.get_tensor_by_name('layer6-fc2/bias:0')

        result = tf.nn.softmax(tf.matmul(fc1, fc2_w) + fc2_b)

        _, binary = cv2.threshold(digit_arr, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        # print(binary.shape)
        # cv2.imshow('window1', binary)
        # cv2.waitKey(0)
        for i in range(binary.shape[0]):
            for j in range(binary.shape[1]):
                if binary[i][j]==0:
                    binary[i][j]=1
                else:
                    binary[i][j]=0
        img_data = np.reshape(binary,[1, HEIGHT, WIDTH, CHANNEL_NUM])
        result = sess.run(result, feed_dict={x: np.array(img_data)})

        max = 0
        max_index = 0

        for j in range(NUM_CLASSES):
            if result[0][j] > max:
                max = result[0][j]
                max_index = j
                continue
    return config.LETTERS_DIGITS[max_index]

predict_digits.py

predict_provinces.py
import tensorflow as tf
import os
import PlateNumberRecognition.config as config
import numpy as np
import PlateNumberRecognition
NUM_CLASSES = config.PROVINCE_NUM_CLASSES
SAVER_DIR = config.PROVINCE_SAVER_DIR
HEIGHT = config.HEIGHT
WIDTH = config.WIDTH
CHANNEL_NUM = config.CHANNEL_NUM

SIZE = config.SIZE
PROVINCES = config.PROVINCES

def predict_provinces(pro_arr):
    x = tf.placeholder(tf.float32, shape=[None, HEIGHT, WIDTH, CHANNEL_NUM])
    saver = tf.train.import_meta_graph(os.path.join(SAVER_DIR, 'model.ckpt.meta'),clear_devices=True)
    with tf.Session() as sess:
        model_file = tf.train.latest_checkpoint(SAVER_DIR)
        saver.restore(sess, model_file)
        conv1_w = sess.graph.get_tensor_by_name('layer1-conv1/weight:0')
        conv1_b = sess.graph.get_tensor_by_name('layer1-conv1/bias:0')

        conv1 = tf.nn.conv2d(x, conv1_w, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_b))
        pool1 = tf.nn.max_pool(relu1, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')


        conv2_w = sess.graph.get_tensor_by_name('layer3-conv2/weight:0')
        conv2_b = sess.graph.get_tensor_by_name('layer3-conv2/bias:0')
        conv2 = tf.nn.conv2d(pool1, conv2_w, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_b))
        pool2 = tf.nn.max_pool(relu2, [1, 1, 1, 1], [1, 1, 1, 1], padding='SAME')


        fc1_w = sess.graph.get_tensor_by_name('layer5-fc1/weight:0')
        fc1_b = sess.graph.get_tensor_by_name('layer5-fc1/bias:0')
        pool_shape = pool2.get_shape().as_list()
        nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]

        reshaped = tf.reshape(pool2, [-1, nodes])
        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_w) + fc1_b)

        fc2_w = sess.graph.get_tensor_by_name('layer6-fc2/weight:0')
        fc2_b = sess.graph.get_tensor_by_name('layer6-fc2/bias:0')

        result = tf.nn.softmax(tf.matmul(fc1, fc2_w) + fc2_b)

        img_data = np.reshape(pro_arr, [1, HEIGHT, WIDTH, CHANNEL_NUM])
        result = sess.run(result, feed_dict={x: np.array(img_data)})

        max = 0
        max_index = 0

        for j in range(NUM_CLASSES):
            if result[0][j] > max:
                max = result[0][j]
                max_index = j
                continue
        license_number = PROVINCES[max_index]
    return license_number

测试.py

import PlateNumberRecognition.predict_digits as pd
import PlateNumberRecognition.predict_provinces as pp
import cv2
import tensorflow as tf
pic_1=cv2.imread('6.bmp',0)
pic_2=cv2.imread('1.bmp',0)
pp.predict_provinces(pic_2)
pd.digit_predict(pic_1)

错误

G:\Pycharm\test\venv\Scripts\python.exe C:/Users/asus/Desktop/Intelligent-Transportation/PlateNumberRecognition/test.py
2019-03-19 17:21:24.765040: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
Traceback (most recent call last):
  File "G:\Pycharm\test\venv\lib\site-packages\tensorflow\python\client\session.py", line 1334, in _do_call
    return fn(*args)
  File "G:\Pycharm\test\venv\lib\site-packages\tensorflow\python\client\session.py", line 1319, in _run_fn
    options, feed_dict, fetch_list, target_list, run_metadata)
  File "G:\Pycharm\test\venv\lib\site-packages\tensorflow\python\client\session.py", line 1407, in _call_tf_sessionrun
    run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Assign requires shapes of both tensors to match. lhs shape= [512,6] rhs shape= [512,34]

我希望将这两个功能一起使用

标签: tensorflowconv-neural-network

解决方案


我已经通过使用两个图形分别运行这两个函数来解决这个问题。修改后的 test.py 如下:

import PlateNumberRecognition.predict_digits as pd
import PlateNumberRecognition.predict_provinces as pp
import cv2
import tensorflow as tf
pic_1=cv2.imread('6.bmp',0)
pic_2=cv2.imread('1.bmp',0)
g1=tf.Graph()
with g1.as_default():
    pp.predict_provinces(pic_2)
g2=tf.Graph()
with g2.as_default():
    pd.digit_predict(pic_1)

但是,我不知道为什么它可以解决这个问题......


推荐阅读