Исполнение нейронной сети, загруженной на бэкенд вручную
Этот раздел содержит инструкции по созданию нейронной сети, ее загрузке на бэкенд для CPU и исполнению.
Вы можете использовать эту инструкцию для разработки прикладных решений.
Чтобы автоматически загрузить нейронную сеть на бэкенд и исполнить ее:
- В директории вашего проекта создайте файл программы с расширением .py, в котором будет реализована функция для создания и запуска нейронной сети.
- В файле программы импортируйте объекты библиотек платформы, необходимые для исполнения нейронной сети.
Если требуется, определите псевдонимы с помощью оператора
as.Пример подключения объектов библиотек для исполнения нейронной сети с популяцией BLIFAT-нейронов и проекцией дельта-синапсов на однопоточном бэкенде для CPU:
Python
from knp.base_framework._knp_python_framework_base_framework import BackendLoader
from knp.core._knp_python_framework_core import UID, BLIFATNeuronPopulation, DeltaSynapseProjection, SpikeMessage
from knp.neuron_traits._knp_python_framework_neuron_traits import BLIFATNeuronParameters
from knp.synapse_traits._knp_python_framework_synapse_traits import DeltaSynapseParameters, OutputType
- Реализуйте генератор нейронов с нужными вам свойствами или используйте готовый генератор из библиотеки фреймворка.
Пример реализации генератора BLIFAT-нейронов:
Python
# Реализация функции, генерирующей BLIFAT-нейроны.
def neuron_generator(_): # type: ignore[no-untyped-def]
return BLIFATNeuronParameters()
- Реализуйте генератор синапсов с нужными вам свойствами или используйте готовый генератор из библиотеки фреймворка.
Пример реализации генератора дельта-синапсов:
Python
# Реализация функции, генерирующей дельта-синапсы для проекции, которая будет замыкать вывод
# популяции на себя.
def synapse_generator(_): # type: ignore[no-untyped-def]
return DeltaSynapseParameters(1.0, 6, OutputType.EXCITATORY), 0, 0
# Реализация функции, генерирующей дельта-синапсы для проекции, которая будет связана
# с каналом ввода.
def input_projection_gen(_): # type: ignore[no-untyped-def]
return DeltaSynapseParameters(1.0, 1, OutputType.EXCITATORY), 0, 0
- Создайте функцию, в которой будут созданы объекты, необходимые для исполнения нейронной сети.
Пример создания функции main:
Python
def main(): # type: ignore[no-untyped-def]
# ...
- В созданной функции создайте объект популяции и передайте в конструктор генератор нейронов.
Пример создания объекта популяции:
Python
# ...
# Создание объекта популяции с одним BLIFAT-нейроном.
population = BLIFATNeuronPopulation(neuron_generator, 1)
# ...
- В созданной функции создайте объект проекции, который будет замыкать вывод популяции на себя. Передайте в конструктор идентификатор связанной популяции и генератор синапсов.
Пример создания проекции, замыкающей вывод популяции на себя:
Python
# ...
# Создание объекта проекции с одним дельта-синапсом, замыкающей вывод популяции
# на себя.
loop_projection = DeltaSynapseProjection(
population.uid, population.uid, synapse_generator, 1
)
# ...
- В созданной функции создайте объект входной проекции. Передайте в конструктор генератор синапсов и идентификатор связанной популяции.
Пример создания входной проекции, связанной с каналом ввода и популяцией:
Python
# ...
# Создание объекта входной проекции с одним дельта-синапсом, которой присваивается
# нулевой идентификатор (UID(False)). Проекция принимает спайки от канала ввода
# и отправляет синаптическое воздействие в объект популяции.
input_projection = DeltaSynapseProjection(
UID(False), population.uid, input_projection_gen, 1
)
# Сохранение UID входной проекции в переменной input_uid.
input_uid = input_projection.uid
# ...
- В созданной функции загрузите экземпляр бэкенда и загрузите в него созданные популяцию и проекции. Создайте точку подключения.
Пример загрузки бэкенда и создания точки подключения:
Python
# ...
# Загрузка экземпляра однопоточного бэкенда для CPU с локального компьютера.
backend = BackendLoader().load(f'{pytestconfig.rootdir}/../lib/libknp-cpu-single-threaded-backend')
# Загрузка созданной популяции в экземпляр бэкенда.
backend.load_all_populations([population])
# Загрузка созданных проекций в экземпляр бэкенда.
backend.load_all_projections([input_projection, loop_projection])
# Инициализация бэкенда.
backend._init()
# Создание объекта точки подключения.
endpoint = backend.message_bus.create_endpoint()
# ...
- В созданной функции определите идентификаторы каналов ввода и вывода.
Пример определения идентификаторов каналов ввода и вывода:
Python
# ...
# Создание произвольных идентификаторов in_channel_uid и out_channel_uid для каналов
# ввода и вывода.
in_channel_uid = UID()
out_channel_uid = UID()
# ...
- В созданной функции подпишите бэкенд и точку подключения на сообщения от каналов ввода и вывода.
Пример подписки бэкенда и точки подключения на сообщения
SpikeMessage:Python
# ...
# Подписка бэкенда на спайки от канала ввода.
backend.subscribe(SpikeMessage, input_uid, [in_channel_uid])
# Подписка точки подключения на спайки от канала вывода.
endpoint.subscribe(SpikeMessage, out_channel_uid, [population.uid])
# ...
- В созданной функции исполните нейронную сеть. При необходимости создайте список, в который будут записываться индексы шагов, на которых на канал вывода приходят спайки.
Пример исполнения 20 шагов нейронной сети:
Python
# ...
# Создание списка results, в который будут записываться индексы шагов со спайками.
results = []
for step in range(0, 20):
# Отправка спайков на шагах 0, 5, 10 и 15 исполнения нейронной сети.
if step % 5 == 0:
# Отображение номера шага, на котором канал ввода отправил спайк входной проекции.
print(f'STEP {step}')
message = SpikeMessage((in_channel_uid, step), [0])
endpoint.send_message(message)
backend._step()
messages_count = endpoint.receive_all_messages()
output = endpoint.unload_messages(SpikeMessage, out_channel_uid)
if len(output):
# Отображение номера шага, на котором на канал вывода пришел спайк.
print(f'STEP {step}')
- Запустите программу.