У меня есть 10000 изображений, каждое из которых помечено 20 тегами.Для каждого изображения тег имеет значение true или false.Я пытаюсь обучить модель с несколькими выходами для выполнения всех этих 20 двоичных классификаций в одной сети.
Сеть является остаточной сетью.После сплющенного слоя сеть разветвляется на 20 ветвей.Каждая ветвь имеет 2 полностью связанных слоя, каждый из которых сопровождается выпадающим слоем.И, наконец, плотный слой с одним узлом и сигмовидной активацией в конце.
Метки для каждого изображения и имени изображения хранятся в текстовом файле, как для поезда, так и для набора проверки.Например: 1.jpg 1 -1 1 -1 -1 1 -1 .........
Я написал собственный генератор, но не могу заставить их работать.Я получаю эту ошибку:
Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 20 array(s), but instead got the following list of 1 arrays.
Объяснения функций: get_input
функция читает изображение и изменяет его размер.get_output
подготавливает ярлыки для каждого изображения.Метки хранятся в списке и возвращаются в конце.preprocess_input
выполняет предварительную обработку и преобразование изображений в массивы.train_generator
и validation_generator
генерируют пакеты размером 32 для подачи на модель.
Вот мой код:
def get_input(img_name):
path = os.path.join("images", img_name)
img = image.load_img(path, target_size=(224, 224))
return img
def get_output(img_name, file_path):
data = pd.read_csv(file_path, delim_whitespace=True, header=None)
img_id = img_name.split(".")[0]
img_id = img_id.lstrip("0")
img_id = int(img_id)
labels = data.loc[img_id - 1].values
labels = labels[1:]
labels = list(labels)
label_arrays = []
for i in range(20):
val = np.zeros((1))
val[0] = labels[i]
label_arrays.append(val)
return label_arrays
def preprocess_input(img_name):
img = get_input(img_name)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
return x
def train_generator(batch_size):
file_path = "train.txt"
data = pd.read_csv(file_path, delim_whitespace=True, header=None)
while True:
for i in range(math.floor(8000/batch_size)):
x_batch = np.zeros(shape=(32, 224, 224, 3))
y_batch = np.zeros(shape=(32, 20))
for j in range(batch_size):
img_name = data.loc[i * batch_size + j].values
img_name = img_name[0]
x = preprocess_input(img_name)
y = get_output(img_name, file_path)
x_batch[j, :, :, :] = x
y_batch[j] = y
yield(x_batch, y_batch)
def val_generator(batch_size):
file_path = "val.txt"
data = pd.read_csv(file_path, delim_whitespace=True, header=None)
while True:
for i in range(math.floor(2000/batch_size)):
x_batch = np.zeros(shape=(32, 224, 224, 3))
y_batch = np.zeros(shape=(32, 20))
for j in range(batch_size):
img_name = data.loc[i * batch_size + j].values
img_name = img_name[0]
x = preprocess_input(img_name)
y = get_output(img_name, file_path)
x_batch[j, :, :, :] = x
y_batch[j] = y
yield(x_batch, y_batch)
Редактировать: Один быстрый вопрос.В чем разница между этой петлей и той, что в вашем ответе:
ys = []
for i in range(batch_size):
ys.append(y_batch[i, :])
yield(x_batch, ys)