Приветствую всех! Меня зовут Сосо, и я хочу поделиться с вами своим путешествием в мир машинного обучения и глубокого обучения с использованием TensorFlow и Keras. В этой статье мы рассмотрим процесс классификации пород собак по изображениям с помощью нейронных сетей. Будем изучать, как применение этих мощных инструментов может помочь нам автоматически распознавать породы собак на фотографиях.

Машинное обучение является одной из самых захватывающих областей в современных науках о данных. Оно позволяет компьютерам обучаться на основе опыта и данных, и способно выполнять сложные задачи, включая классификацию изображений. Классификация изображений — это процесс определения категории или класса, к которому принадлежит каждое изображение.

Для нашего проекта классификации пород собак мы выбрали TensorFlow и Keras в качестве наших основных инструментов. TensorFlow — это мощная и гибкая платформа для разработки и обучения нейронных сетей, в то время как Keras предоставляет удобный и высокоуровневый интерфейс для создания моделей глубокого обучения.

Подготовка среды и загрузка данных

Первым шагом является установка TensorFlow и Keras с помощью следующих команд:

pip install tensorflow

После установки необходимых пакетов мы приступаем к настройке нашей рабочей среды, импортируя необходимые библиотеки и проверяя версию TensorFlow.

import tensorflow as tf

from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions

from tensorflow.keras.preprocessing import image

import numpy as np

import matplotlib.pyplot as plt

print(tf.__version__)

 Загрузка и предобработка изображений

Для начала загрузим изображение, с которым будем работать:

from PIL import Image

img_path = "./samples/dog_1100x628.jpg"

img = np.asarray(Image.open(img_path))

plt.imshow(img)

plt.show()

 Затем изменим размер изображения на 224x224 пикселей, так как большинство моделей глубокого обучения ожидают именно такой размер:

img = image.load_img(img_path, target_size=(224, 224))

plt.imshow(img)

plt.show()

 Мы также преобразуем изображение в массив и создадим пакет из одного изображения:

img_array = image.img_to_array(img)

print(img_array.shape)

img_batch = np.expand_dims(img_array, axis=0)

 Модели работают хорошо, когда они получают данные в постоянном диапазоне. В этом случае значения пикселей изображения находятся в диапазоне от 0 до 255. Итак, если мы запустим функцию preprocess_input() из Keras для входных изображений, мы нормализуем каждый пиксель до стандартного диапазона.

img_preprocessed = preprocess_input(img_batch)

print(img_preprocessed .shape)

Для нашего проекта мы выбрали предварительно обученную модель ResNet-50. Вот как мы можем загрузить модель:

tf.keras.applications.resnet50.ResNet50(

    include_top=True,

    weights='imagenet',

    input_tensor=None,

    input_shape=None,

    pooling=None,

    classes=1000

)

model = tf.keras.applications.resnet50.ResNet50()

 Таблица параметров обученной модели:
model = tf.keras.applications.resnet50.ResNet50()

Запускаем предварительно обученную модель(дважды)

prediction = model.predict(img_preprocessed)

Применение модели и вывод результатов

Теперь мы можем прогнозировать породу собаки на основе нашего изображения:

print(decode_predictions(prediction, top=3)[0])

print(tf.keras.applications.imagenet_utils.decode_predictions(prediction, top=5))

Таблица параметров вывода результатов классификации:
model = tf.keras.applications.resnet50.ResNet50()

После запуска кода мы получим вероятности для трех наиболее вероятных пород собак, обнаруженных на изображении.

Прогнозируемые категории для этого изображения — различные типы собак:

golden_retriever -0.7459664;

vizsla -0.06819201;

flat-coated_retriever -0.041535184;

Chesapeake_Bay_retriever-0.035749573;

Labrador_retriever-0.018360337.

Вся программа целиком

import tensorflow as tf

from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions

from tensorflow.keras.preprocessing import image

# Helper libraries

import numpy as np

import matplotlib.pyplot as plt

def classify(img_path):

    img = image.load_img(img_path, target_size=(224, 224))

    img_array = image.img_to_array(img)

    img_batch = np.expand_dims(img_array, axis=0)

    img_preprocessed = preprocess_input(img_batch)

    model = tf.keras.applications.resnet50.ResNet50()

    prediction = model.predict(img_preprocessed)

    print(decode_predictions(prediction, top=3)[0])

classify("./samples/dog_1100x628.jpg")

Мы можем Разработать визуальный интерфейс модели ResNet50() CNN Keras с использованием библиотеки Tkinter. Этот уникальный код позволяет нам распознавать объект, изображенный на фотографии, просто выбирая изображение через графический интерфейс.

from tkinter import *

from tkinter.filedialog import *

from tkinter.messagebox import *

from tkinter.ttk import Combobox

from tkinter.messagebox import showerror

from PIL import Image, ImageTk

import  pandas as pd

import tensorflow as tf

from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions

from tensorflow.keras.preprocessing import image

import numpy as np

import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)

def start_image_fure():

    try:

        url=askopenfilename()

        img=Image.open(url)

        img=image.load_img(url, target_size=(224, 224))

        render=ImageTk.PhotoImage(img, master=tk)

        lab=Label(tk,image=render)

        lab.image=render

        lab.grid(row=0,column=0)       

        img_array=image.img_to_array(img)

        img_batch=np.expand_dims(img_array, axis=0)

        img_preprocessed=preprocess_input(img_batch)

        model=tf.keras.applications.resnet50.ResNet50()

        prediction=model.predict(img_preprocessed)

        info.set(decode_predictions(prediction, top=5)[0][0][1:])

    except:

             showerror(title="Error", message="File opening error")

def close_win():  

        tk.destroy()

tk=Tk()

tk.title("Visual interface of the ResNet50 model")

main_menu=Menu(tk)

tk.config(menu=main_menu)

file_menu=Menu(main_menu)

main_menu.add_cascade(label="MENU", menu=file_menu)

file_menu.add_command(label="Open Image", command= start_image_fure)

file_menu.add_command(label="Exit", command= close_win)

info=StringVar(tk)

lab_1=Label(tk, textvariable=info, font=("Arial", 12,  "bold "),foreground='black')

lab_1.grid(row=0,column=1)   

x=(tk.winfo_screenwidth()-tk.winfo_reqwidth())/4 #центрирование формы

y=(tk.winfo_screenheight()-tk.winfo_reqheight())/16 #центрирование формы

tk.wm_geometry("+%d+%d" % (x, y))#центрирование формы

tk.geometry('550x280')

tk.mainloop()

Этот код создает окно с графическим интерфейсом, где вы можете выбрать изображение с помощью кнопки "Open Image". После выбора изображения, оно отображается в окне, и модель ResNet50 автоматически классифицирует объект на изображении. Результат классификации выводится рядом с изображением.

Tkinter предоставляет нам возможность создавать простые графические интерфейсы для взаимодействия с моделями глубокого обучения и упрощает использование моделей в реальном времени. Это отличный способ представить результаты классификации и сделать их более доступными для широкой аудитории.

Используя этот код в сочетании с предыдущими шагами, вы сможете создать полноценный проект по классификации пород собак с помощью нейронных сетей и предоставить удобный визуальный интерфейс для пользователей. Это может быть особенно полезно в случаях, когда вы хотите демонстрировать возможности модели или интегрировать ее в приложение или веб-страницу.

Выводы

В этой статье мы рассмотрели процесс классификации пород собак с использованием TensorFlow и Keras. Мы установили необходимые пакеты, загрузили и предобработали изображение, выбрали предварительно обученную модель ResNet-50 и получили результаты классификации. Машинное обучение и глубокое обучение предоставляют удивительные возможности в области распознавания объектов на изображениях, и я надеюсь, что этот проект вдохновит вас на собственные исследования и эксперименты.

Дополнительные ресурсы

Документация TensorFlow

Документация Keras

Официальный сайт проекта ResNet

Комментарии (3)


  1. fire64
    07.07.2023 06:42

    Модель сами обучали? Где брали материалы? На чем обучали и какой объем?


    1. AnonimYYYs
      07.07.2023 06:42

      В статье нифига не объяснено, потому что автор видимо и сам не понял или не разбирался.

      В общем, модель уже обучена на тысяче классов (в том моменте, когда создаем модель и указываем что веса имаджнетовские и 1000 классов - собсно все классы имаджнета).

      Более того, эта модель может распознавать не только собак - там есть и всякие раковины с петухами, более того бутылку пива оно тоже умеет классифицировать. Собак там пород 15-20 примерно, на самом деле большой процент относительно всего остального, но все равно лишь малая часть возможностей модели.

      Однако, возможно обучить и свою модель. При создании указать top=False, weights=None и num_classes не указывать. Потом объединить с Dense слоем на выход, размером с кол-во классов, замутить compile и потом fit на итоговую модель. Вот так:

          # загружаем модель ResNet50 без весов
          base_model = keras.applications.ResNet50(weights=None, include_top=False, input_shape=(224, 224, 3))
          
          # вытаскиваем выход, чтобы потом объединить с Dense слоем
          x = base_model.output
          
          # собственно, слой на custom_num_classes выходов
          predictions = keras.layers.Dense(custom_num_classes, activation='softmax')(x)
          
          # создаём окончательную модели ResNet50 с новыми слоями
          model = keras.models.Model(inputs=base_model.input, outputs=predictions)
          
          # компилируем модель, без этого не взлетит 
          model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
          
          # обучаем на датасете
          model_black.fit(x_train, y_train)

      Штука на самом деле очень неплохая, картинки небольшого размера классифицирует на ура, картинки примерно 200х200, с 20-30 классами точность выдает 75-85%, при обучении на датасетах размером 15-20 тысяч, и это если совсем не играться с гиперпараметрами. Единственное, возвращать будет массив длины custom_num_classes, поэтому функцию восстановления лейбла придется самому делать, но это буквально одна-две строки.


  1. digtatordigtatorov
    07.07.2023 06:42

    Для первой статьи не плохое начало)