Как преобразовать дискретные варианты (цвета) из вывода нейронной сети в цвета непосредственно в TensorFlow?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как преобразовать дискретные варианты (цвета) из вывода нейронной сети в цвета непосредственно в TensorFlow?

Сообщение Anonymous »

Контекст: я учусь использовать Tensorflow и хочу провести простой эксперимент, где я предоставляю нейронную сеть с 4 вариантами цвета для каждого пикселя. Сеть должна научиться выбирать лучшие цвета из выбора, доступных для каждого пикселя, чтобы представлять изображение, которое оно дано. По сути, нейронная сеть с рассыланием. Это будет сравниваться с размытым справочным изображением.
У меня есть следующий код, который, я думаю, делает то, что я хочу, но над Numpy Матриц:
def convert_to_image(output_matrix, color_choices):
"""Maps network outputs to RGB colors using predefined choices."""
# Converts (height*width, 4-floats) to (height*width) array of 0-3 indices
chosen_colors = np.argmax(output_matrix, axis=1)
# Uses color_choices to mach each indice to a pixel color
mapped_image = color_choices[np.arange(color_choices.shape[0]), chosen_colors] * 255

mapped_image = mapped_image.reshape((INPUT_SHAPE[0], INPUT_SHAPE[1], 3)) # Reshape to (height, width, 3)
return mapped_image
< /code>
Однако я вскоре узнал, что не могу использовать это для обучения подкрепления, потому что Tensorflow не сможет рассчитать, что он должен изменить в сети.def convert_to_image_tf(output_matrices, color_choices_batch):
"""Maps network outputs to RGB colors using predefined choices in TensorFlow."""
batch_size = output_matrices.shape[0]
print("output_matrices dimensions: " + str(output_matrices.shape))
print("color_choices_batch dimensions: " + str(color_choices_batch.shape))
chosen_colors = tf.argmax(output_matrices, axis=2, output_type=tf.int32)
print("chosen_colors shape: " + str(chosen_colors.shape))
#batch_indices = tf.range(batch_size)[:, tf.newaxis] # Shape: (batch_size, 1)
#print("batch_indices shape: " + str(chosen_colors.shape))
#chosen_colors_expanded = tf.stack([batch_indices, chosen_colors], axis=-1) # Shape: (batch_size, width*height, 2)
#print("chosen_colors_expanded shape: " + str(chosen_colors_expanded.shape))

batch_size, num_pixels, num_choices_per_px, num_colors = color_choices_batch.shape # Extract dimensions

# Use batch-wise advanced indexing
mapped_image = color_choices[np.arange(batch_size)[:, None], np.arange(num_pixels), chosen_colors] * 255

#mapped_image = tf.gather_nd(color_choices_batch, chosen_colors) * 255 # Shape: (batch_size, width*height, 3)
# mapped_image = tf.gather(color_choices_batch, chosen_colors, batch_dims=0) * 255
print("mapped_image shape: " + str(mapped_image.shape))
mapped_image = tf.reshape(mapped_image, (INPUT_SHAPE[0], INPUT_SHAPE[1], 3)) # Reshape to (height, width, 3)
< /code>
output: < /p>
output_matrices dimensions: (32, 1024, 4)
color_choices_batch dimensions: (32, 1024, 4, 3)
chosen_colors shape: (32, 1024)
Traceback (most recent call last):
File "xxx\python_tests\dither_test_1.py", line 229, in
loss = train_step(color_decider, image_batch, color_choices_batch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "xxx\python_tests\dither_test_1.py", line 209, in train_step
generated_images = convert_to_image_tf(raw_outputs, color_choices_batch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "xxx\python_tests\dither_test_1.py", line 182, in convert_to_image_tf
mapped_image = color_choices[np.arange(batch_size)[:, None], np.arange(num_pixels), chosen_colors] * 255
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IndexError: index 4 is out of bounds for axis 1 with size 4
< /code>
Полная программа ниже. Обратите внимание, что, похоже, есть недавняя проблема с импортом TensorFlow, поэтому вам может потребоваться изменить их: < /p>
import tensorflow as tf
import tensorflow.python.keras as keras
import tensorflow.python.keras.layers as layers
import tensorflow.python.keras.losses as losses
import tensorflow.python.keras.optimizers as optimizers
import numpy as np
import os
import random
import cv2

# Define input shape
INPUT_SHAPE = (32, 32, 3) # Example: 32x32 RGB images
NUM_COLORS = 4 # The four color choices per pixel

# Second network: Color decision maker
def build_color_decider():
# First input: Matrix with 4 values per pixel
color_choices = keras.Input(shape=(INPUT_SHAPE[0] * INPUT_SHAPE[1], 4, 3), name="ColorChoices")

# Second input: Normal RGB image
image_data = keras.Input(shape=(INPUT_SHAPE[0], INPUT_SHAPE[1], 3), name="ImageData")

# Process color choices matrix
x1 = layers.Conv2D(32, (3,3), activation="relu")(color_choices)
x1 = layers.Flatten()(x1)

# Process image data matrix
x2 = layers.Conv2D(32, (3,3), activation="relu")(image_data)
x2 = layers.Flatten()(x2)

merged = layers.Concatenate()([x1, x2])
merged = layers.Dense(128, activation="relu")(merged)
# One number per pixel, representing the chosen color
output = layers.Dense(INPUT_SHAPE[0] * INPUT_SHAPE[1]*4, activation='linear')(merged) # Example output layer
output = layers.Reshape((INPUT_SHAPE[0] * INPUT_SHAPE[1], 4))(output)
model = keras.Model(inputs=[color_choices, image_data], outputs=output)
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])

model.summary()
# model = keras.Sequential([
# layers.Input(shape=(INPUT_SHAPE[0], INPUT_SHAPE[1], 4)),
# layers.Conv2D(INPUT_SHAPE[0], (3,3), activation='relu', input_shape=INPUT_SHAPE),
# layers.Conv2D(64, (3,3), activation='relu'),
# layers.Flatten(),
# layers.Dense(1024, activation='relu'),
# layers.Dense(INPUT_SHAPE[0] * INPUT_SHAPE[1] * 3, activation='linear') # Final RGB values
# ])
return model

image_dirs = ["ENTER IMAGE FOLDER HERE"] # Example folders

def load_random_image():
"""Loads a random image from one of the folders."""
chosen_dir = random.choice(image_dirs) # Pick a random folder
images = os.listdir(chosen_dir) # List images
img_path = os.path.join(chosen_dir, random.choice(images)) # Pick a random image
return img_path

def preprocess_image(img_path, downsample_factor=2, target_size=(32, 32)):
"""Loads, downsamples, and crops the image."""
img = cv2.imread(img_path) # Read image
# Calculate new size so that smallest dimension is same as target size
h, w, _ = img.shape
if h < w:
new_h = target_size[0]
new_w = int(w * (new_h / h))
else:
new_w = target_size[0]
new_h = int(h * (new_w / w))
img = cv2.resize(img, (new_w, new_h)) # Resize to maintain aspect ratio
#img = cv2.resize(img, (64, 64)) # Downsample (adjust size)

# Random Crop (Center Crop for simplicity)
crop_size = target_size[0] # Assume square crop
h, w, _ = img.shape
start_x = (w - crop_size) // 2
start_y = (h - crop_size) // 2
img = img[start_y:start_y+crop_size, start_x:start_x+crop_size] # Crop

img = img / 255.0 # Normalize
return img

def data_generator(batch_size=32):
"""Yields batches of processed images."""
while True:
batch_images = []
for _ in range(batch_size):
img_path = load_random_image()
img = preprocess_image(img_path)
batch_images.append(img)

yield np.array(batch_images)

# Create the models
color_decider = build_color_decider()

color_map = {
"cyan": [0, 255, 255], # RGB for Cyan
"magenta": [255, 0, 255], # RGB for Magenta
"yellow": [255, 255, 0], # RGB for Yellow
"black": [0, 0, 0], # RGB for Black
"white": [255, 255, 255], # RGB for White
"green": [0, 255, 0], # RGB for Green
"red": [255, 0, 0], # RGB for Red
"blue": [0, 0, 255] # RGB for Blue
}

# normalize color map values to [0, 1] range
color_map = {k: np.array(v) / 255.0 for k, v in color_map.items()}

pixel_option_1 = np.array([
color_map["cyan"],
color_map["magenta"],
color_map["yellow"],
color_map["black"]
])

pixel_option_2 = np.array([
color_map["blue"],
color_map["black"],
color_map["red"],
color_map["white"]
])

# first run with preset color choices - CMYK
color_choices = np.array([
pixel_option_1 if xcolor%2==0 else pixel_option_2 for xcolor in range(INPUT_SHAPE[0]*INPUT_SHAPE[1])
])

def data_generator_with_color_choices(batch_size=32):
"""Yields batches of processed images with color choices."""

images_generator = data_generator(batch_size)
while True:
batch_color_choices = [color_choices for _ in range(batch_size)]

yield np.array(batch_color_choices), np.array(next(images_generator))

def convert_to_image_tf(output_matrices, color_choices_batch):
"""Maps network outputs to RGB colors using predefined choices in TensorFlow."""
batch_size = output_matrices.shape[0]
print("output_matrices dimensions: " + str(output_matrices.shape))
print("color_choices_batch dimensions: " + str(color_choices_batch.shape))
chosen_colors = tf.argmax(output_matrices, axis=2, output_type=tf.int32)
print("chosen_colors shape: " + str(chosen_colors.shape))
#batch_indices = tf.range(batch_size)[:, tf.newaxis] # Shape: (batch_size, 1)
#print("batch_indices shape: " + str(chosen_colors.shape))
#chosen_colors_expanded = tf.stack([batch_indices, chosen_colors], axis=-1) # Shape: (batch_size, width*height, 2)
#print("chosen_colors_expanded shape: " + str(chosen_colors_expanded.shape))

batch_size, num_pixels, num_choices_per_px, num_colors = color_choices_batch.shape # Extract dimensions

# Use batch-wise advanced indexing
mapped_image = color_choices[np.arange(batch_size)[:, None], np.arange(num_pixels), chosen_colors] * 255

#mapped_image = tf.gather_nd(color_choices_batch, chosen_colors) * 255 # Shape: (batch_size, width*height, 3)
# mapped_image = tf.gather(color_choices_batch, chosen_colors, batch_dims=0) * 255
print("mapped_image shape: " + str(mapped_image.shape))
mapped_image = tf.reshape(mapped_image, (INPUT_SHAPE[0], INPUT_SHAPE[1], 3)) # Reshape to (height, width, 3)

return mapped_image

def blur_image(image):
"""Applies Gaussian blur to smooth the image."""
return cv2.GaussianBlur(image, (5, 5), 0) # Kernel size of (5,5)

train_data = tf.data.Dataset.from_generator(
lambda: data_generator_with_color_choices(32),
output_types=(tf.float32, tf.float32), # Two inputs: color choices & image data
output_shapes=((None, INPUT_SHAPE[0]*INPUT_SHAPE[1], 4, 3), (None, INPUT_SHAPE[0], INPUT_SHAPE[1], 3)) # First is color choices, second is image data
)

loss_fn = tf.keras.losses.MeanSquaredError()
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)

# Custom training loop
def train_step(model, image_batch, color_choices_batch):
with tf.GradientTape() as tape:
batch_size = image_batch.shape[0]
raw_outputs = model((color_choices_batch, image_batch)) # Get predictions
generated_images = convert_to_image_tf(raw_outputs, color_choices_batch)

blurred_generated_images = tf.nn.avg_pool2d(generated_images, ksize=5, strides=1, padding="SAME")
blurred_original_images = tf.nn.avg_pool2d(image_batch, ksize=5, strides=1, padding="SAME")

# Compute loss
loss = loss_fn(blurred_original_images, blurred_generated_images)

# Compute and apply gradients
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))

return loss.numpy()

# Training loop
for epoch in range(300):
for step, (color_choices_batch, image_batch) in enumerate(train_data.take(100)):
loss = train_step(color_decider, image_batch, color_choices_batch)
print(f"Epoch {epoch}, Step {step}, Loss: {loss}")



Подробнее здесь: https://stackoverflow.com/questions/796 ... t-to-color
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»