I get an error when trying to create a model with Tensorflow. 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. Full shape received: (Dimension(None), Dimension(32), Dimension(32))
I have Tensorflow version 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]
In tensorflow2.x the Conv2D layer expects four dimensions: batch size, height, width, channel. So even if it is a grayscale image, you should add a dimension of 1 at the end of the image.
I suggest trying to add np.expand_dims(images, axis=-1) to your 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]
Then you should also adjust any placeholder that declares the shape of the images so it matches with the input image dimension
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.