[英]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
I get an error when trying to create a model with Tensorflow.尝试使用 Tensorflow 创建 model 时出现错误。 The error is:错误是:
Traceback (most recent call last): at block 5, line 154 at block 5, line 61, in init (self) at block 5, line 41, in conv(self, input, num_outputs, name) ValueError: Input 0 of layer conv2d_1 is incompatible with the layer: : expected min_ndim=4, found ndim=3. 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。 Full shape received: (Dimension(None), Dimension(32), Dimension(32))收到的完整形状:(维度(无),维度(32),维度(32))
I have Tensorflow version 2.5.0我有 Tensorflow 版本 2.5.0
Here is my code:这是我的代码:
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)
I assume that you are inputting a grayscale image, I see that我假设您正在输入灰度图像,我看到了
self.images = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT, IMAGE_WIDTH] self.images = tf.placeholder(tf.float32, [无, IMAGE_HEIGHT, IMAGE_WIDTH]
In tensorflow2.x the Conv2D layer expects four dimensions: batch size, height, width, channel.在 tensorflow2.x 中,Conv2D 层需要四个维度:批量大小、高度、宽度、通道。 So even if it is a grayscale image, you should add a dimension of 1 at the end of the image.所以即使是灰度图,也应该在图的最后加上1的维度。
I suggest trying to add np.expand_dims(images, axis=-1) to your load() function我建议尝试将 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
This should give you an input shape of [None, IMAGE_HEIGHT, IMAGE_WIDTH, 1]这应该为您提供 [None, IMAGE_HEIGHT, IMAGE_WIDTH, 1] 的输入形状
Then you should also adjust any placeholder that declares the shape of the images so it matches with the input image dimension然后,您还应该调整任何声明图像形状的占位符,使其与输入图像尺寸匹配
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.