Нормировка входных данных в нерокомпьютинге применяется давно. Основная её цель — это привести все разнородные (различные единицы измерений) входные сигналы к единому формату. Но если в отдельных случаях для обучения искусственного нейрона можно обойтись и без нормирования, то в случае VMR, этот фокус не пройдёт. Дело в том, что предварительное нормирование входных данных к диапазоно от -1 до 1 включительно является обязательной подготовкой к последующей инвариантности.
Формулы для нормирования в LibVMR линейные, т.к. нелинейность достигается с помощью ядерных преобразований. Сначала для каждой объясняющей переменной находим максимальное (max) и минимальное (min) значения, а потом уже взяв конкретное значение переменной, загоняем его в диапазон от -1 до 1 включительно:
v' = 2 * (v – min) / (max – min) – 1
где:
v' – нормированное значение ненормированной переменной v
Помимо самого нормирования входных данных нам ещё необходимо отделить значения объясняющих переменных и зависимой переменной, разнеся их по разным массивам.
Создадим код на Java:
package libvmr; /** * Векторная машина Решетова * @author Yury V. Reshetov * @version 1.0 */ public class VMR { /** * Максимумы столбцов обучающей выборки */ private double[] maxs = null; /** * Минимумы столбцов обучающей выборки */ private double[] mins = null; /** * Значения зависимых переменных */ private double[] ideals = null; /** * Нормирование обучающей выборки * @param samples ненормированная обучающая выборка * @return Нормированная обучающая выборка */ private double[][] normSetting(double[][] samples) { // Вытаскиваем последний столбец обучающей выборки - результаты this.ideals = new double[samples.length]; for (int i = 0; i < samples.length; i++) { this.ideals[i] = this.convertToRange(samples[i][samples[0].length - 1], 1d, 0d); } double[][] normsamples = new double[samples.length][samples[0].length - 1]; // Ищем максимумы и минимумы this.maxs = new double[normsamples[0].length]; this.mins = new double[normsamples[0].length]; for (int j = 0; j < normsamples[0].length; j++) { double max = samples[0][j]; double min = max; for (int i = 1; i < normsamples.length; i++) { if (samples[i][j] > max) { max = samples[i][j]; } if (samples[i][j] < min) { min = samples[i][j]; } } this.maxs[j] = max; this.mins[j] = min; } // Нормализуем for (int i = 0; i < normsamples.length; i++) { for (int j = 0; j < normsamples[0].length; j++) { normsamples[i][j] = this.convertToRange(samples[i][j],this.maxs[j],this.mins[j]); } } return normsamples; } /** * Преобразование переменных из диапазона от минимального значения до максимального включительно к диапазону от -1 до 1 включительно * @param value значение переменной * @param maximmumvalue максимальное значение переменной * @param minimumvalue минимальное значение переменной * @return нормированное значение переменной в диапазоне от -1 до 1 включительно */ private double convertToRange(double value, double maximmumvalue, double minimumvalue) { return 2d * (value - minimumvalue) / (maximmumvalue - minimumvalue) - 1d; } }
Комментариев нет:
Отправить комментарий