Я занимаюсь построением нейронных сетей, но постоянно застреваю на обучении NN.
На этот раз я хотел сделать Intel Image Classification от (Kaggle).
Я использую тензорный поток 2.12 в WSL.
Импорт, метки, пути данных:
import tensorflow as tf
import os
from tqdm import tqdm
import numpy as np
# Labels
labels = ["buildings", "forest", "glacier", "mountain", "sea", "street"]
# Data directories
train_data = os.path.join(os.getcwd(), "data", "seg_train", "seg_train")
test_data = os.path.join(os.getcwd(), "data", "seg_test", "seg_test")
# Shape of the input data (needs color channel as last dimension)
data_shape = (150, 150, 3)
# Set up filepath dictionary
train_dirs = {}
test_dirs = {}
for label in labels:
train_dirs[label] = os.path.join(train_data, label)
test_dirs[label] = os.path.join(test_data, label)
Вспомогательные функции для обработки данных:
# Prepare list of files with asociated labels and remove files that have size other than desired data_shape
def remove_bad_data(dirs_dict):
indexed_files = []
for idx, directory in enumerate(dirs_dict):
listfiles = os.listdir(dirs_dict[directory])
for file in listfiles:
image_path = os.path.join(dirs_dict[directory], file)
image = tf.io.read_file(image_path)
image = tf.io.decode_image(image, channels=data_shape[-1])
if image.shape == data_shape:
indexed_files.append((image_path, idx))
else:
os.remove(image_path)
print(f"Removed file with shape {image.shape} located at: {image_path}")
return indexed_files
# Define image preprocessing function
def preprocess_images(image_path, label):
image = tf.io.read_file(image_path)
image = tf.io.decode_image(image, channels=data_shape[-1])/255
return (image, label)
# Define dataset pipeline function
def dataset_pipeline(dataset):
dataset = dataset.map(map_func=preprocess_images)
dataset = dataset.cache()
dataset = dataset.shuffle(buffer_size=len(dataset))
dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)
return dataset
Создание набора данных
train_files = remove_bad_data(train_dirs)
test_files = remove_bad_data(test_dirs)
# Create a dataset
train_files = np.array(train_files)
train_dataset = tf.data.Dataset.from_tensor_slices((train_files[:,0].astype(str), train_files[:,1].astype(int)))
train_dataset = dataset_pipeline(dataset=train_dataset)
в этот момент train_dataset.as_numpy_iterator().next() возвращает кортеж массива (150, 150, 3) и метку (int от 0 до 6).
# Define the model architecture
input_layer = tf.keras.Input(shape=data_shape, name = "input_layer")
conv_layer = tf.keras.layers.Conv2D(filters=16, kernel_size=3, padding = "same", activation = "relu", name = "first_conv2d")(input_layer)
maxpool_layer = tf.keras.layers.MaxPool2D(name = "first_maxpool")(conv_layer)
conv_layer = tf.keras.layers.Conv2D(filters=32, kernel_size=3, padding = "same", activation = "relu", name = "second_conv2d")(maxpool_layer)
maxpool_layer = tf.keras.layers.MaxPool2D(name = "second_maxpool")(conv_layer)
conv_layer = tf.keras.layers.Conv2D(filters=64, kernel_size=3, padding = "same", activation = "relu", name = "third_conv2d")(maxpool_layer)
maxpool_layer = tf.keras.layers.MaxPool2D(name = "third_maxpool")(conv_layer)
conv_layer = tf.keras.layers.Conv2D(filters=128, kernel_size=3, padding = "same", activation = "relu", name = "fourth_conv2d")(maxpool_layer)
maxpool_layer = tf.keras.layers.MaxPool2D(name = "fourth_maxpool")(conv_layer)
flatten_layer = tf.keras.layers.Flatten(name = "flatten_layer")(maxpool_layer)
dense_layer = tf.keras.layers.Dense(units=128, activation = "relu")(flatten_layer)
output_layer = tf.keras.layers.Dense(units=len(labels), name = "output_layer")(dense_layer)
# Initialize model
model = tf.keras.Model(inputs=input_layer, outputs=output_layer, name = "intel_classification")
model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
tf.keras.utils.plot_model(model, "model.png", show_shapes=True)
history = model.fit(train_dataset)
Когда я пытаюсь обучить модель, я продолжаю получать эту ошибку:
ValueError: slice index 0 of dimension 0 out of bounds. for '{{node strided_slice}} = StridedSlice[Index=DT_INT32, T=DT_INT32, begin_mask=0, ellipsis_mask=0, end_mask=0, new_axis_mask=0, shrink_axis_mask=1](Shape, strided_slice/stack, strided_slice/stack_1, strided_slice/stack_2)' with input shapes: [0], [1], [1], [1] and with computed input tensors: input[1] = <0>, input[2] = <1>, input[3] = <1>.
Я попытался изменить функцию потерь на CategoricalCrossentropy(), но затем столкнулся с другой ошибкой:
2023-04-18 15:25:56.800730: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor 'Placeholder/_1' with dtype int64 and shape [13986]
[[{{node Placeholder/_1}}]]
2023-04-18 15:25:56.800956: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor 'Placeholder/_1' with dtype int64 and shape [13986]
[[{{node Placeholder/_1}}]]
Traceback (most recent call last):
File "/home/jw/projects/testmodels/main.py", line 109, in <module>
history = model.fit(train_dataset)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/utils/traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/tmp/__autograph_generated_file7w1vt_rv.py", line 15, in tf__train_function
retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
ValueError: in user code:
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/training.py", line 1284, in train_function *
return step_function(self, iterator)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/training.py", line 1268, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/training.py", line 1249, in run_step **
outputs = model.train_step(data)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/training.py", line 1051, in train_step
loss = self.compute_loss(x, y, y_pred, sample_weight)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/training.py", line 1109, in compute_loss
return self.compiled_loss(
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/engine/compile_utils.py", line 265, in __call__
loss_value = loss_obj(y_t, y_p, sample_weight=sw)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/losses.py", line 142, in __call__
losses = call_fn(y_true, y_pred)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/losses.py", line 268, in call **
return ag_fn(y_true, y_pred, **self._fn_kwargs)
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/losses.py", line 1984, in categorical_crossentropy
return backend.categorical_crossentropy(
File "/home/jw/projects/testmodels/venv/lib/python3.10/site-packages/keras/backend.py", line 5559, in categorical_crossentropy
target.shape.assert_is_compatible_with(output.shape)
ValueError: Shapes () and (None, 6) are incompatible
Вы забыли пакетировать набор данных.
BATCHSIZE = 32
def dataset_pipeline(dataset):
dataset = dataset.map(map_func=preprocess_images)
dataset = dataset.cache()
dataset = dataset.shuffle(buffer_size=len(dataset))
dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)
dataset = dataset.batch(BATCHSIZE) # you need to add this
return dataset
Вы должны передать тензор размера (batch_size, 150, 150, 3) в метод model.fit
.