Сосать кошек вместе с кодом! Эта статья участвует【Эссе "Мяу Звезды"】.
предисловие
В этой статье рассказывается, как использовать сеть реснет для различения изображений кошек и собак, и точность может достигать 98%. Маме больше не нужно беспокоиться о том, что я не узнаю свою кошку.
Установка фреймворка MegEngine
megEngine — это универсальная платформа для разработки моделей «глубокого обучения», которая поможет вам начать свой путь развития навыков искусственного интеллекта.
Загрузка фреймворка MegEngine может выполняться следующей командой:
pip3 install megengine -f https://megengine.org.cn/whl/mge.html
В то же время вы также можете разветвить публичный проект, чтобы узнать о модели.
Так совпало, что в этом месяце мероприятие призвано привлечь кошек к кодированию, поэтому я пришел изучить проект войны кошек и собак на MegEngine.
запись об обучении
Описание Проекта
Война кошек и собак — это метод на платформе megengine, в котором используются алгоритмы глубокого обучения, чтобы различать изображения кошек и собак.Через сеть реснет конечная точность идентификации может достигать 98%, и вы больше не боитесь распознавать кошек и собак. собаки.
подготовка данных
Набор данных набора данных Megengine
Сначала введите зависимости
from typing import Tuple
import numpy as np
from megengine.data.dataset import Dataset
import os
import cv2
Разделите 1000 изображений на обучающий и тестовый наборы в соотношении 9:1.
class CatVsDogDataset(Dataset):
def __init__(self, mode, dir):
super().__init__()
self.mode = mode
self.dir = dir
self.data_size = 0
self.data = []
self.label = []
# self.data 是数据,self.label 数据对应的标签
if self.mode == 'train':
dir = os.path.join(dir, "train")
for file in os.listdir(dir):
# 读文件
img = cv2.imread(os.path.join(dir, file))
self.data.append(img)
name = file.split(sep='.')
if name[0] == 'cat':
self.label.append(0) # the label of cat is 0
else:
self.label.append(1) # the label of dog is 1
elif self.mode == 'test':
dir = os.path.join(dir, "test")
for file in os.listdir(dir):
img = cv2.imread(os.path.join(dir, file))
self.data.append(img)
name = file.split(sep='.')
if name[0] == 'cat':
self.label.append(0) # the label of cat is 0
else:
self.label.append(1) # the label of dog is 1
else:
print('Undefined Dataset!')
self.data = np.array(self.data)
self.label = np.array(self.label)
print(self.data.shape)
print(self.label.shape)
# 定义获取数据集中每个样本的方法
def __getitem__(self, index: int) -> Tuple:
return self.data[index], self.label[index]
# 定义返回数据集长度的方法
def __len__(self) -> int:
return len(self.data)
Проверьте разделенные данные:
import os
print("训练数据集总数:",len(os.listdir("./dataset/CatVsDog/train")))
print("测试数据集总数:",len(os.listdir("./dataset/CatVsDog/test")))
train_dataset = CatVsDogDataset("train", "./dataset/CatVsDog")
test_dataset = CatVsDogDataset("test", "./dataset/CatVsDog")
Указывает, что работа по подготовке данных была выполнена
Создайте сетевую структуру реснета
Что такое структура сети реснет
Слой данных, выводимых из переднего ряда нескольких слоев, напрямую пропускает несколько слоев, введенных во входную часть заднего слоя данных. Это означает, что содержимое слоев векторного слоя будет частично добавлено определенным слоем фронта.
Исходя из опыта, глубина сети имеет решающее значение для производительности модели.Когда количество сетевых слоев увеличивается, сеть может извлекать более сложные шаблоны признаков, поэтому теоретически лучшие результаты могут быть достигнуты, когда модель глубже. Однако, когда количество сетевых слоев увеличивается, возникает проблема глубокой деградации сети, которая создала огромное препятствие для развития глубоких сетей.
Алгоритм ResNet, предложенный доктором Хе, решает проблему сложности обучения модели CNN.В 2014 году у VGC было всего 19 слоев, а в 2015 году — целых 152 слоя, что также подтвердило превосходство ResNet.
Основной код конструкции ссылается на методы megengine.functional и module.
Реализация этого алгоритма непроста, если он написан на чистом нативном питоне, за подробностями обращайтесь к публичному проекту Megengine.
Megengine официально предоставляет обученную модель, мы можем напрямую обратиться к ней, мы напрямую загружаем модель, текущая модель обучена, и нет необходимости обучать снова.
os.system("wget https://data.megengine.org.cn/models/weights/resnet18_naiveaug_70312_78a63ca6.pkl")
Конечно, модель также можно продолжать обучать.
обучение модели
def model_train():
import megengine as mge
smallnet = resnet18()
# 可选
state_dict = mge.load('resnet18_naiveaug_70312_78a63ca6.pkl')
smallnet.load_state_dict(state_dict)
batch_size = 16
sampler = RandomSampler(dataset=train_dataset, batch_size=batch_size, drop_last=True)
from megengine.data import transform
transform = transform.Compose([
transform.RandomResizedCrop(224),
transform.RandomHorizontalFlip(),
transform.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),
transform.Lighting(0.1),
transform.Normalize(
mean=[103.530, 116.280, 123.675], std=[57.375, 57.120, 58.395]
),
transform.ToMode("CHW"),
])
train_dataloader = DataLoader(
train_dataset,
sampler=sampler,
transform=transform,
)
# 定义静态图训练函数
@trace(symbolic=True)
def train_func(data, label, *, net, optimizer):
net.train() # 网络设置成训练模式
pred = net(data)
# 使用交叉熵损失
loss = F.cross_entropy_with_softmax(pred, label)
optimizer.backward(loss)
return pred, loss
# 定义优化器
opt = optim.SGD(smallnet.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-4)
# 模型训练
import megengine as mge
import numpy as np
# set trace.enabled=False if you want to run eager mode
# trace.enabled = False
# 训练迭代,优化器更新参数
# 这里为了方便演示,只迭代 10 个 epochs 。
# 实际训练可以设成 200 个 epochs ,在第 100 和第 150 个 epoch 位置将 lr 分别降至 0.01 和 0.001 。
epochs = 100
data_tensor = mge.tensor(dtype=np.float32)
label_tensor = mge.tensor(dtype=np.int32)
losses = []
for i in range(epochs):
print(".")
loss_rec = []
for data, label in train_dataloader:
"""
# 验证数据的正确性
img = np.array(data[0])
img = np.transpose(img,[1,2,0])
print(img.shape)
cv2.imshow("img", img)
cv2.waitKey(0)
"""
data_tensor.set_value(data)
label_tensor.set_value(label.astype("int32"))
opt.zero_grad()
# pred = smallnet(data)
# print(pred.shape)
# exit()
_, loss = train_func(data_tensor, label_tensor, net=smallnet, optimizer=opt)
opt.step()
loss_rec.append(loss.numpy().item())
loss = sum(loss_rec) / len(loss_rec)
losses.append(loss)
print("[Epoch {}] loss: {}".format(i, loss))
"""
损失可视化
模型保存
"""
import matplotlib.pyplot as plt
plt.plot(range(len(losses)), losses, color='red')
plt.xlabel("iterator")
plt.ylabel('loss')
plt.show()
# 模型保存
mge.save(smallnet.state_dict(), 'resnet18_static_100.mge')
Прости Xiaobai, часть обучения модели не до конца понятна.
Тестирование модели
Если вы используете модель, предоставленную megengine, вам не нужно писать отдельную тестовую функцию, в противном случае вам нужно написать сложную тестовую функцию, такую как обучение, здесь вы можете показать силу презрения.
def model_test():
"""
模型的加载与测试
:return:
"""
smallnet = resnet18()
import megengine as mge
state_dict = mge.load('resnet18_static_100.mge')
smallnet.load_state_dict(state_dict)
# 创建 DataLoader 用于测试
from megengine.data import transform
batch_size = 1
sampler_test = SequentialSampler(dataset=test_dataset, batch_size=batch_size)
transform_test = transform.Compose([
transform.Resize(256),
transform.CenterCrop(224),
transform.Normalize(
mean=[103.530, 116.280, 123.675], std=[57.375, 57.120, 58.395]
), # BGR
transform.ToMode("CHW"),
])
test_dataloader = DataLoader(
test_dataset,
sampler=sampler_test,
transform=transform_test,
)
# 定义静态图测试函数,进行模型的测试
@trace(symbolic=True)
def eval_func(data, label, *, net):
net.eval() # 网络设置为测试模式
pred = net(data)
loss = F.cross_entropy_with_softmax(pred, label)
return pred, loss
data_tensor = mge.tensor()
label_tensor = mge.tensor(dtype=np.int32)
correct = 0
total = 0
for data, label in test_dataloader:
label = label.astype("int32")
pred, _ = eval_func(data, label, net=smallnet)
pred_label = F.argmax(pred, axis=1)
# if(pred_label.numpy()[0]!=label[0]):
# img = np.array(data[0])
# img = np.transpose(img, [1, 2, 0])
# print(img.shape)
# cv2.imshow("img", img)
# cv2.waitKey(0)
correct += (pred_label == label).sum().numpy().item()
total += label.shape[0]
print("correct: {}, total: {}, accuracy: {:.2f}%".format(correct, total, correct * 100.0 / total))
Меры предосторожности
- Модель, предоставляемая MegStudio, представляет собой 1000 классификаций в сети изображений, которые можно улучшить, чтобы разделить на 2 классификации и загрузить предварительно обученную модель.
- Скорость обучения MegStudio немного медленная, рекомендуется скопировать код на локальный компьютер для обучения.
Спасибо
- Ссылка на ссылку:Мегенгинская драка кота и собаки,MegStudio
- Спасибо моему маленькому другу Battlefield Packet за приглашение, опубликуйте егоЭтодомашняя страница (Талант /user/442409…)