Генетический алгоритм в сочетании с PyTorch для обучения нейронной сети(1)

PyTorch
Генетический алгоритм в сочетании с PyTorch для обучения нейронной сети(1)

Это 25-й день моего участия в Gengwen Challenge.Подробности о мероприятии:Обновить вызов

Генетический алгоритм сегодня широко используется в некоторых алгоритмах машинного обучения. Он может не только заменить алгоритм градиентного спуска для оптимизации параметров, но также может использоваться для поиска параметров нейронных сетей в пространстве параметров. На этот раз мы в основном возьмем посмотрите как использовать генетику в тренировочном процессе Pytorch.Алгоритмы оптимизации весовых параметров.

Краткое изложение шагов

  • Создайте модель PyTorch
  • создать экземплярpygad.torchga.TorchGAсвоего рода
  • Подготовьте обучающие данные
  • определить функцию оценки
  • создать экземплярpygad.GAсвоего рода
  • Запустите генетический алгоритм

Создайте модель PyTorch

import torch

# 定义神经网络,包含一个隐含层,然后输出层
input_layer = torch.nn.Linear(3, 5)
relu_layer = torch.nn.ReLU()
output_layer = torch.nn.Linear(5, 1)

model = torch.nn.Sequential(input_layer,
                            relu_layer,
                            output_layer)

pygad.torchga.TorchGA Class

В модуле pygad.torchga есть класс TorchGA для создания начальных популяций для генетических алгоритмов на основе моделей PyTorch. Конструкторы, методы и свойства в этом классе.

Конструктор класса pygad.torchga.TorchGA принимает следующие параметры:

  • модель: принимает экземпляр модели PyTorch
  • num_solutions: количество решений в совокупности. Каждое решение имеет разные параметры модели

свойства экземпляра

Все параметры в конструкторе класса pygad.torchga.TorchGA используются в качестве атрибутов экземпляра, кроме того, был добавлен новый атрибут, называемый населением_весов.

Ниже приведен список всех свойств экземпляра:

  • model
  • num_solutions
  • населения_весов: вложенный список, содержащий веса всех решений в совокупности

Методы класса TorchGA

Далее поговорим о методах, предоставляемых экземплярами класса pygad.torchga.TorchGA.

create_population()

create_population()Метод создает начальную популяцию генетических алгоритмов в виде списка решений, каждое из которых представляет отдельный параметр модели. Список сетей назначается свойству населения_весов экземпляра.

pygad.torchga.model_weights_as_vector()

model_weights_as_vector()Функция принимает только один параметр, модель, которая имеет тип модели PyTorch. Возвращает вектор, содержащий все веса модели. Причина представления весов модели в виде векторов заключается в том, что генетический алгоритм ожидает, что все параметры любого решения будут представлены в виде одномерных векторов.

параметры функции.

  • model: PyTorch model

Возвращаемое значение представляет собой одномерный вектор весов модели.

pygad.torch.model_weights_as_dict()

Функция model_weights_as_dict() принимает следующие параметры.

  • модель: модель PyTorch
  • weights_vector: параметры модели в векторной форме

Возвращаемое значение этой функции совпадает с возвращаемым значением state_dict(), которое представляет собой вес модели. Возвращенную модель можно загрузить в параметры модели PyTorch с помощью метода load_state_dict().

pygad.torchga.predict()

Функция predict() делает прогнозы на основе решения. принять параметры

  • модель: модель PyTorch.
  • решение: развитое решение
  • data: ввод для тестовых данных

Возвращает результат прогнозирования для выборки данных

В сочетании с этим примером давайте рассмотрим следующий код шаг за шагом, основываясь на общих шагах использования генетического алгоритма для обновления параметров модели Pytorch для реализации обучения модели Pytorch.

Создайте модель Pytorch

Первый шаг — создать модель PyTorch.Следующее — использовать API Pytorch для создания простой модели Pytorch.Модель состоит из двухслойной нейронной сети, скрытого слоя и выходного слоя. Всего в качестве весов используется 10 нейронов.

import torch

input_layer = torch.nn.Linear(3, 5)
relu_layer = torch.nn.ReLU()
output_layer = torch.nn.Linear(5, 1)

model = torch.nn.Sequential(input_layer,
                            relu_layer,
                            output_layer)

Создайте экземпляр класса pygad.torchga.TorchGA.

Второй шаг — создать экземпляр класса pygad.torchga.TorchGA с 10 решениями на популяцию, соответствующими 10 весовым параметрам приведенной выше нейронной сети.

import pygad.torchga

torch_ga = torchga.TorchGA(model=model,
                           num_solutions=10)

Конструктор torchga.TorchGA принимает 2 параметра: модель pytorch, размерность каждого отдельного вектора и количество параметров, которые должна изучить модель.

Подготовьте обучающий набор данных

Третий шаг — подготовить входные данные (функции выборки) и выходные данные (метки выборки) обучающих данных, есть пример с 4 выборками. Каждый образец имеет 3 функции в качестве входных данных и 1 в качестве метки.

import numpy

# Data inputs
data_inputs = numpy.array([[0.02, 0.1, 0.15],
                           [0.7, 0.6, 0.8],
                           [1.5, 1.2, 1.7],
                           [3.2, 2.9, 3.1]])

# Data outputs
data_outputs = numpy.array([[0.1],
                            [0.6],
                            [1.3],
                            [2.5]])

определить функцию оценки

Четвертый шаг - определить функцию оценки, эта функция должна принимать 2 параметра: первый индивидуум (решение) и положение индивидуума в популяции. Следующая функция оценки вычисляет MAE (средняя абсолютная ошибка) модели PyTorch на основе параметров решения. Инверсия MAE возвращается в качестве оценочного значения.

loss_function = torch.nn.L1Loss()

def fitness_func(solution, sol_idx):
    global data_inputs, data_outputs, torch_ga, model, loss_function

    predictions = pygad.torchga.predict(model=model,
                                        solution=solution,
                                        data=data_inputs)

    abs_error = loss_function(predictions, data_outputs).detach().numpy() + 0.00000001

    solution_fitness = 1.0 / abs_error

    return solution_fitness

ga_instance.run()

После выполнения PyGAD весь тренировочный процесс будет визуально представлен графиком, а для отображения графика будет вызываться метод plot_fitness().

ga_instance.plot_fitness(title="PyGAD & PyTorch - Iteration vs. Fitness", linewidth=4)

полный код

import torch
import pygad.torchga
import pygad

def fitness_func(solution, sol_idx):
    global data_inputs, data_outputs, torch_ga, model, loss_function
    """
    - model:模型
    - solution: 也就是遗传算法群体中的个体
    - data: 数据
    """
    predictions = pygad.torchga.predict(model=model,
                                        solution=solution,
                                         data=data_inputs)
    # 计算误差
    abs_error = loss_function(predictions, data_outputs).detach().numpy() + 0.00000001

    # 因为评估值是越大越好
    solution_fitness = 1.0 / abs_error

    return solution_fitness

def callback_generation(ga_instance):
    print("Generation = {generation}".format(generation=ga_instance.generations_completed))
    print("Fitness    = {fitness}".format(fitness=ga_instance.best_solution()[1]))

# 创建 PyTorch 模型
input_layer = torch.nn.Linear(3, 5)
relu_layer = torch.nn.ReLU()
output_layer = torch.nn.Linear(5, 1)

# 定义模型
model = torch.nn.Sequential(input_layer,
                            relu_layer,
                            output_layer)

# 在初始化种群时,实例化 pygad.torchga.TorchGA 
torch_ga = pygad.torchga.TorchGA(model=model,
                           num_solutions=10)
# 定义 loss 函数
loss_function = torch.nn.L1Loss()

# 数据集输入数据
data_inputs = torch.tensor([[0.02, 0.1, 0.15],
                            [0.7, 0.6, 0.8],
                            [1.5, 1.2, 1.7],
                            [3.2, 2.9, 3.1]])

# 数据集
data_outputs = torch.tensor([[0.1],
                             [0.6],
                             [1.3],
                             [2.5]])

num_generations = 250 # 迭代次数
num_parents_mating = 5 # 每次从父类中选择的个体进行交叉、和突变的数量
initial_population = torch_ga.population_weights # 初始化网络权重

ga_instance = pygad.GA(num_generations=num_generations,
                       num_parents_mating=num_parents_mating,
                       initial_population=initial_population,
                       fitness_func=fitness_func,
                       on_generation=callback_generation)

ga_instance.run()

ga_instance.plot_fitness(title="PyGAD & PyTorch - Iteration vs. Fitness", linewidth=4)

# 返回最优参数的详细信息
solution, solution_fitness, solution_idx = ga_instance.best_solution()
print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
print("Index of the best solution : {solution_idx}".format(solution_idx=solution_idx))

# 基于最好的个体来进行预测
predictions = pygad.torchga.predict(model=model,
                                    solution=solution,
                                    data=data_inputs)
print("Predictions : \n", predictions.detach().numpy())

abs_error = loss_function(predictions, data_outputs)
print("Absolute Error : ", abs_error.detach().numpy())

# 以下是评估效果

"""
Fitness value of the best solution = 74.17345574365933
Index of the best solution : 0
预测结果 : 
 [[0.09415314]
 [0.6399874 ]
 [1.2981992 ]
 [2.5062926 ]]
错误率的绝对值 :  0.013481902
"""