Добавил:
Кафедра ВТ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Проект / НС_проект_отчёт.docx
Скачиваний:
3
Добавлен:
07.04.2023
Размер:
1.22 Mб
Скачать

МИНОБРНАУКИ РОССИИ

САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ

ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)

Кафедра вычислительной техники

Отчёт по проекту

по дисциплине «Нейронные сети»

Тема: Разработка модели нейронной сети для классификации изображений

Студенты гр.

Преподаватель

Викснин И.И.

СОДЕРЖАНИЕ

Введение 3

Введение 3

Постановка задачи 3

Постановка задачи 3

Сбор данных 3

Сбор данных 3

План работы 3

План работы 3

Добавление аугментированных фотографий 4

Добавление аугментированных фотографий 4

Подготовка данных 8

Подготовка данных 8

Создание новой папочной структуры 11

Создание новой папочной структуры 11

Демонстрация работы архитектуры 14

Демонстрация работы архитектуры 14

Обучение с помощью CNN 18

Обучение с помощью CNN 18

Принципы предыдущих архитектур 28

Принципы предыдущих архитектур 28

Вывод 33

Вывод 33

Введение

Постановка задачи

Целями разработки проекта являются: получение навыков работы со свёрточными нейронными сетями (CNN), получение опыта при подготовки датасета к обучению, создание и анализ архитектур для нейронных сетей на Python.

Сбор данных

Набор данных представлен 7000 изображениями автомобилей на 197 классов по марке, году выпуска и модели. Для получения адекватных результатов будет применена аугментация данных (библиотеки Torch.Transforms и/или Albumentations). После добавления аугментированных изображений файлов стало в 2 раза больше (14000).

План работы

  1. Аугментация данных;

  2. Создание новой папочной структуры;

  3. Распаковка и определение меток класса;

  4. Разработка архитектур и обучение.

Добавление аугментированных фотографий

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

Мы будем использовать следующие методы аугментации данных:

  1. Resize – Выбор случайного обреза 224x224;

  2. Random Rotation – Случайный поворот на небольшой угол в 10*;

  3. Random Flip – Рандомное отражение по горизонтиали;

  4. Gauss Blur – Применение Гауссовского размытия;

Мы производим удаление старых аугментированных фотографий, если они есть, то есть подготавливаем датасет к загрузке новых аугментированных фотографий, чтобы не было ошибок и коллизий:

# Удаление всех аугментированных фотографий

dir_name = DATASET_PATH + "/dataset"

all_files = os.listdir(dir_name)

print(len(all_files))

# + обновите файл csv

for file in all_files:

if "aug" in file:

os.remove(os.path.join(dir_name, file))

Создаём новые аугментированные фотографии и добавляем их в датасет, а также трансформируем тензоры фотографий в формат 224x224 для новых аугментированных изображений:

all_files = os.listdir(dir_name)

print(len(all_files))

import os

import sys

import PIL

from PIL import Image

from imgaug import augmenters as iaa

import imageio.v2 as imageio

# Определение преобразований

transform = transforms.Compose([

transforms.Resize((224, 224)),

transforms.RandomHorizontalFlip(), # Случайное отражение по горизонтали

transforms.RandomRotation(10), # Случайный поворот на 10 градусов

#transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.1),

transforms.GaussianBlur(kernel_size=(7, 13), sigma=(0.1, 1.0)), # blur images with a sigma of 0.1 to 1.0

transforms.ToTensor(), # Преобразование в тензор

# transforms.RandomResizedCrop(224), # Случайный обрез на размер 224x224

transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # Нормализация

])

def augmentation(pilimg):

return transforms.ToPILImage()(transform(pilimg))

csv_file = pd.read_csv(DATASET_PATH+"/train.csv")

print("Before: ", len(csv_file))

dest_dir = DATASET_PATH + "/dataset"

print("Проверка! Файлов в датасете (до обработки):", end = " ")

all_files = os.listdir(dest_dir)

print(len(all_files))

suffix = "_aug1."

# files = ["/content/drive/MyDrive/Colab Notebooks/dataset/dataset/00001.jpg"]

files = [os.path.join(path, name) for path, subdirs, files in os.walk(dest_dir) for name in files]

files.sort()

# print(dest_dir, files)

gi, N = 0, len(files)

for file_i in files:

if "_aug" not in file_i:

file_i_rel = os.path.relpath(file_i, dest_dir)

file_i_out = os.path.join(dest_dir, file_i_rel)

file_parts = file_i_out.split(".")

imagepil = PIL.Image.open(file_i)

imagepil = imagepil.convert('RGB')

imagepil.load()

imagepil = augmentation(imagepil)

new_filename = file_parts[0]+suffix+file_parts[1]

imagepil.save(new_filename)

new_classs = csv_file[csv_file.image == file_i_rel].Class.item()

new_row = pd.Series({'image': os.path.relpath(new_filename, dest_dir),

'Class': new_classs})

csv_file = csv_file.append(new_row, ignore_index=True)

# csv_file = pd.concat([csv_file, new_row])

gi+=1

if gi % 1000 == 0:

print("Прошло файлов: " + str(gi))

# Как отсортировать строки по имени в csv?

csv_file = csv_file.sort_values(by=["image"])

print("After: ", len(csv_file))

csv_file.to_csv(DATASET_PATH+"/train.csv", index=False)

print("Проверка! Файлов в датасете (после обработки):", end = " ")

all_files = os.listdir(dest_dir)

print(len(all_files))

Подготовка данных

Произведём импорт необходимых библиотек, монтирование диска, с которого будем считывать фотографии, а также определив их по классам, указанным в файле “train.csv”. Затем трансформируем новые аугментированные фотографии в определённый заранее формат – 224x224 пикселя для корректной работы модели, чтобы она читала и загружала в тензоры один формат для всех данных.

Мы не будем менять формат фотографий, то есть не будем конвертировать имеющиеся фотографии в формат 224x224 пикселя, мы будем сразу сжимать их при загрузке в тензор.

Производим импорт необходимых библиотек и монтирование диска:

import torch

import torchvision

# dataset preparation

import torchvision.transforms as transforms

# NN

import torch.nn as nn

import torch.nn.functional as F

import torch.optim as optim

from torchvision import models as torch_models

# Utils

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

# Other

import os

import zipfile

import requests

import hashlib

import random

import time

import datetime

import PIL

from PIL import Image

np.random.seed(5051)

device = "cuda" if torch.cuda.is_available() else "cpu"

#DATASET_PATH = "/content/drive/MyDrive/dataset"

DATASET_PATH = "/content/drive/MyDrive/Colab Notebooks/dataset"

from google.colab import drive

drive.mount('/content/drive/')

Читаем csv-файл, который содержит метки класса:

csv_file = pd.read_csv(DATASET_PATH+"/train.csv")

print(csv_file)

print(len(csv_file))

# classes = list(set(csv_file["Class"]))

files_cars = list(csv_file["image"])

# print(classes)

print(files_cars)

Создание новой папочной структуры

На основе ImageFolder мы строили тестовую и обучающие выборки для аугментированных фотографий. Изначально на основе оригинала создавалась аугментированная фотография, из которых рандомно делались различные выборки, а метки классов назначались из csv-файла. В ImageFolder изначально имелась структура данных, где каждая папка – это “train” или “test” выборка, в которой были папки с соответствующими классами.

Код структуры:

NEW_DATASET_PATH = "/content/drive/MyDrive/Colab Notebooks/new_dataset"

train_dir = NEW_DATASET_PATH + "/train"

test_dir = NEW_DATASET_PATH + "/test"

import shutil

# Заблокировать на случай, если уже создана папочная структура

os.mkdir(NEW_DATASET_PATH)

os.mkdir(train_dir)

os.mkdir(test_dir)

classes = set(list(csv_file["Class"]))

for classs in classes:

os.mkdir(os.path.join(train_dir, str(classs)))

os.mkdir(os.path.join(test_dir, str(classs)))

# ------------------------------------------------------------

all_files = os.listdir(DATASET_PATH+"/dataset")

random.shuffle(all_files)

# Разделяем тренировочную и тестовую выборки в соответствие 90 на 10

length = len(all_files)

bound = int(length*0.9)

train_files = all_files[0:bound]

test_files = all_files[bound:length]

def generate_new_folder(files, dir):

for file in files:

classs = str(csv_file[csv_file.image == file].Class.item())

src_file = os.path.join(DATASET_PATH+"/dataset", file)

dest_file = os.path.join(dir, classs, file)

try:

shutil.copyfile(src_file, dest_file)

except FileNotFoundError:

print("No such file or directory: ", src_file)

# раскидывает файлы по папочкам

generate_new_folder(train_files, train_dir)

generate_new_folder(test_files, test_dir)

Соседние файлы в папке Проект