В последнее время это вдруг появилось, и мне вдруг захотелось изучить очень популярное в последнее время глубокое обучение (запыхавшись). Тем не менее, как инженер-программист, основной целью этого исследования является не исследование алгоритма, а основная цель — иметь возможность использовать его в разработке, поэтому некоторые детали и математические принципы не будут изучаться и анализироваться в этой статье.
В этой статье в основном используется типичный сценарий применения глубокого обучения — классификация изображений в качестве отправной точки для объяснения.
Введение
Как мы все знаем, прямая линия может разделить плоскость на две половины. Предполагая известную прямую линиюax + by + c = 0
, дайте вам еще один балл(x1, y1)
, то я полагаю, что каждый может легко определить, к какой стороне линии принадлежит эта точка.
Итак, теперь давайте трансформируем задачу.Дайте вам кучу точек и скажите, к какой стороне линии принадлежат эти точки.Теперь вам нужно найти линию?
Этот вопрос очень интересен, боюсь, сложно сразу придумать, как его решить. Общая проблема в том,公式 + 参数 => 答案
, проблема наоборот, становится参数 + 答案 => 公式
. Эту задачу на самом деле можно назвать упрощенной версией принципа глубокого обучения.
распознавание почерка
Приведенный выше пример может показаться вам немного запутанным. Что, это глубокое обучение, почему я ничего не понимаю? Не волнуйтесь, не торопитесь, приведу еще один более наглядный пример — распознавание рукописного ввода.
Как показано на рисунке выше, одно из наших изображений состоит из n пикселей. Для простоты мы рассматриваем только идентификацию 10 чисел от 0 до 9 и просто думаем, что белые пиксели равны 1, а черные пиксели равны 0.
Размышляя над простейшей идеей, мы думаем, что каждый пиксель имеет свой вес, и, наконец, складываются веса всех белых пикселей, и мы можем определить, какому числу он соответствует.
Тогда мы можем написать 10 уравнений для конечного результата распознавания 0 ~ 9.
Тогда для каждого рукописного изображения мы знаеми , конечная цель – найти все коэффициенты. Можно видеть, что эта задача и задача прямой линии, приведенная выше, принимают одинаковую форму. который已知参数和结果求系数
.
ps: На самом деле, приведенные выше 10 уравнений преобразованы в форму графа, который является классической сетевой моделью в глубоком обучении — полносвязной сетью. Как показано ниже:
резюме
Из приведенного выше введения я думаю, что каждый может легко представить себе основной процесс глубокого обучения:
1. 构建公式(构建网络)
2. 使用训练集求出每个公式的系数
3. 使用测试集测试这些系数的准确率
Но для решения коэффициентов используются такие алгоритмы, как градиентный спуск и обратное распространение. В этой статье подробно не объясняется, вы можете самостоятельно использовать Baidu. В этой статье используется готовый интерфейс, предоставленный непосредственно в pytorch.
Фреймворк AI — использование pytorch
Чтобы быстро приступить к работе, о выборе языка мы, очевидно, выбираем python, а для фреймворка AI мы выбираем основной фреймворк pytorch. В pytorch наш процесс обучения сети в основном выглядит следующим образом:
- Получить данные (тренировочный набор и тестовый набор)
- Создайте сеть
- Используйте тренировочный набор для обучения (найдите коэффициенты)
- Тест с тестовым набором
Установить
официальный сайт питорчСуществуют команды установки, которые здесь подробно объясняться не будут. Конечно, при установке нужно обратить внимание на выбор версий CPU и GPU (CUDA).
получить данные
В области ИИ существует множество общедоступных наборов данных, таких как MNIST — рукописные цифры, CIFAR10 и CIFAR100 — распознавание изображений, ImageNet — распознавание изображений и т. д. Pytorch предоставляет готовые API для загрузки этих общедоступных наборов данных (конечно, pytorch также поддерживает пользовательские наборы данных). Для простоты возьмем в качестве примера CIFAR 10. CIFAR 10 имеет в общей сложности 10 категорий изображений, а именно самолеты, автомобили, птицы, кошки, олени, собаки, лягушки, лошади, лодки и грузовики.
Далее идет код для pytorch для загрузки данных
import torchvision
import torchvision.transforms as transforms
BATCH_SIZE = 8 # BATCH_SIZE此处为了快速执行,就设定得小一点
# 定义图片转换规则
transform_rule = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
# 加载训练集
train_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_rule)
train_loader = DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True, num_workers=2, drop_last=True)
# 加载测试集
test_set = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_rule)
test_loader = DataLoader(test_set, batch_size=BATCH_SIZE, shuffle=True, num_workers=2, drop_last=True)
Вы можете видеть, что pytorch напрямую предоставляет метод torchvision.datasets.CIFAR10 для загрузки и загрузки набора данных CIFAR10.
Затем мы смотрим на выше, есть правило преобразования изображения. Для pytorch вся обработка основана на количественном типе тензора (tensor), который можно просто понимать как многомерный массив, который может работать на GPU. Затем, если мы хотим обучить данные, мы должны сначала загрузить изображение и преобразовать его в тензорный формат, поэтому нам нужно вызватьToSensor()
метод. СледующееNormalize()
Он нормализован и используется для предварительной обработки данных, но здесь игнорируется.
За ним стоит DataLoader для загрузки данных (ps: в обычных условиях мы не будем закладывать все данные обучающей выборки в нейросеть для обучения за один раз, а будем тренировать пачками, ведь объем данных Большой машины с этим не справляются).
Создайте сеть
Теперь, когда у нас есть данные, нам нужно построить сеть.В pytorch для построения сети нам нужно только наследоватьtorch.nn.Module
и реализоватьforward()
метод. следующее:
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.model = nn.Sequential(
nn.Linear(3072, 10),
)
def forward(self, x):
x = x.view(BATCH_SIZE, -1)
x = self.model(x)
return x
прежде всегоx = x.view(BATCH_SIZE, -1)
Он используется для сведения изображения к одному измерению, потому что сеть, которую мы здесь используем, является полносвязной сетью, а вход и выход одномерными.
Далее мы определяем однослойную полносвязную сеть,nn.Linear(x, y)
Он представляет полностью связанный слой, x представляет количество входов, а y представляет количество выходов.
Точно так же мы можем увеличить количество слоев следующим образом:
self.model = nn.Sequential(
nn.Linear(3072, 1024),
nn.Linear(1024, 10),
)
Таким образом, мы построили простую нейронную сеть.
обучающий набор данных
Далее идет код для обучающего набора данных.
# 用来设置执行设备,cpu/gpu
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = Net().to(device)
criterion = nn.CrossEntropyLoss().to(device) # 定义损失函数,此处使用CrossEntropyLoss,其他算法请自行搜索
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) # 定义优化器,此处使用SGD,其他算法请自行搜索
for epoch in range(10): # 训练10轮
for i, data in enumerate(train_loader, 0):
inputs, labels = data # input表示图片,label表示图片的分类
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad() # 重置网络梯度
outputs = net(inputs) # 用训练数据执行网络
loss = criterion(outputs, labels) # 计算结算偏差
loss.backward() # 反向传播计算梯度
optimizer.step() # 根据梯度调整系数
Этот код является кодом шаблона для выполнения обучения сети.Сначала верните градиент к 0, затем выполните сеть, затем выполните обратное распространение для расчета градиента и, наконец, отрегулируйте коэффициенты. Что касается конкретных функций и принципов работы каждого алгоритма, то эта статья не будет подробно объяснять.
Всего несколько строк кода, и обучение завершено.
тестовый набор данных
Наконец, мы берем обученную модель и проверяем точность модели.
correct = 0
total = 0
with torch.no_grad(): # 测试时不再需要计算梯度了,防止性能浪费
for data in test_loader:
images, labels = data
images, labels = images.to(device), labels.to(device)
outputs = net(images) # 调用已训练好的模型识别测试图片
_, predicted = torch.max(outputs.data, 1) # 网络最终会输出10个分类对应的概率,取概率最高的
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))
По сути, это тоже шаблонный код, поэтому подробно его объяснять не буду.
резюме
Из приведенного выше кода мы можем в основном понять, как устроена нейронная сеть, а также процесс ее обучения и тестирования. Конечно, есть еще много понятий, которые не были упомянуты, например, в дополнение к полносвязному слою, сетевой уровень может также иметь слой свертки, слой активации и так далее. Для получения дополнительной информации вы можете перейти на станцию B, чтобы найти соответствующие учебные пособия и выполнить поиск по ключевым словам — введение в pytorch.
Простое инженерное приложение
С точки зрения инженера-программиста очевидно, что нам не нужно самостоятельно отлаживать сетевую модель, наша цель — напрямую вызвать существующую сетевую модель для производства. Этот pytorch также предоставляет множество известных сетевых моделей, таких как VGG, GoogLeNet, ResNet и т. д. В этой статье в качестве примера используется ResNet (остаточная сеть), достаточно одной строки кода:
resnet = torchvision.models.resnet152(pretrained=True, progress=True)
Затем мы на самом деле вызовем эту сеть, чтобы распознать изображение,
import torch
import torchvision.models
from PIL import Image
from torchvision import transforms
# ResNet是基于ImageNet数据集的,此处imagenet_classes.txt存的是ImageNet的标签,见https://blog.csdn.net/LegenDavid/article/details/73335578
with open('./imagenet_classes.txt') as f:
labels = [line.strip() for line in f.readlines()]
# 读取图片 & 预处理 (这里面的各种转换参数也是网上找的,没太细究)
image = Image.open('./img.png').convert('RGB')
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
image_preprocessed = preprocess(image)
batch_image_preprocessed = torch.unsqueeze(image_preprocessed, 0)
# 执行网络,并输出结果
resnet = torchvision.models.resnet152(pretrained=True, progress=True)
resnet.eval()
out = resnet(batch_image_preprocessed)
_, index = torch.max(out, 1)
print(labels[index])
Как видите, настоящий вызов на самом деле очень прост, т.е.out = resnet(batch_image_preprocessed)
. Если вы хотите применить его в продакшене, есть много способов, самый простой из которых — наслоить веб-фреймворк, такой как Django, снаружи.
Ссылаться на
[1] Краткое руководство по глубокому обучению PyTorch
[2] PyTorch — как загружать и прогнозировать с помощью модели Resnet