Есть ли лучшая функция активации для моей нейронной сети?

Я пишу программу для распознавания рукописных букв. У меня есть изображения 500px * 500px, которые я импортирую как BufferedImages, и я принимаю значение getRBG() каждого пикселя в качестве входных данных для нейронной сети, поэтому есть 250 000 входных данных. Значения для getRGB() находятся в диапазоне от -16777216 (обозначает запись) до -1 (обозначает белый фон). Веса от входа до первого скрытого узла рандомизированы от 0 до 1. Я использовал сигмовидную функцию 1/(1+e^(-x)) в качестве функции активации, чтобы получить все значения между 0 и 1. Моя проблема, однако, заключается в том, что, поскольку есть так много входных данных, когда я беру их скалярное произведение с весами, я получаю число с огромной величиной (например, 1.3E8 или -1.3E8). Затем, когда я помещаю это число в сигмовидную функцию, результаты всегда равны 1 или 0, поэтому, по сути, он не передает никакой ценной информации второму скрытому узлу. Кроме того, поскольку изображения преимущественно белые, большинство входных данных равны -1.

Я изменил код так, чтобы он печатал значения после скалярного произведения, а затем печатал их после того, как они проходят через сигмовидную функцию.

After dot product with weights, before sigmoid function: 
-1.3376484582733577E8   
-1.3382651127917042E8   
-1.3438475698429278E8   
-1.3356711106666781E8   
-1.3470225249402404E8   
-1.3372922925798771E8   
-1.3211961536262843E8   
-1.3512040351863045E8   

After sigmoid function: 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 
0.0 

Для редактирования значений getRGB() я использовал функцию newRGBValue = (getRGB() + 2) * (-1), поэтому все значения находились в диапазоне от -1 до 16777214. Однако когда я передаю все эти значения в сигмовидную функцию, она просто возвращает 1, поскольку новое скалярное произведение с этими значениями — огромные положительные числа (показаны в выводе ниже).

After dot product, before sigmoid function: 
1.3198725189415371E8    
1.3345978405544662E8    
1.3375036029244222E8    
1.3278472449389385E8    
1.328751157809899E8 
1.3309195657860701E8    
1.34090008925348E8  
1.3300517803640646E8

After: 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0

Есть ли лучшая функция активации, которую я должен использовать для этой программы? Или есть способ манипулировать входами, чтобы сигмовидная функция подходила? Извините за этот длинный пост и заранее спасибо за любую информацию.


person Biz    schedule 01.05.2018    source источник


Ответы (1)


Нормализуйте свои входные данные. То есть для каждого изображения вычислите среднее значение mu и дисперсию sigma значений пикселей и замените старое значение пикселя v нормализованным значением (v - mu) / sigma. Это устраняет огромные отрицательные значения, которые у вас были для значений пикселей.

Также рассмотрите возможность использования нормально распределенных начальных случайных весов со средним значением 0 и дисперсией 1, чтобы ожидаемое значение ваших скалярных произведений было равно 0. Тогда было бы лучше переключиться на функцию активации tanh, центр которой находится в 0, что приводит к к более быстрому обучению (если ваши скалярные произведения близки к 0).

person k_ssb    schedule 01.05.2018