ValueError: ввод 0 слоя «edsr_model» несовместим с
слоем: ожидаемая форма = (Нет, Нет, Нет, 3), найдено shape=(1, 16, 24,
24, 3)" в этой строке "preds = model.predict_step(lowres)

Мой код
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import os
from tensorflow.keras import layers
AUTOTUNE = tf.data.AUTOTUNE
Определите пути к вашим наборам данных
HR_DIR = 'D:\\upscalingProject\\Flickr2K\\Flickr2K_HR\\'
LR_DIR = 'D:\\upscalingProject\\Flickr2K\\Flickr2K_LR_bicubic\X4\\'
Загрузить имена файлов
hr_images = sorted([os.path.join(HR_DIR, img) for img in os.listdir(HR_DIR)])
lr_images = sorted([os.path.join(LR_DIR, img) for img in os.listdir(LR_DIR)])
Переворачивайте, обрезайте и изменяйте размер изображений
def flip_left_right(lowres_img, highres_img):
return tf.cond(
tf.random.uniform([], 0, 1) < 0.5,
lambda: (lowres_img, highres_img),
lambda: (tf.image.flip_left_right(lowres_img), tf.image.flip_left_right(highres_img))
)
def random_rotate(lowres_img, highres_img):
rn = tf.random.uniform([], 0, 4, dtype=tf.int32)
return tf.image.rot90(lowres_img, rn), tf.image.rot90(highres_img, rn)
def random_crop(lowres_img, highres_img, hr_crop_size=96, scale=4):
lr_crop_size = hr_crop_size // scale
lr_img_shape = tf.shape(lowres_img)[:2]
lr_height, lr_width = lr_img_shape[0], lr_img_shape[1]
lr_x = tf.random.uniform([], 0, lr_width - lr_crop_size, dtype=tf.int32)
lr_y = tf.random.uniform([], 0, lr_height - lr_crop_size, dtype=tf.int32)
hr_x = lr_x * scale
hr_y = lr_y * scale
lowres_cropped = lowres_img[lr_y:lr_y+lr_crop_size, lr_x:lr_x+lr_crop_size]
highres_cropped = highres_img[hr_y:hr_y+hr_crop_size, hr_x:hr_x+hr_crop_size]
return lowres_cropped, highres_cropped
# Function to apply all augmentations sequentially
def augment_images(lowres_img, highres_img):
lowres_img, highres_img = flip_left_right(lowres_img, highres_img)
lowres_img, highres_img = random_rotate(lowres_img, highres_img)
lowres_img, highres_img = random_crop(lowres_img, highres_img)
return lowres_img, highres_img
Загрузка и предварительная обработка изображений
def load_image(lr_path, hr_path):
lr_img = tf.io.read_file(lr_path)
hr_img = tf.io.read_file(hr_path)
lr_img = tf.image.decode_png(lr_img, channels=3)
hr_img = tf.image.decode_png(hr_img, channels=3)
lr_img = tf.cast(lr_img, tf.float32) / 255.0
hr_img = tf.cast(hr_img, tf.float32) / 255.0
return lr_img, hr_img
# Dataset function that ensures random cropping and other augmentations
def dataset_object(lr_images, hr_images, training=True):
dataset = tf.data.Dataset.from_tensor_slices((lr_images, hr_images))
dataset = dataset.map(load_image, num_parallel_calls=AUTOTUNE)
# Apply random cropping first
dataset = dataset.map(lambda lr, hr: random_crop(lr, hr, scale=4), num_parallel_calls=AUTOTUNE)
if training:
# Apply augmentations if training
dataset = dataset.map(lambda lr, hr: random_rotate(lr, hr), num_parallel_calls=AUTOTUNE)
dataset = dataset.map(lambda lr, hr: flip_left_right(lr, hr), num_parallel_calls=AUTOTUNE)
# Batching the dataset
dataset = dataset.batch(16)
if training:
# Repeat the dataset and prefetch for efficiency
dataset = dataset.repeat()
dataset = dataset.prefetch(buffer_size=AUTOTUNE)
return dataset
# Define the training and validation datasets
train_ds = dataset_object(lr_images, hr_images, training=True)
val_ds = dataset_object(lr_images, hr_images, training=False)
Визуализация данных
def visualize_data(dataset):
lowres, highres = next(iter(dataset))
plt.figure(figsize=(10, 10))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(tf.image.convert_image_dtype(highres, tf.uint8))
plt.title(f"HR Image {i+1}")
plt.axis("off")
plt.figure(figsize=(10, 10))
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(tf.image.convert_image_dtype(lowres, tf.uint8))
plt.title(f"LR Image {i+1}")
plt.axis("off")
visualize_data(train_ds)
Построение модели
from tensorflow.keras import layers
class EDSRModel(tf.keras.Model):
def train_step(self, data):
x, y = data
with tf.GradientTape() as tape:
y_pred = self(x, training=True)
loss = self.compiled_loss(y, y_pred, regularization_losses=self.losses)
gradients = tape.gradient(loss, self.trainable_variables)
self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))
self.compiled_metrics.update_state(y, y_pred)
return {m.name: m.result() for m in self.metrics}
def predict_step(self, x):
x = tf.cast(tf.expand_dims(x, axis=0), tf.float32)
super_resolution_img = self(x, training=False)
super_resolution_img = tf.clip_by_value(super_resolution_img, 0, 255)
super_resolution_img = tf.round(super_resolution_img)
super_resolution_img = tf.squeeze(
tf.cast(super_resolution_img, tf.uint8), axis=0
)
return super_resolution_img
# Define a custom layer for the Depth-to-Space operation
class DepthToSpace(layers.Layer):
def __init__(self, scale, **kwargs):
super(DepthToSpace, self).__init__(**kwargs)
self.scale = scale
def call(self, inputs):
return tf.nn.depth_to_space(inputs, self.scale)
# Residual block
def residual_block(x, filters=64, kernel_size=3, scaling=0.1):
skip = x
x = layers.Conv2D(filters, kernel_size, padding="same")(x)
x = layers.ReLU()(x)
x = layers.Conv2D(filters, kernel_size, padding="same")(x)
x = layers.Add()([x, skip])
return x
# Upsample block using custom DepthToSpace layer
def upsample_block(x, scale):
x = layers.Conv2D(256, 3, padding="same")(x)
x = DepthToSpace(scale)(x) # Use the custom DepthToSpace layer here
return x
# EDSR model definition
def build_edsr(scale, num_res_blocks=10, filters=64):
inputs = layers.Input(shape=(None, None, 3))
x = layers.Conv2D(filters, 3, padding="same")(inputs)
for _ in range(num_res_blocks):
x = residual_block(x)
x = upsample_block(x, scale)
outputs = layers.Conv2D(3, 3, padding="same")(x)
return inputs, outputs
# Build the EDSR model
inputs, outputs = build_edsr(scale=4)
model = EDSRModel(inputs, outputs)
Определение метрики и проверка формы
for lr, hr in train_ds.take(1):
print("Low-res shape:", lr.shape)
print("High-res shape:", hr.shape)
import tensorflow as tf
# Define the PSNR metric
def psnr(y_true, y_pred):
# Clip values to avoid out of range errors
y_pred = tf.clip_by_value(y_pred, 0.0, 1.0)
return tf.image.psnr(y_true, y_pred, max_val=1.0)
Обучение модели
Оптимизатор Адама с планированием скорости обучения
optim_edsr = tf.keras.optimizers.Adam(
learning_rate=tf.keras.optimizers.schedules.PiecewiseConstantDecay(
boundaries=[5000], values=[1e-4, 5e-5]
)
)
# Compile the model with PSNR as a metric
model.compile(optimizer=optim_edsr, loss="mse", metrics=[psnr])
# Fit the model with validation data and training
model.fit(train_ds, epochs=100, steps_per_epoch=200, validation_data=val_ds)
визуализация результатов
def plot_results(lowres, preds):
"""
Displays low resolution image and super resolution image
"""
plt.figure(figsize=(24, 14))
plt.subplot(132), plt.imshow(lowres), plt.title("Low resolution")
plt.subplot(133), plt.imshow(preds), plt.title("Prediction")
plt.show()
for lowres, highres in val_ds.take(10):
lowres = tf.image.random_crop(lowres, (16,24, 24, 3))
preds = model.predict_step(lowres)
plot_results(lowres, press)
Подробнее здесь: https://stackoverflow.com/questions/790 ... d-shape-no