Модель с MNIST дает низкую точность и длительное время обучения, когда данные загружаются с помощью tf.data.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Модель с MNIST дает низкую точность и длительное время обучения, когда данные загружаются с помощью tf.data.

Сообщение Anonymous »

Я новичок в машинном обучении и Python. Извините за вопрос для новичков.
Я использую набор данных MNIST для изучения простой модели CNN.
Во-первых, я данные MNIST сохранены в файлы png.

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

import cv2
import os

from keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()

img_root = './images'
train = os.path.join(img_root, 'train')
test = os.path.join(img_root, 'test')

if not os.path.exists(img_root):
os.mkdir(img_root)

if not os.path.exists(train):
os.mkdir(train)

if not os.path.exists(test):
os.mkdir(test)

# Save Train images
for i in range(x_train.shape[0]):
img_dir = os.path.join(train, str(y_train[i]))
if not os.path.exists(img_dir):
os.mkdir(img_dir)
image_out = os.path.join(img_dir, str(i) + ".png")
cv2.imwrite(image_out, x_train[i])

# Save Test images
for i in range(x_test.shape[0]):
img_dir = os.path.join(test, str(y_test[i]))
if not os.path.exists(img_dir):
os.mkdir(img_dir)
image_out = os.path.join(img_dir, str(i) + ".png")
cv2.imwrite(image_out, x_test[i])
Затем я загрузил эти изображения тремя разными методами и провел обучение модели.
Метод 1 «cv_only» : загрузить все изображения в массив numpy с помощью cv2.imread(). Не используйте tf.data.
Результаты:

Эпоха 48/50
469/469 [======= ======================] - 2 с 5 мс/шаг - потеря: 0,0025 - точность: 0,9992 - val_loss: 0,0490 - val_accuracy: 0,9937

Эпоха 49/50
469/469 [================ =============] - 2 с 5 мс/шаг - потеря: 0,0042 - точность: 0,9990 - val_loss: 0,0477 - val_accuracy: 0,9924


Эпоха 50/50
469/469 [========================= ===] - 2 с 5 мс/шаг - потеря: 0,0033 - точность: 0,9991 - val_loss: 0,0485 - val_accuracy: 0,9914


Время обучения: 199[с]

Метод 2 «tf_cv»: используйте tf.data.Dataset.from_tensor_slices() , Map() и Batch() для создания наборов данных. Внутри метода map() используется cv2.imread() для чтения изображений.
Результаты:

Эпоха 48/50
469/ 469 [============================] - 32 с 68 мс/шаг - потеря: 5.8638e-07 - точность: 1.0000 - val_loss: 4.7863 - val_accuracy: 0.4507


Эпоха 49/50
469/469 [===== =======================] - 32 с 68 мс/шаг - потеря: 4.6416e-07 - точность: 1,0000 - val_loss: 4,8436 - val_accuracy: 0,4514


Эпоха 50/50
469/469 [============ =================] - 32 с 69 мс/шаг - потеря: 3.6748e-07 - точность: 1,0000 - val_loss: 4,8742 - val_accuracy: 0,4517


Время обучения: 1638[с]

Метод 3 «tf_only: используйте методы tf.data.Dataset.from_tensor_slices(), Map() и Batch() для создания наборов данных (то же, что и метод 2). Но метод Inside map() использует tf.io.read_file() для чтения изображений.
Результаты:

Эпоха 48/50
469/469 [=============================] - 16 с 33 мс/шаг - потеря: 8.5148e-07 - точность : 1.0000 - val_loss: 5.4608 - val_accuracy: 0.4065


Эпоха 49/50
469/469 [== ==========================] - 16 с 34 мс/шаг - потеря: 6.7230e-07 - точность: 1.0000 - val_loss: 5.4721 - val_accuracy: 0,4085


Эпоха 50/50
469/469 [========= ====================] - 15 с 33 мс/шаг - потеря: 5.3065e-07 - точность: 1,0000 - val_loss: 5,4845 - val_accuracy: 0,4087


Время обучения: 700[с]

Что такое Я делаю неправильно в методах 2 и 3. Пожалуйста, помогите.
Это полный код модели, которую я использовал.

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

import numpy as np
import cv2
import glob
import datetime

import tensorflow as tf
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from keras.layers import Dense, Flatten
from keras.utils import to_categorical

# Valid Options are "cv_only", "tf_cv" and "tf_only"
data_load_method = "tf_cv"

train_images = "./images/train/"
test_images = "./images/test/"

# network parameters
batch_size = 128

categories = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
num_classes = len(categories)

def make_sample_imgs(files):
global X, Y
X = []
Y = []
for cat, fname in files:
X.append(cv2.imread(fname, cv2.IMREAD_GRAYSCALE))
Y.append(cat)
return np.array(X), np.array(Y)

def make_sample(files):
global X, Y
X = []
Y = []
for cat, fname in files:
X.append(fname)
Y.append(cat)
return np.array(X), np.array(Y)

def process_path_cv2(image_path, label):

def load_image(path):
image_gray = cv2.imread(path.decode("utf-8"), cv2.IMREAD_GRAYSCALE)
image_gray = image_gray.astype('float32')/255
image_gray = tf.expand_dims(image_gray, axis=-1)
return image_gray

image = tf.numpy_function(load_image, [image_path], tf.float32)
return image, label

def process_path_tf(image_path, label):
image = tf.io.read_file(image_path)
image = tf.image.decode_image(image, channels=1)
image = tf.image.convert_image_dtype(image, tf.float32)
return image, label

start_time = datetime.datetime.now()

train = []
test = []

for idx, cat in enumerate(categories):
image_dir = train_images + cat
files = glob.glob(image_dir + "/*.png")
for f in files:
train.append((idx, f))
print("Train ", image_dir, "append ", len(files), "files!")

for idx, cat in enumerate(categories):
image_dir = test_images + cat
files = glob.glob(image_dir + "/*.png")
for f in files:
test.append((idx, f))
print("Test ", image_dir, "append ", len(files), "files!")

if data_load_method == "cv_only":
x_train, y_train = make_sample_imgs(train)
x_test, y_test = make_sample_imgs(test)

# convert to one-hot vector
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)

x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255

elif data_load_method == "tf_cv"  or data_load_method == "tf_only":
x_train, y_train = make_sample(train)
x_test, y_test = make_sample(test)

# convert to one-hot vector
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

train_datasets = tf.data.Dataset.from_tensor_slices((x_train, y_train))
test_datasets = tf.data.Dataset.from_tensor_slices((x_test, y_test))

if data_load_method == "tf_cv":
train_datasets = train_datasets.map(process_path_cv2, num_parallel_calls=tf.data.AUTOTUNE)
test_datasets = test_datasets.map(process_path_cv2, num_parallel_calls=tf.data.AUTOTUNE)

else:
train_datasets = train_datasets.map(process_path_tf, num_parallel_calls=tf.data.AUTOTUNE)
test_datasets = test_datasets.map(process_path_tf, num_parallel_calls=tf.data.AUTOTUNE)

# train_datasets = train_datasets.cache()
# test_datasets = test_datasets.cache()

train_datasets = train_datasets.batch(batch_size)
test_datasets = test_datasets.batch(batch_size)
train_datasets = train_datasets.prefetch(tf.data.AUTOTUNE)
test_datasets = test_datasets.prefetch(tf.data.AUTOTUNE)

else:
print("Method not defined!")
exit()

model = Sequential()

model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same", activation="relu", input_shape=(28, 28, 1)))
model.add(Conv2D(filters=64, kernel_size=(3, 3), padding="same", strides=2, activation="relu"))
model.add(BatchNormalization())

model.add(Conv2D(filters=128, kernel_size=(3, 3), padding="same", strides=2, activation="relu"))
model.add(Conv2D(filters=128, kernel_size=(3, 3), padding="same", strides=2, activation="relu"))
model.add(BatchNormalization())

model.add(Conv2D(filters=256, kernel_size=(3, 3), padding="same", strides=2, activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())

model.add(Flatten())
model.add(Dense(512, activation="relu"))

model.add(Dense(10, activation="softmax"))

model.summary()

model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])

if data_load_method == "cv_only":
model.fit(x_train, y_train, epochs=50, batch_size=batch_size, validation_data=(x_test, y_test))

elif data_load_method == "tf_cv" or data_load_method == "tf_only":
model.fit(train_datasets, epochs=50, batch_size=batch_size, validation_data=test_datasets)

end_time = datetime.datetime.now()
time_diff = (end_time - start_time)
learning_time = time_diff.total_seconds()
print(f'Learning time: {int(learning_time)}[s]')
Если я использую

train_datasets = train_datasets.cache()


test_datasets = test_datasets.cache()

тогда время можно сократить примерно до 150 секунд , Но валюта также drop.
Я использую python 3.10, keras 2.10.0, tensorflow-gpu 2.10.0
Извините за беспорядочный код. Я все еще учусь программированию.

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

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

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

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

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

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

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