- •Факультет вычислительной математики и кибернетики
- •Кафедра математического обеспечения ЭВМ
- •Введение
- •1. Возможные модели функционирования биологической нейронной сети
- •2. Математические модели, положенные в основу рассматриваемого подхода
- •2.1. Изменение мембранного потенциала
- •2.2. Кратковременная синаптическая пластичность
- •2.3. Долговременная синаптическая пластичность
- •3. Программная реализация
- •4. Повышение производительности вычислений
- •Заключение
- •Литература
- •Приложение
Заключение
В результате проделанной работы было установлено, что рассмотренная выше модель функционирования биологической нейронной сети хорошо подходит для применения вычислений общего назначения на графических процессорах; поэтому их можно применять для исследования других подобных моделей.
Полученные результаты также подтверждают, что при прочих равных условиях производительность, полученная с использованием технологии CUDA, лучше, чем в случае применения OpenCL (на картах от NVidia). Однако в том случае, если нас интересует поддержка кроссплатформенности, применение OpenCL можно рассматривать как некий компромисс между производительностью и возможностью исполнения на разных устройствах.
15
Литература
1.Савельев А.В. На пути к общей теории нейросетей. К вопросу о сложности (грант РФФИ 04-06-80460. Журнал Нейрокомпьютеры: разработка, применение №4-5, 2006 г., с. 4).
2.Ёлкин С.C., Ёлкин С.В., Клышинский Э.С., Максимов В.Ю., Мусаева Т.Н. Модель бионической нейронной сети и её применения. ИПМ им. М.В.Келдыша РАН, Москва, 2008.
3.Круглов В.В., Борисов В.В. Искусственные нейронные сети. Теория и практика – М.: Издательство Горячая линия-Телеком, 2002.
4.Давыдов А.А., Зайцев Д.В. Модель динамики нейронной сети на основе теории марковских процессов. Сергиев Посад, Центральный физико-технический институт, 2001.
5.Tsodyks, M., Pawelzik, K., Markram, H. Neural networks with dynamic synapses. Neural Computation 10:821-835, 1998.
6.Куффлер C., Николс Дж. От нейрона к мозгу. М.: Мир. 1979.
7.Малинецкий Г.Г., Ижикевич Е.M. О возможной роли хаоса в нейросистемах // ДАН, т.
326, N 4, 1992, с. 626-632.
8.Izhikevich E.M. Simple Model of Spiking Neurons. - IEEE Transactions on Neural Networks,
2003, vol. 14, № 6, pp. 1569 – 1572.
16
Приложение
Листинг 1: Ядра на CUDA
__global__ void Calculate_Input_Sum(const int Count_In_Neurons, const int max_values_count, float* weights,
float* output_signal, int* excitory,
int* delay_index, float input_sum)
{
int idx = blockDim.x*blockIdx.x + threadIdx.x;
if (idx < Count_In_Neurons)
{
if (excitory[idx])
input_sum += (output_signal+max_values_count*idx)[delay_index[idx]]* weights[idx];
else
input_sum -= (output_signal+max_values_count*idx)[delay_index[idx]]* weights[idx];
}
}
__global__ void STDP_first(const int Count_In_Neurons, const int max_values_count, const float learning_rate, float* output_signal,
int* excitory, int* delay_index, float* weights)
{
int idx = blockDim.x*blockIdx.x + threadIdx.x;
if ((idx < Count_In_Neurons)&&(excitory[idx]))
weights[idx] += learning_rate*(1-weights[idx])* (output_signal+max_values_count*idx)[delay_index[idx]];
}
__global__ void STDP_second(const int Count_In_Neurons, const int max_values_count, const float learning_rate, const float alfa_learn, float* output_signal,
int* delay_index, float* weights)
{
int idx = blockDim.x*blockIdx.x + threadIdx.x;
if ((idx < Count_In_Neurons)&&(excitory[idx]))
{
if ((output_signal+max_values_count*idx)[delay_index[idx]+1]< (output_signal+max_values_count*idx)[delay_index[idx]])
weights[idx] -= learning_rate*alfa_learn*weights[idx]*output;
}
}
17
Листинг 2: Ядра на OpenCL
const char* source_cl_string =
"__kernel void Calculate_Input_Sum(const uint Count_In_Neurons, |
\n"\ |
|
" |
const uint max_values_count, |
\n"\ |
" |
__global float* weights, |
\n"\ |
" |
__global float* output_signal, |
\n"\ |
" |
__global uint* excitory, |
\n"\ |
" |
__global int* delay_index, |
\n"\ |
" |
float input_sum) |
\n"\ |
"{ |
|
\n"\ |
"int i = get_global_id(0); |
\n"\ |
|
"if (i < Count_In_Neurons) |
\n"\ |
|
"{ |
|
\n"\ |
"if (excitory[i]) |
\n"\ |
|
"input_sum += (output_signal+max_values_count*i)[delay_index[i]]* |
\n"\ |
|
" |
weights[i]; |
\n"\ |
"else input_sum -= |
\n"\ |
|
"output_signal+max_values_count*i)[delay_index[i]]*weights[i]; |
\n"\ |
|
"} |
|
\n"\ |
"} |
|
\n"\ |
" |
|
\n"\ |
"__kernel void STDP_first(const uint Count_In_Neurons, |
\n"\ |
|
" |
const uint max_values_count, |
\n"\ |
" |
const float learning_rate, |
\n"\ |
" |
__global float* output_signal, |
\n"\ |
" |
__global uint* excitory, |
\n"\ |
" |
__global int* delay_index, |
\n"\ |
" |
__global float* weights) |
\n"\ |
"{ |
|
\n"\ |
"int i = get_global_id(0); |
\n"\ |
|
"if ((i < Count_In_Neurons)&&(excitory[i])) |
\n"\ |
|
" |
|
\n"\ |
"weights[i] += learning_rate*(1-weights[i])* |
\n"\ |
|
" |
(output_signal+max_values_count*i)[delay_index[i]]; |
\n"\ |
"} |
|
\n"\ |
" |
|
\n"\ |
"__kernel void STDP_second(const uint Count_In_Neurons, |
\n"\ |
|
" |
const uint max_values_count, |
\n"\ |
" |
const float learning_rate, |
\n"\ |
" |
const float alfa_learn, |
\n"\ |
" |
__global float* output_signal, |
\n"\ |
" |
__global int* delay_index, |
\n"\ |
" |
__global float* weights) |
\n"\ |
"{ |
|
\n"\ |
"int i = get_global_id(0); |
\n"\ |
|
"if ((i < Count_In_Neurons)&&(excitory[i])) |
\n"\ |
|
"{ |
|
\n"\ |
"if ((output_signal+max_values_count*i)[delay_index[i]+1]< |
\n"\ |
|
" |
(output_signal+max_values_count*i)[delay_index[i]]) |
\n"\ |
" |
|
\n"\ |
"weights[i] -= learning_rate*alfa_learn*weights[i]*output; |
\n"\ |
|
"} |
|
\n"\ |
"}"; |
|
|
18