Что такое нейронная сеть?
Нейронные сети, также известные как искусственные нейронные сети (ИНС), представляют собой тип машинного обучения, лежащий в основе алгоритмов глубокого обучения. Их название и форма вдохновлены человеческим мозгом, и они повторяют способ взаимодействия биологических нейронов друг с другом. Чтобы учиться и повышать точность с течением времени, нейронные сети полагаются на обучающие данные. Однако эти алгоритмы обучения становятся эффективными инструментами в области информатики и искусственного интеллекта.
Давайте рассмотрим, как работает нейронная сеть.
Считайте, что каждый узел представляет собой отдельную модель линейной регрессии с входными данными (X), весами (w), смещением (b) и выходными данными (Z). Формула должна выглядеть следующим образом:
— это метод, с помощью которого нейронная сеть выдает выходные данные для определенного входного сигнала. Выходные данные последнего слоя также называются прогнозами нейронной сети. Далее в этой статье мы рассмотрим, как мы оцениваем прогнозы. Эти оценки можно использовать, чтобы определить, нуждается ли наша нейронная сеть в улучшении.
Мы вычисляем функцию стоимости сразу после генерации выходных данных последним слоем. Функция стоимости вычисляет, насколько далека от желаемых прогнозов наша нейронная сеть. Значение функции стоимости демонстрирует несоответствие между истинным значением и прогнозируемым значением.
Вот одна из функций стоимости:
Здесь 1/m масштабирует результаты потерь, yi представляет фактический выход, а log(yhat) представляет прогнозируемый выход. Самое интересное в этой функции потерь — это отрицательный знак в начале, она просто компенсирует логарифмический отрицательный выход как log (близко к 0) дает отрицательное значение.
Обратное распространение
В качестве алгоритма машинного обучения обратное распространение ошибки выполняет обратный проход для настройки параметров модели нейронной сети с целью минимизировать потери.
Давайте посмотрим, как он рассчитывает градиенты
Градиентный спуск
Параметры нейронной сети обновляются с использованием градиентного спуска. Этот алгоритм изменяет веса и смещения каждого слоя в сети в зависимости от того, как это повлияет на минимизацию функции стоимости. Обратное распространение ошибки используется для расчета влияния весов и смещений каждого входного нейрона сети на минимизацию функции стоимости.
Производная функции потерь по (w,b) и вычисление градиентов для оптимизации потерь. Здесь J — функция потерь, а градиент w представляет направление в пространстве. Целью здесь является достижение глобальных минимумов.
Обновить градиенты
Здесь альфа — скорость обучения, w — старый вес, а dl/dw — потеря производной по весу. Для нового смещения мы сделали то же самое.
Давайте реализуем эти идеи в коде
Инициализировать параметр для каждого уровня сети. У вас есть возможность инициализировать вес в различных типах распределения, например: равномерном, случайном нормальном распределении или любом другом распределении, если хотите. Здесь я использую numpy randn, который по сути генерирует стандартное нормальное распределение.
def initialize_parameters(self): np.random.seed(42) for l in range(1, len(self.layers_size)): self.parameters["W" + str(l)] = np.random.randn(self.layers_size[l], self.layers_size[l - 1]) / np.sqrt( self.layers_size[l - 1]) self.parameters["b" + str(l)] = np.zeros((self.layers_size[l], 1))
Прямое распространение
def forward(self, X): dict = {} A = X.T for l in range(self.L - 1): Z = self.parameters["W" + str(l + 1)].dot(A) + self.parameters["b" + str(l + 1)] A = self.sigmoid(Z) dict["A" + str(l + 1)] = A dict["W" + str(l + 1)] = self.parameters["W" + str(l + 1)] dict["Z" + str(l + 1)] = Z Z = self.parameters["W" + str(self.L)].dot(A) + self.parameters["b" + str(self.L)] A = self.softmax(Z) dict["A" + str(self.L)] = A dict["W" + str(self.L)] = self.parameters["W" + str(self.L)] dict["Z" + str(self.L)] = Z return A, dict
Обратное распространение
def backward(self, X, Y, dict): derivatives = {} dict["A0"] = X.T A = store["A" + str(self.L)] dZ = A - Y.T dW = dZ.dot(dict["A" + str(self.L - 1)].T) / self.batch db = np.sum(dZ, axis=1, keepdims=True) / self.batch dAPrev = dict["W" + str(self.L)].T.dot(dZ) derivatives["dW" + str(self.L)] = dW derivatives["db" + str(self.L)] = db for l in range(self.L - 1, 0, -1): dZ = dAPrev * self.sigmoid_derivative(dict["Z" + str(l)]) dW = 1. / self.batch * dZ.dot(dict["A" + str(l - 1)].T) db = 1. / self.batch * np.sum(dZ, axis=1, keepdims=True) if l > 1: dAPrev = dict["W" + str(l)].T.dot(dZ) derivatives["dW" + str(l)] = dW derivatives["db" + str(l)] = db return derivatives
Обновить градиенты с помощью мини-пакета
Мини-пакет — это фиксированное количество обучающих примеров, меньшее, чем фактический набор данных. Таким образом, на каждой итерации мы обучаем сеть на разных группах выборок, пока не будут использованы все выборки набора данных. У вас есть возможность выбирать размер пакета. Теоретически разумно выбрать любую степень по основанию 2.
def fit(self, X, Y, learning_rate=1, n_iterations=10,batch=32): np.random.seed(1) self.batch = batch for loop in range(n_iterations): mini_batches = self.create_mini_batches(X, Y, self.batch) loss = 0 acc = 0 for mini_batch in mini_batches: X_mini, y_mini = mini_batch A, store = self.forward(X_mini) loss += -1*np.mean(y_mini * np.log(A.T+ 1e-8))# CCE cost function A.T is updated weight derivatives = self.backward(X_mini, y_mini, store) for l in range(1, self.L + 1): self.parameters["W" + str(l)] = self.parameters["W" + str(l)] - learning_rate * derivatives[ "dW" + str(l)] self.parameters["b" + str(l)] = self.parameters["b" + str(l)] - learning_rate * derivatives[ "db" + str(l)] acc += self.predict(X_mini, y_mini) self.costs.append(loss) print("Epoch",loop+1,"\steps ",len(mini_batches),"Train loss: ", "{:.4f}".format(loss/len(mini_batches)), "Train acc:", "{:.4f}".format(acc/len(mini_batches)))
Запустите и посмотрите результат
train_x , test_x , train_y , test_y = load_mnist() layers_dims = [10, 10] ann = ANN(layers_dims,train_x.shape[1]) ann.fit(train_x, train_y, learning_rate=.1, n_iterations=100,batch=64)
Я показываю вам только последние несколько шагов вывода обучающей модели, поскольку она имеет большое количество итераций.
После завершения обучения можно построить график потерь, чтобы увидеть, как они меняются с течением каждой эпохи.
Проверка работоспособности с помощью одного изображения прогноз
Как вы можете видеть, наша модель работает довольно хорошо: ее точность при тестировании составляет 92,3%, а точность поезда — 95,45%. Есть много возможностей для обновления этой модели и повышения точности. Дайте мне знать ваш подход к повышению производительности.
Спасибо, что прочитали. Вот полный код
Ссылки
MIT Deep Learning 6.S191MIT Deep Learning 6.S191http://introtodeeplearning.com
https://en.wikipedia.org/wiki/Backpropagation