InvalidArgumentError: только один входной размер может быть -1, а не 0 и 1 в модели TensorFlow во время прогнозирования Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 InvalidArgumentError: только один входной размер может быть -1, а не 0 и 1 в модели TensorFlow во время прогнозирования

Сообщение Anonymous »

Я работаю над моделью TensorFlow для распознавания лиц, в которой я предварительно обрабатываю изображения, генерирую встраивания и затем сохраняю их в базе данных CSV. Модель отлично работает при прогнозировании по пакету изображений (форма: (12000, 112, 112, 3)), но когда я пытаюсь прогнозировать по одному изображению (форма: (1, 112, 112, 3)), я возникла следующая ошибка:

Код: Выделить всё

InvalidArgumentError: Graph execution error:

Detected at node sequential_13_1/flatten_13_1/Reshape defined at (most recent call last):
...
only one input size may be -1, not both 0 and 1
Я сузил проблему до следующей строки в своем коде:

Код: Выделить всё

new_embedding = model.predict(new_image)  # Generating embedding for new image
Вот мой код для создания вложений и добавления нового человека в базу данных:

Код: Выделить всё

import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity

def preprocessing_new_person(person_path):
img = cv2.imread(person_path)
img_resized = cv2.resize(img, (112, 112))
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_normalized = img_resized / 255.0
img_expanded = np.expand_dims(img_normalized, axis=0)  # Shape becomes (1, 112, 112, 3)
return np.array(img_expanded)

def generate_new_embedding(new_image, model):
return model.predict(new_image)

def add_to_database(new_image, new_label, model, database_filename='embeddings_database.csv'):
new_embedding = generate_new_embedding(new_image, model)
try:
database = pd.read_csv(database_filename)
except FileNotFoundError:
database = pd.DataFrame()
new_entry = pd.DataFrame(new_embedding, columns=[f'feature_{i}' for i in range(new_embedding.shape[1])])
new_entry['label'] = new_label
updated_database = pd.concat([database, new_entry], ignore_index=True)
updated_database.to_csv(database_filename, index=False)

# Example usage:
new_image = preprocessing_new_person("/path/to/image.jpg")
new_label = 'New Person'
add_to_database(new_image, new_label, model)
Вот полный код модели CNN (проблема не в CNN, поскольку первое предсказание с использованием 12000 изображений работает нормально):

Код: Выделить всё

import tensorflow as tf
from tensorflow.keras import layers, models
import numpy as np
import pandas as pd
import random
from sklearn.metrics.pairwise import cosine_similarity

from tensorflow.keras import layers, models

def generate_triplets(data, labels, num_triplets):
"""
Generates triplets for metric learning.

Parameters:
- data: numpy array of image data
- labels: numpy array of corresponding labels
- num_triplets: number of triplets to generate

Returns:
- x_triplets: numpy array of triplets (anchor, positive, negative)
- y_triplets: numpy array of labels for the triplets (all ones as labels)
"""
x_triplets = []
y_triplets = []
label_indices = {label:  np.where(labels == label)[0] for label in np.unique(labels)}

for _ in range(num_triplets):
anchor_label = random.choice(list(label_indices.keys()))
positive_label = anchor_label
negative_label = random.choice([label for label in label_indices.keys() if label != anchor_label])

anchor_idx = random.choice(label_indices[anchor_label])
positive_idx = random.choice(label_indices[positive_label])
negative_idx = random.choice(label_indices[negative_label])

anchor = data[anchor_idx]
positive = data[positive_idx]
negative = data[negative_idx]

x_triplets.append([anchor, positive, negative])
y_triplets.append(anchor_label)

x_triplets = np.array(x_triplets)
# Reshape the triplets to merge the triplet dimension into the batch dimension
x_triplets = x_triplets.reshape(-1, x_triplets.shape[2], x_triplets.shape[3], x_triplets.shape[4])

y_triplets = np.array(y_triplets)
# Repeat labels three times to match the reshaped triplets
y_triplets = np.repeat(y_triplets, 3)

return x_triplets, y_triplets

# Define the CNN model
def create_model(input_shape):
model = models.Sequential()

# Convolutional Layer 1
model.add(layers.Conv2D(16, (3, 3), strides=1, padding='same', activation='relu', input_shape=input_shape))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2)))

# Convolutional Layer 2
model.add(layers.Conv2D(32, (3, 3), strides=1, padding='same', activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2)))

# Convolutional Layer 3
model.add(layers.Conv2D(64, (3, 3), strides=1, padding='same', activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2)))

# Convolutional Layer 4
model.add(layers.Conv2D(128, (3, 3), strides=1, padding='same', activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2)))

# Flattening Layer
model.add(layers.Flatten())

# Fully Connected Layers
model.add(layers.Dense(512, activation='relu'))  # FC1
model.add(layers.Dense(255))  # FC2

return model

# Triplet loss function
def triplet_loss(y_true, y_pred, alpha=0.2):
anchor, positive, negative = tf.split(y_pred, num_or_size_splits=3, axis=0)
pos_dist = tf.reduce_sum(tf.square(anchor - positive), axis=-1)
neg_dist = tf.reduce_sum(tf.square(anchor - negative), axis=-1)
loss = tf.maximum(pos_dist - neg_dist + alpha, 0.0)
return tf.reduce_mean(loss)

def triplet_validation_metric(y_true, y_pred, alpha=0.2):
# Split embeddings into anchor, positive, and negative
anchor, positive, negative = tf.split(y_pred, num_or_size_splits=3, axis=0)

# Compute distances
pos_dist = tf.reduce_sum(tf.square(anchor - positive), axis=1)
neg_dist = tf.reduce_sum(tf.square(anchor - negative), axis=1)

# Check if triplet condition is satisfied
valid_triplets = tf.reduce_mean(tf.cast(pos_dist + alpha < neg_dist, tf.float32))
return valid_triplets

# Training the model
input_shape = (112, 112, 3)
model = create_model(input_shape)

optimizer = tf.keras.optimizers.Adam(learning_rate=0.0004)
# Compile the model with the validation metric
model.compile(optimizer=optimizer, loss=triplet_loss, metrics=[triplet_validation_metric])
model.summary()

# Generate triplets (train and test data assumed to be preloaded)
x_triplets_train, y_triplets_train = generate_triplets(train_data, train_labels, num_triplets=1500)
x_triplets_test, y_triplets_test = generate_triplets(test_data, test_labels, num_triplets=1500)

# Train the model
model.fit(x_triplets_train, y_triplets_train, epochs=20, validation_data=(x_triplets_test, y_triplets_test), batch_size=30)
Помните, что входной размер верен, но модель все равно не дает прогноза

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

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

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

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

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

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

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