Ставьте лайк и смотрите снова, выработайте привычку, найдите [JackCui-AI] в общедоступной учетной записи WeChat и подпишитесь на этого программиста, который любит создавать технические галантереи. Эта статьяGitHubGitHub.com/Джек-Чери — это…Включено, и есть полные тестовые площадки, материалы и мой цикл статей для интервью с производителями первой линии.
Введение
Обещанная серия руководств по иллюстративным алгоритмам ИИ уже здесь!
В последнее время я написал много интересных туториалов по алгоритмам ИИ, и на данный момент я написал 14, среди которых есть учебники с хорошим откликом:
- Твои красные туфли на высоких каблуках — первый опыт применения технологии искусственного интеллекта для изменения лица.
- Заставь картинку двигаться, Трамп и Мона Лиза ласково поют «Unravel»
- Удивительные алгоритмы для искусства
- Алгоритм реставрации фотографий вековой давности, эти дорогие родители!
- Алгоритм создания портретного рисунка "Идеальная перегравировка" U^2-Net
Читатели прекрасно провели время и интересовались алгоритмами ИИ и глубоким обучением.
Но это ограничивается счастливым бегом с сумками, что в лучшем случае можно рассматривать только как «упаковщика».
Теперь, когда вам интересно, почему бы не ковать железо, пока горячо, получить больше базовых знаний и стремиться как можно скорее вступить в ряды «Героев-наставников».
Давайте все вместе займемся алхимией и попрактикуемся.
Учебники серии графических алгоритмов ИИ включают не только базовые знания глубокого обучения, но и обучения с подкреплением, обучения переносу и т. д., а также, кроме того, такие как разборка алгоритмов обнаружения целей, состязательных нейронных сетей (GAN) и т. д.
Если вам понравилась эта серия туториалов по алгоритму ИИ, обязательно дайте мне знать, пересылка — это поддержка, а больше текстов — больше мотивации!
Сложность будет постепенно увеличиваться.Сегодня давайте сначала разомнемся, давайте расслабимся и используем это как начало этой серии.
2. Глубокое обучение
глубокое обучение(Глубокое обучение) — это область исследований, которая быстро развивается в последние годы.искусственный интеллектМногие подполя . С самого начала глубокое обучение является ответвлением машинного обучения.
Глубокое обучение происходит отограниченная выборкаОбщие правила суммируются с помощью алгоритмов и могут быть применены к новымНеизвестные данныеначальство.
Например, мы можем подытожить какой-нибудь сборник исторических случаевсимптомиболезньмежду правилами. Таким образом, когда есть новый пациент, мы можем использовать суммированное правило, чтобы определить, какое заболевание у пациента.
Какие базовые знания вам нужно освоить, если вы хотите научиться глубокому обучению?прямо над:
Организовал карту разума давно,Рекомендуемая коллекция!
Глубокое обучение в основном состоит из нескольких частей, как показано на рисунке выше.Если вы хотите изучить принцип алгоритма глубокого обучения, это зависит от того, какая у него структура сети, как вычисляются потери и как выполняются предварительная и постобработка. Выполнено.
Существует так много стратегий инициализации веса и настройки скорости обучения, алгоритмов оптимизации и сред глубокого обучения, и не все из них нужно освоить.Например, среды глубокого обучения, Pytorch может обрабатывать большинство сценариев.
Сначала имейте общее познание, а затем следуйте этой карте ума, изучайте точки знания одну за другой и, наконец, объединяйте их вместе, вы обнаружите, что:Вы также можете реализовать свои собственные алгоритмы для различных функций..
Основная цель глубокого обучения состоит в том, чтобы автоматически учиться на данных, чтобы эффективноПредставление функций, как это работает? Начать нужно с нейронов.
С развитием нейронауки и когнитивной науки мы постепенно узнаем, что интеллектуальное поведение человека связано с активностью мозга.
нервная система головного мозга человекапредставляет собой очень сложную ткань, содержащую почти 86 миллиардов нейронов, которые составляютсупер огромная нейронная сеть.
Мы знаем, что интеллект человека определяется не всецело наследственностью, а большей частью жизненным опытом. Другими словами, нейронная сеть человеческого мозга представляет собой систему со способностью к обучению.
Синапсы между разными нейронами бывают сильными или слабыми, и их сила может непрерывно изменяться в процессе обучения (тренировки) с определенной степенью пластичности, и разные связи образуют разные отпечатки памяти.
Нейронная сеть глубокого обучения — это вычислительная модель, вдохновленная нейронной сетью человеческого мозга, которая имитирует нейронную сеть человеческого мозга с точки зрения структуры, механизма реализации и функции.
Например, на следующем рисунке показана простейшая нейронная сеть с прямой связью, а 0-й слой называетсявходной слой, последний слой называетсявыходной слой, остальные промежуточные слои называютсяскрытый слой.
Как работает нейронная сеть? Как работает сетевая иерархия, функция потерь, алгоритм оптимизации, инициализация веса, настройка скорости обучения?
Обратное распространение дает вам ответ. фронт,Предупреждение о высокой энергии!
3. Обратное распространение
Чтобы понять принципы глубокого обучения, вы должныобратное распространениеи правило вывода цепи.
Давайте сначала поговорим о ментальной картесетевая иерархия, нейронная сеть, которая может быть сложной или простой.Для удобства вывода предположим, что у вас есть такой слой сети:
Первый слойвходной слой, содержащий два нейрона i1, i2 и точку пересечения b1 (смещение);
Второй слойскрытый слой, содержащий два нейрона h1, h2 и точку пересечения b2;
Третий слойвыходной слойo1 и o2, wi, отмеченный в каждой строке, представляет собой вес связи между слоями, а функция активации по умолчанию является сигмовидной функцией.
Перед обучением этой сети эти веса wi должны быть инициализированы, чтоИнициализация веса, способов инициализации тут много, выбираем самый простой,случайная инициализация.
Результат случайной инициализации, как показано на следующем рисунке:
Среди них исходные данные: i1=0,05, i2=0,10;
Выходные данные (желаемый результат): o1=0,01, o2=0,99;
Начальные веса: w1=0,15, w2=0,20, w3=0,25, w4=0,30, w5=0,40, w6=0,45, w7=0,50, w8=0,55.
Цель: Имея входные данные i1, i2 (0,05 и 0,10), сделайте вывод как можно ближе к исходному выводу o1, o2 (0,01 и 0,99).
Рабочий процесс нейронной сети делится на два этапа:прямое распространениеиобратное распространение.
1. Прямое распространение
Прямое распространение заключается в вычислении входных данных для выходного слоя в соответствии с весами.
1) Входной слой -> скрытый слой
Вычислите взвешенную сумму входов в нейрон h1:
После нейрона следуйтеслой активации, тем самым вводя нелинейные факторы, которые подобны человеческим нейронам, позволяя клеткам находиться ввзволнованныйилиторможениестатус.
Форма математического моделирования черезфункция активации, если он больше порога, он будет активирован, иначе будет заблокирован.
Часто используемые функции активации, такие каккарта разумаКак показано, в качестве примера приведена очень простая сигмовидная функция активации, форма ее функции выглядит следующим образом:
Математическая формула:
Используя сигмовидную функцию активации, продолжим расчет, вывод нейрона h1 o_h1:
Точно так же можно рассчитать выход o_h2 нейрона h2:
2) Скрытый слой -> выходной слой
Рассчитаем значения нейронов выходного слоя o1 и o2:
Таким образом, процесс прямого распространения завершен.По входному значению и весу мы получаем выходное значение [0,75136079, 0,772928465], которое далеко от фактического значения (целевого) [0,01, 0,99].Теперь делаем обратное Распространение ошибки, обновление весов, пересчет вывода.
2. Обратное распространение
После прямого распространения обнаруживается, что выходной результат далек от ожидаемого.В это время необходимообновить веса.
Так называемое обучение глубокому обучению (алхимия) изучает эти веса, и мы ожидаем отрегулировать эти веса так, чтобы выходные результаты соответствовали нашим ожиданиям.
Способ обновления весов основан на обратном распространении.
1) Рассчитать общую ошибку
После прямого распространения возникает разрыв между выходным значением (прогнозируемое значение) и целевым значением (значение метки), поэтому необходимо измерить, насколько велик этот разрыв.
Метод измерения заключается в использованиикарта разумафункция потерь в .
Функций потерь тоже много, мы все равно выбираем самую простую, среднеквадратичную ошибку (MSE loss).
Формула функции среднеквадратичной ошибки:
По формуле непосредственно рассчитайте общую ошибку между прогнозируемым значением и значением метки:
Есть два выхода, поэтому ошибки для o1 и o2 рассчитываются отдельно, а общая ошибка представляет собой сумму двух:
2) Скрытый слой -> обновление веса выходного слоя
Взяв в качестве примера весовой параметр w5, если мы хотим узнать, какое влияние w5 оказывает на общую ошибку, мы можем использовать общую ошибку для частичного получения w5.
Это цепное правило, которое является правилом вывода составных функций в исчислении, и вот оно:
По цепному правилу легко получить:
Следующий рисунок может быть более интуитивным, чтобы увидеть, как ошибка распространяется обратно:
Теперь посчитаем значение каждой формулы отдельно:
рассчитать:
рассчитать:
Этот шаг фактически является выводом сигмовидной функции, которая относительно проста и может быть получена самостоятельно.
рассчитать:
Умножьте последние три:
Таким образом, мы вычисляем частную производную общей ошибки E(total) по w5.
Возвращаясь к приведенной выше формуле, мы находим:
Для удобства выражения используйтедля представления ошибки выходного слоя:
Следовательно, формула частной производной общей ошибки E(total) для w5 может быть записана как:
Если ошибка выходного слоя считается отрицательной, ее также можно записать как:
Наконец, мы обновляем значение w5: входной слой
Стратегия обновления весовкарта разумасерединаоптимизация,скорость обучения, здесь мы берем 0,5.
Если скорость обучения должна быть скорректирована в соответствии с количеством итераций, используйтекарта разумасерединаРегулировка скорости обучения.
Точно так же можно обновить w6,w7,w8:
3) Скрытый слой -> обновление веса скрытого слоя
Метод на самом деле похож на описанный выше, но есть одно место, которое необходимо изменить.При расчете частной производной полной ошибки для w5 выше, это из out(o1)->net(o1)->w5, но в скрытом слое. Когда веса между ними обновляются, это out(h1)->net(h1)->w1, а out(h1) примет ошибку от E(o1) и E(o2), так что это место Оба должны быть рассчитаны.
рассчитать:
Рассчитать сначала:
Аналогично рассчитать:
Сложите два вместе, чтобы получить общее значение:
пересчитывать:
пересчитывать:
Наконец, умножьте три вместе:
Чтобы упростить формулу, используйте sigma(h1) для обозначения ошибки единицы скрытого слоя h1:
Наконец, обновите веса w1:
Таким же образом можно обновить веса w2, w3 и w4:
Таким образом, метод обратного распространения ошибки завершен, и, наконец, мы пересчитываем обновленные веса и непрерывно итерируем.
После первой итерации в этом примере общая ошибка E(total) падает с 0,298371109 до 0,291027924.
После 10 000 итераций общая ошибка составляет 0,000035085, а результат — [0,015912196, 0,984065734] (исходный ввод — [0,01, 0,99]), что доказывает, что эффект по-прежнему хорош.
Так работает вся нейросеть, если следовать за идеей, то здесь можно увидеть успешно. Тогда поздравляем, вы прошли уровень глубокого обучения.
В-четвертых, реализация Python
Весь процесс может быть реализован с помощью кода Python.
#coding:utf-8
import random
import math
#
# 参数解释:
# "pd_" :偏导的前缀
# "d_" :导数的前缀
# "w_ho" :隐含层到输出层的权重系数索引
# "w_ih" :输入层到隐含层的权重系数的索引
class NeuralNetwork:
LEARNING_RATE = 0.5
def __init__(self, num_inputs, num_hidden, num_outputs, hidden_layer_weights = None, hidden_layer_bias = None, output_layer_weights = None, output_layer_bias = None):
self.num_inputs = num_inputs
self.hidden_layer = NeuronLayer(num_hidden, hidden_layer_bias)
self.output_layer = NeuronLayer(num_outputs, output_layer_bias)
self.init_weights_from_inputs_to_hidden_layer_neurons(hidden_layer_weights)
self.init_weights_from_hidden_layer_neurons_to_output_layer_neurons(output_layer_weights)
def init_weights_from_inputs_to_hidden_layer_neurons(self, hidden_layer_weights):
weight_num = 0
for h in range(len(self.hidden_layer.neurons)):
for i in range(self.num_inputs):
if not hidden_layer_weights:
self.hidden_layer.neurons[h].weights.append(random.random())
else:
self.hidden_layer.neurons[h].weights.append(hidden_layer_weights[weight_num])
weight_num += 1
def init_weights_from_hidden_layer_neurons_to_output_layer_neurons(self, output_layer_weights):
weight_num = 0
for o in range(len(self.output_layer.neurons)):
for h in range(len(self.hidden_layer.neurons)):
if not output_layer_weights:
self.output_layer.neurons[o].weights.append(random.random())
else:
self.output_layer.neurons[o].weights.append(output_layer_weights[weight_num])
weight_num += 1
def inspect(self):
print('------')
print('* Inputs: {}'.format(self.num_inputs))
print('------')
print('Hidden Layer')
self.hidden_layer.inspect()
print('------')
print('* Output Layer')
self.output_layer.inspect()
print('------')
def feed_forward(self, inputs):
hidden_layer_outputs = self.hidden_layer.feed_forward(inputs)
return self.output_layer.feed_forward(hidden_layer_outputs)
def train(self, training_inputs, training_outputs):
self.feed_forward(training_inputs)
# 1. 输出神经元的值
pd_errors_wrt_output_neuron_total_net_input = [0] * len(self.output_layer.neurons)
for o in range(len(self.output_layer.neurons)):
# ∂E/∂zⱼ
pd_errors_wrt_output_neuron_total_net_input[o] = self.output_layer.neurons[o].calculate_pd_error_wrt_total_net_input(training_outputs[o])
# 2. 隐含层神经元的值
pd_errors_wrt_hidden_neuron_total_net_input = [0] * len(self.hidden_layer.neurons)
for h in range(len(self.hidden_layer.neurons)):
# dE/dyⱼ = Σ ∂E/∂zⱼ * ∂z/∂yⱼ = Σ ∂E/∂zⱼ * wᵢⱼ
d_error_wrt_hidden_neuron_output = 0
for o in range(len(self.output_layer.neurons)):
d_error_wrt_hidden_neuron_output += pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].weights[h]
# ∂E/∂zⱼ = dE/dyⱼ * ∂zⱼ/∂
pd_errors_wrt_hidden_neuron_total_net_input[h] = d_error_wrt_hidden_neuron_output * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_input()
# 3. 更新输出层权重系数
for o in range(len(self.output_layer.neurons)):
for w_ho in range(len(self.output_layer.neurons[o].weights)):
# ∂Eⱼ/∂wᵢⱼ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢⱼ
pd_error_wrt_weight = pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].calculate_pd_total_net_input_wrt_weight(w_ho)
# Δw = α * ∂Eⱼ/∂wᵢ
self.output_layer.neurons[o].weights[w_ho] -= self.LEARNING_RATE * pd_error_wrt_weight
# 4. 更新隐含层的权重系数
for h in range(len(self.hidden_layer.neurons)):
for w_ih in range(len(self.hidden_layer.neurons[h].weights)):
# ∂Eⱼ/∂wᵢ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢ
pd_error_wrt_weight = pd_errors_wrt_hidden_neuron_total_net_input[h] * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_weight(w_ih)
# Δw = α * ∂Eⱼ/∂wᵢ
self.hidden_layer.neurons[h].weights[w_ih] -= self.LEARNING_RATE * pd_error_wrt_weight
def calculate_total_error(self, training_sets):
total_error = 0
for t in range(len(training_sets)):
training_inputs, training_outputs = training_sets[t]
self.feed_forward(training_inputs)
for o in range(len(training_outputs)):
total_error += self.output_layer.neurons[o].calculate_error(training_outputs[o])
return total_error
class NeuronLayer:
def __init__(self, num_neurons, bias):
# 同一层的神经元共享一个截距项b
self.bias = bias if bias else random.random()
self.neurons = []
for i in range(num_neurons):
self.neurons.append(Neuron(self.bias))
def inspect(self):
print('Neurons:', len(self.neurons))
for n in range(len(self.neurons)):
print(' Neuron', n)
for w in range(len(self.neurons[n].weights)):
print(' Weight:', self.neurons[n].weights[w])
print(' Bias:', self.bias)
def feed_forward(self, inputs):
outputs = []
for neuron in self.neurons:
outputs.append(neuron.calculate_output(inputs))
return outputs
def get_outputs(self):
outputs = []
for neuron in self.neurons:
outputs.append(neuron.output)
return outputs
class Neuron:
def __init__(self, bias):
self.bias = bias
self.weights = []
def calculate_output(self, inputs):
self.inputs = inputs
self.output = self.squash(self.calculate_total_net_input())
return self.output
def calculate_total_net_input(self):
total = 0
for i in range(len(self.inputs)):
total += self.inputs[i] * self.weights[i]
return total + self.bias
# 激活函数sigmoid
def squash(self, total_net_input):
return 1 / (1 + math.exp(-total_net_input))
def calculate_pd_error_wrt_total_net_input(self, target_output):
return self.calculate_pd_error_wrt_output(target_output) * self.calculate_pd_total_net_input_wrt_input();
# 每一个神经元的误差是由平方差公式计算的
def calculate_error(self, target_output):
return 0.5 * (target_output - self.output) ** 2
def calculate_pd_error_wrt_output(self, target_output):
return -(target_output - self.output)
def calculate_pd_total_net_input_wrt_input(self):
return self.output * (1 - self.output)
def calculate_pd_total_net_input_wrt_weight(self, index):
return self.inputs[index]
# 文中的例子:
nn = NeuralNetwork(2, 2, 2, hidden_layer_weights=[0.15, 0.2, 0.25, 0.3], hidden_layer_bias=0.35, output_layer_weights=[0.4, 0.45, 0.5, 0.55], output_layer_bias=0.6)
for i in range(10000):
nn.train([0.05, 0.1], [0.01, 0.09])
print(i, round(nn.calculate_total_error([[[0.05, 0.1], [0.01, 0.09]]]), 9))
#另外一个例子,可以把上面的例子注释掉再运行一下:
# training_sets = [
# [[0, 0], [0]],
# [[0, 1], [1]],
# [[1, 0], [1]],
# [[1, 1], [0]]
# ]
# nn = NeuralNetwork(len(training_sets[0][0]), 5, len(training_sets[0][1]))
# for i in range(10000):
# training_inputs, training_outputs = random.choice(training_sets)
# nn.train(training_inputs, training_outputs)
# print(i, nn.calculate_total_error(training_sets))
5. Другие
Предобработка и постобработка относительно просты, а предобработка — это некоторые обычные операции преобразования изображения, методы улучшения данных и т. д. Постобработка немного отличается для каждой задачи, например, не максимальное подавление для обнаружения объектов и т. д., что можно обсудить позже.
Что касается изучения фреймворков глубокого обучения, это еще одна большая часть контента.Фреймворки глубокого обучения представляют собой сумму ресурсов, таких как инструменты, библиотеки и предварительно обученные модели для разработки глубокого обучения. Мы можем использовать Python для реализации простых нейронных сетей, но сложные нейронные сети зависят от фреймворков, использование фреймворков может значительно снизить наши затраты на разработку.
Что касается того, какой фреймворк изучать, это зависит от личных предпочтений, и Pytorch, и Tensorflow подходят. Жизнь слишком коротка, я выбираю Pytorch.
6. Рекомендуемые учебные материалы
После прочтения этой статьи ее можно рассматривать только как введение в глубокое обучение, и в ней еще много материала для углубленного изучения.
Некоторые материалы рекомендованы для удобства заинтересованных читателей для продолжения своего исследования.
видео:
книги:
- «Нейронные сети и глубокое обучение»
- «Глубокое обучение PyTorch на практике»
Проект с открытым исходным кодом:
- Учебник Pytorch 1:GitHub.com/Yunjin Malicious/py для…
- Учебник по Pytorch 2:GitHub.com/py факел/тотем…
Видео и книги, публичный аккаунт "JackCui-AI"За кулисамиОтветить"666"Есть сюрприз!
Семь, болтовня
Накопление знаний - долгий и одинокий процесс. Накопление может привести к истончению волос. Если у вас есть знания, которых вы не понимаете, вам нужно больше читать и думать. Вы должны верить, что в конце концов победит тот, кто кто упорствует.
Эта статья хардкорная, если она вам понравилась, я надеюсь переслать ее и увидеть большую поддержку.
Я Джек, увидимся в следующий раз.
Статья постоянно обновляется, вы можете найти [JackCui-AI] в общедоступной учетной записи WeChat, чтобы прочитать ее впервые, эта статья GitHubGitHub.com/Джек-Чери — это…Он был включен, и есть полные тестовые сайты для интервью с крупными заводами.Добро пожаловать в Star.