Прогнозирование лесных пожаров с использованием PyTorch

«Перенос обучения на ЦП – эффективный способ построения точных классификаторов изображений»

В этой статье я использую перенос обучения с помощью PyTorch* для классификации воздушных фотографий в соответствии с опасностью пожаров на них, используя только детали изображения. Набор данных MODIS fire dataset (MODIS fire dataset) содержит информацию о известных пожарах в Калифорнии с 2018 по 2020 год. Набор данных MODIS (Moderate Resolution Imaging Spectroradiometer) содержит изображения высокого разрешения и размеченные области на карте для заданного временного периода, чтобы получить информацию о прошлых местах локализации лесных пожаров. Затем я выбрал изображения из предыдущего двухлетнего периода, 2016–2017 гг., в областях внутри и недалеко от будущих пожарных регионов. Перенос обучения используется для адаптации предварительно обученной модели ResNet 18 (которая ранее не обучалась на воздушных фотографиях) с добавлением сотен изображений, помеченных как “Пожар” и “Нет пожара”.

Тонкая настройка предварительно обученной модели (оригинально обученной на наборе данных ImageNet) для использования с воздушными фотографиями является эффективным подходом для извлечения значимой информации из этих изображений в контексте прогнозирования лесных пожаров. Архитектура ResNet, с ее глубокими слоями и пропускными соединениями, доказала свою эффективность в различных задачах компьютерного зрения, включая распознавание объектов и классификацию изображений. С использованием этого подхода мне нужно всего лишь несколько сотен изображений и примерно 15 минут времени процессора, чтобы построить точную модель. Читайте дальше для получения более подробной информации!

Кейс-стади по использованию воздушных изображений

Мой подход заключался в создании бинарного классификатора, сосредоточенного только на предсказании с помощью воздушных изображений известных пожарных и непожарных регионов в Калифорнии за период с 2016 по 2021 год. Обучающий набор состоял из воздушных фотографий с 2016 по 2017 года — до пожаров в критических регионах. Оценочный набор состоял из изображений из тех же мест, сделанных с 2018 по 2020 год (и расширенного набора, включающего изображения с 2021 года). Выбраны как пожарные, так и непожарные регионы. Вероятность возникновения лесных пожаров определяется по областям известных лесных пожаров, полученных из набора данных MODIS. Выбранные области находились в районе Сакраменто и от побережья до Сьерра-Невада. В этом регионе в прошлом произошло много больших и смертельных пожаров.

Получение данных

Получение данных и их предварительная обработка выполнялись в следующих основных этапах. Сначала я использовал Google Earth Engine* и программу на JavaScript* для сбора данных о лесных пожарах и воздушных фотографий с помощью проектных скриптов, которые можно найти в репозитории ForestFirePrediction. Затем я создал карту на основе набора данных USDA/NAIP/DOQQ Министерства сельского хозяйства США. Наконец, я выбрал воздушные фотографии из набора данных NASA MODIS/006/MCD64A1.

Пожарные и непожарные регионы, определенные MODIS с 2018 по 2020 год, показаны на рисунках 1 и 2. Красные области — это области, где были пожары. Оранжевые и голубые штыри представляют выбранные места для использованных изображений, при этом голубой цвет обозначает выбранные точки без пожаров, а оранжевый — выбранные точки с пожарами. Каждое изображение охватывает примерно 60 квадратных миль.

Изображение 1

Для выборки воздушных фотографий используется набор данных NAIP/DOQQ. Например, на рисунке 3 показано воздушное изображение около города Парадайс, Калифорния, до большого пожара (2018 г.), который затронул этот город.

У меня есть 106 образцов для пожарных регионов и 111 образцов для непожарных регионов (Таблица 1). Используя перенос обучения, мой набор данных может быть намного меньше, чем если бы я обучал модель с нуля. Распределение обучающих, проверочных и тестовых изображений следующее:

 

ОБУЧЕНИЕ

ПРОВЕРКА

ТЕСТИРОВАНИЕ

ПОЖАР

87

9

10

НЕТ ПОЖАРА

90

10

11

Код

Модель основана на ResNet-18. Я создал четыре основных секции кода: вспомогательные функции, класс тренера, класс модели и класс метрик. Кроме того, я добавил код для отображения конечной матрицы ошибок и точности модели.

Импорты

import intel_extension_for_pytorch as ipeximport torchimport torch.nn as nnimport torchvision.models as modelsfrom torch.utils.data import DataLoaderfrom torchvision import datasets, models, transforms 

Создание наборов данных для обучения и валидации

Ниже мы задаем расположение изображений для тренировки и валидации и вычисляем преобразования изображений для каждого набора.

num_physical_cores = psutil.cpu_count(logical=False)data_dir = pathlib.Path("./data/output/")TRAIN_DIR = data_dir / "train"VALID_DIR = data_dir / "val"… 

Определение преобразования набора данных для тренировки и валидации

Ниже мы определяем серию преобразований, которые будут применены к каждому изображению.

…img_transforms = {    "train": transforms.Compose(        [            transforms.RandomHorizontalFlip(),            transforms.RandomVerticalFlip(),            transforms.RandomRotation(45),            transforms.ToTensor(),            transforms.Normalize(*imagenet_stats),    ),…}… 

Определение класса модели

Наша модель – это бинарный классификатор глубокой нейронной сети на основе ResNet18.

class FireFinder(nn.Module):…    def __init__(self, backbone=18, simple=True, dropout= .4):        super(FireFinder, self).__init__()        backbones = {            18: models.resnet18,        }            fc = nn.Sequential(                nn.Linear(self.network.fc.in_features, 256),                nn.ReLU(),                nn.Dropout(dropout),                nn.Linear(256, 2) 

Определение класса тренера

В этом шаге используется расширение Intel® для PyTorch*. Оно является частью Intel® AI Analytics Toolkit.

class Trainer:…        self.loss_fn = torch.nn.CrossEntropyLoss()        self.ipx = ipx        self.epochs = epochs        if isinstance(optimizer, torch.optim.Adam):            self.lr = 2e-3        self.optimizer = optimizer(self.model.parameters(), lr=lr)    def train(self):        self.model.train()        t_epoch_loss, t_epoch_acc = 0.0, 0.0        start = time.time()        for inputs, labels in tqdm(train_dataloader, desc="tr loop"):            inputs, labels = inputs.to(self.device), labels.to(self.device)            if self.ipx:                inputs = inputs.to(memory_format=torch.channels_last)            self.optimizer.zero_grad()            loss, acc = self.forward_pass(inputs, labels)            loss.backward()            self.optimizer.step()            t_epoch_loss += loss.item()            t_epoch_acc += acc.item()        return (t_epoch_loss, t_epoch_acc)…    def _to_ipx(self):        self.model.train()        self.model = self.model.to(memory_format=torch.channels_last)        self.model, self.optimizer = ipex.optimize(            self.model, optimizer=self.optimizer, dtype=torch.float32        ) 

Обучение модели

Модель обучается в течение 20 эпох, с вероятностью отсева 0,33 и скоростью обучения 0,02:

epochs = 20ipx = Truedropout = .33lr = .02torch.set_num_threads(num_physical_cores)os.environ["KMP_AFFINITY"] = "granularity=fine,compact,1,0"start = time.time()model = FireFinder(simple=simple, dropout= dropout)trainer = Trainer(model, lr = lr, epochs=epochs, ipx=ipx)tft = trainer.fine_tune(train_dataloader, valid_dataloader)

Вывод модели

Я определяю класс и функции для вывода модели.

class ImageFolderWithPaths(datasets.ImageFolder):…def infer(model, data_path: str):    transform = transforms.Compose(        [transforms.ToTensor(), transforms.Normalize(*imagenet_stats)]    )    data = ImageFolderWithPaths(data_path, transform=transform)    dataloader = DataLoader(data, batch_size=4)… 

В следующем примере кода показано, как использовать модель для оценки изображений.

images, yhats, img_paths = infer(model, data_path="./data//test/") 

Точность модели

Матрица путаницы ниже показывает, что модель имеет общую точность около 89,9% с двумя ложными отрицательными значениями из 21 примера.

Рисунок 4 показывает предсказания модели для всех примеров (обучающих, проверочных и тестовых). Пространственное покрытие показывает, что модель хорошо справилась с предсказанием площадей, указывающих на опасность возникновения пожаров или их отсутствие. Зеленые маркеры обозначают места, где модель предсказывает отсутствие пожара, а красные маркеры предсказывают примеры, где мы ожидаем возникновение пожара. Красные полигональные области представляют собой реальные пожарные зоны с 2018 по 2020 год.

Рисунок 5 увеличивает масштаб карты около Paradise, Калифорния.

Заключение

Я использовал возможности анализа изображений, предоставленные PyTorch и оптимизации от Intel, для обучения и тестирования модели ResNet18, демонстрирующей точное предсказание лесных пожаров. Модель может обрабатывать аэрофотоснимки, охватывающие 60 квадратных миль, чтобы делать точные прогнозы пожаров и их отсутствия. Текущая точность модели составляет примерно 89%, но ее можно улучшить с помощью дополнительных итераций, большего набора изображений и большего акцента на регуляризации.

Присоединяйтесь к нам на нашем Discord-сервере Intel® DevHub для дальнейшего обсуждения, нажав ссылку на приглашение. Кроме того, ознакомьтесь с новым Intel® Developer Cloud, чтобы попробовать инструментарий Intel AI Analytics на самом новом оборудовании Intel®.


Leave a Reply

Your email address will not be published. Required fields are marked *