繁体   English   中英

在 Tensorflow 中创建 model 时出错。 ValueError: 层 conv2d_1 的输入 0 与层不兼容: : 预期 min_ndim=4, 发现 ndim=3

[英]Error with creating a model in Tensorflow. ValueError: Input 0 of layer conv2d_1 is incompatible with the layer: : expected min_ndim=4, found ndim=3

尝试使用 Tensorflow 创建 model 时出现错误。 错误是:

Traceback(最近一次调用最后一次):在第 5 块,第 154 行,第 5 块,第 61 行,在init (self) 中,在第 5 块,第 41 行,在 conv(self, input, num_outputs, name) ValueError: Input 0 of layer conv2d_1 与层不兼容::预期 min_ndim=4,发现 ndim=3。 收到的完整形状:(维度(无),维度(32),维度(32))

我有 Tensorflow 版本 2.5.0

这是我的代码:

    import numpy
    import os
    import math
    import glob
    import random
    import time
    import skimage.data
    import skimage.transform
    import sklearn.preprocessing
    import numpy as np
    import tensorflow.compat.v1 as tf
    from tf_slim.layers import layers as _layers
    import imageio
    import matplotlib
    import matplotlib.pyplot as plt
    from IPython import display
    
    
    TRAIN_DATA_DIR = "traffic/datasets/BelgiumTS/Training"
    TEST_DATA_DIR = "traffic/datasets/BelgiumTS/Testing"
    IMAGE_WIDTH = IMAGE_HEIGHT = 32
    
    def load(data_dir, width, height):
        labels = []
        images = []
        for f in glob.glob(os.path.join(data_dir, "*/*.ppm")):
            labels.append(int(f.split("/")[-2]))
            images.append(skimage.transform.resize(imageio.imread(f), (width, height), mode='constant'))
        labels = np.array(labels)
        images = np.array(images)
        return images, labels
    
    
    train_images, train_labels = load(TRAIN_DATA_DIR, IMAGE_WIDTH, IMAGE_HEIGHT)
    test_images, test_labels = load(TEST_DATA_DIR, IMAGE_WIDTH, IMAGE_HEIGHT)
    
    
    
    class Model4():
        def conv(self, input, num_outputs, name=None):
            return tf.layers.conv2d(
                                        input, filters=num_outputs, kernel_size=(5, 5), strides=(1, 1),
                                        padding="SAME", activation='relu'
            )
        
        def pool(self, input):
            return layers.max_pool2d(input, kernel_size=(2, 2),
                                     stride=(2, 2), padding="SAME")
        
        def __init__(self):
            self.train_log = []
            self.train_time = ()
    
            self.graph = tf.Graph()
            with self.graph.as_default():
                self.global_step = tf.Variable(0, trainable=False, name='global_step')
    
                self.images = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT, IMAGE_WIDTH], name='images')
                self.labels = tf.placeholder(tf.int32, [None], name='labels')
    
                self.conv1 = self.conv(self.images, 8)
                self.pool1 = self.pool(self.conv1)
    
                self.conv2 = self.conv(self.pool1, 12)
                self.pool2 = self.pool(self.conv2)
    
                self.conv3 = self.conv(self.pool2, 16)
                self.pool3 = self.pool(self.conv3)
    
                self.flat = layers.flatten(self.pool3)
    
                self.logits = layers.fully_conneccted(self.flat, 62, lrelu)
    
                self.predicted_labels = tf.argmax((self.logits, 1))
    
                self.loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
                                                                                          logits=self.logits, labels=self.labels))
                self.train = tf.train.AdamOptimizer(learning_rate=0.001)\
                .minimize(self.loss, global_step=self.global_step)
    
                self.init = tf.global_variables_initializer()
    
                self.session = tf.Session()
    
                self.session.run(self.init)
    
    
    
    def train_graph(model, train_images, train_labels, val_images, val_labels, train_count):
        t_start = time.time()
    
        for i in range(1, train_count+1):
            indexes = np.random.choice(np.arange(train_images.shape[0], 100, replace=False))
            batch_images = train_images[indexes]
            batch_labels = train_labels[indexes]
            _, loss = model.session.run([model.train, model.loss], {
                                                                    model.images: batch_images,
                                                                    model.labels: batch_labels,
            })
            if i % 50 == 0:
                evaluate_graph(model, batch_images, batch_labels, val_images, val_labels, time.time() - t_start)
        evaluate_graph(model, batch_images, batch_labels, val_images, val_labels, time.time() - t_start)
    
    
    def evaluate_graph(model, train_images, train_lables, val_images, val_labels, training_time):
        #Run predictions against of a batch of a training set
        train_predicted, train_loss, step = model.session.run(
                                                              {model.predicted_labels, model.loss, model.global_step},
                                                              {model.images: train_images, model.labels: train_lables})
    
        #Run predictions against the full test set
        val_predicted, val_loss = model.session.run(
                                                    {model.predicted_labels, model.loss},
                                                    {model.images: val_images, model.labels: val_lables})
    
        #Calculate accuracy
        train_accuracy = np.sum(train_labels == train_predicted) / train_labels.shape[0]
        val_accuracy = np.sum(val_labels == val_predicted / val_lables.shape[0])
        #Append to training set
        #Не впевнений
        model.train_log.append((step, train_loss, train_accuracy, val_loss, val_accuracy, training_time))
        #Plot
        draw_graph(model.train_log)
    
    
    def draw_graph(logs):
        #Expand log tuples  to the list
        steps, train_losses, train_accuracies, val_losses, val_accuracies, times = zip(*logs)
        #Clear output
        display.clear_output(wait=True)
        fig, (ax1, ax2) = plt.subplots(2, sharex=True, figsize=(0,6))
        #Graph 1: Accuracies
        ax1.set_title("Step: {}  Training Time {:.0f} seconds\n"\
                      "Training Accuracy: {:.3f}  Validation Accuracy: {:.3f}"\
                      .format(steps[-1], times[-1], train_accuracies[-1], val_accuracies[-1], fonsize=9, color=color))
        ax1.plot(steps, train_accuracies, label="Training Accuracy")
        ax1.plot(steps, val_accuracies, label="Validation Accuracy")
        ax1.set_ylabel("Accuracy")
        ax1.legend(fontsize=8, loc=lower_right)
        #ax1.set_ylim(0, 1.1)
        #Graph 2: losses
        ax2.set_title("Training Loss: {:.f} Validation Loss: {:.f}"\
                      .format(train_losses[-1], val_losses[-1]), fontsize=9)
        ax2.set_yscale('log')
        ax2.plot(steps, train_losses, label="Training Loss")
        ax2.plot(steps, val_losses, label="Validation Loss")
        ax2.set_ylabel('Loss')
        ax2.legend(fontsize=8, loc='lower left')
        ax2.set_xlabel('Steps')
        _ = plt.show()
    
    
    
    m4 = Model4()
    train_graph(m4, train_images, train_labels, test_images, test_labels, 4000)

我假设您正在输入灰度图像,我看到了

self.images = tf.placeholder(tf.float32, [无, IMAGE_HEIGHT, IMAGE_WIDTH]

在 tensorflow2.x 中,Conv2D 层需要四个维度:批量大小、高度、宽度、通道。 所以即使是灰度图,也应该在图的最后加上1的维度。

我建议尝试将 np.expand_dims(images, axis=-1) 添加到您的 load() function

def load(data_dir, width, height):
labels = []
images = []
for f in glob.glob(os.path.join(data_dir, "*/*.ppm")):
    labels.append(int(f.split("/")[-2]))
    images.append(skimage.transform.resize(imageio.imread(f), (width, height), mode='constant'))
labels = np.array(labels)
images = np.array(images)
images = np.expand_dims(images, axis=-1)
return images, labels

这应该为您提供 [None, IMAGE_HEIGHT, IMAGE_WIDTH, 1] 的输入形状

然后,您还应该调整任何声明图像形状的占位符,使其与输入图像尺寸匹配

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM