Задний план
Признание первичности кажется плохо приспособленным для (искусственных) нейронных сетей. Тем не менее, теорема об универсальном приближении утверждает, что нейронные сети могут аппроксимировать любую непрерывную функцию, поэтому, в частности, должна быть возможность представить любую функцию с конечной поддержкой, какую только пожелает. Итак, давайте попробуем распознать все простые числа среди первого миллиона чисел.
Точнее, потому что это веб-сайт для программирования, давайте поднимемся до 2 ^ 20 = 1 048 576. Число простых чисел ниже этого порога составляет 82 025 или примерно 8%.
Вызов
Какую маленькую нейронную сеть вы можете найти, чтобы правильно классифицировать все 20-битные целые числа как простые или не простые?
Для целей этой задачи размер нейронной сети - это общее количество весов и смещений, необходимых для ее представления.
Детали
Цель состоит в том, чтобы минимизировать размер одной явной нейронной сети.
Входными данными для вашей сети будет вектор длиной 20, содержащий отдельные биты целого числа, представленные либо с 0 и 1, либо, альтернативно, с -1 и + 1. Их порядок может быть самым старшим битом первым или наименее значимым битом первым.
Выход вашей сети должен быть одним числом, таким образом, что выше некоторого предела вход распознается как простое число, а ниже того же самого предела вход распознается как не простое число. Например, положительное значение может означать простое число (и отрицательное, а не простое) или, альтернативно, больше 0,5 может означать простое число (и меньше 0,5 не простое)
Сеть должна быть на 100% точной на всех 2 ^ 20 = 1 048 576 возможных входах. Как упомянуто выше, отметьте, что в этом диапазоне есть 82 025 простых чисел. (Из этого следует, что всегда вывод «не простое» будет точным на 92%.)
С точки зрения стандартной терминологии нейронной сети это, вероятно, будет называться переоснащением . Другими словами, ваша цель - идеально подобрать простые числа. Другими словами, которые можно использовать, это то, что «тренировочный набор» и «тестовый набор» совпадают.
Эта задача не учитывает количество «обучаемых» или «обучаемых» параметров. Действительно, ваша сеть, скорее всего, содержит жестко запрограммированные веса, а приведенный ниже пример полностью запрограммирован. Вместо этого все веса и смещения считаются параметрами и учитываются.
Длина кода, необходимого для обучения или создания вашей нейронной сети, не имеет отношения к вашей оценке, но публикация соответствующего кода, безусловно, приветствуется.
базисный
В качестве основы можно «запомнить» все 82 025 простых чисел с общим весом 1 804 551 и смещениями.
Обратите внимание, что следующий код включает в себя много вещей: рабочий пример, рабочий тестовый код, рабочее определение нейронной сети с использованием известной библиотеки нейронной сети, «жестко закодированную» (или, по крайней мере, не «обученную») нейронную сеть, и рабочее измерение счета.
import numpy as np
bits = 20
from keras.models import Sequential
from keras.layers import Dense
from sympy import isprime
# Hardcode some weights
weights = []
biases = []
for n in xrange(1<<bits):
if not isprime(n):
continue
bit_list = [(n / (1 << i))%2 for i in xrange(bits)]
weight = [2*bit - 1 for bit in bit_list]
bias = - (sum(bit_list) - 1)
weights.append(weight)
biases .append(bias)
nprimes = len(biases)
weights1 = np.transpose(np.array(weights))
biases1 = np.array(biases )
weights2 = np.full( (nprimes,1), 1 )
biases2 = np.array( [0] )
model = Sequential()
model.add(Dense(units=nprimes, activation='relu', input_dim=bits, weights=[weights1, biases1]))
model.add(Dense(units=1, activation='relu', weights=[weights2, biases2]))
print "Total weights and biases: {}".format( np.size(weights1) + np.size(weights2) + np.size(biases1) + np.size(biases2) )
# Evaluate performance
x = []
y = []
for n in xrange(1<<bits):
row = [(n / (1 << i))%2 for i in xrange(bits)]
x.append( row )
col = 0
if isprime(n):
col = 1
y.append( col )
x = np.array(x)
y = np.array(y)
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy'])
loss, accuracy = model.evaluate(x, y, batch_size=256)
if accuracy == 1.0:
print "Perfect fit."
else:
print "Made at least one mistake."
Что такое нейронная сеть?
Для целей этой задачи мы можем записать узкое, но точное определение (искусственной) нейронной сети. Для некоторого внешнего чтения я предлагаю Википедию по искусственной нейронной сети , нейронной сети с прямой связью , многослойному персептрону и функции активации. .
Упреждением нейронная сеть представляет собой совокупность слоев нейронов. Количество нейронов на слой варьируется: 20 нейронов во входном слое, некоторое количество нейронов в одном или нескольких скрытых слоях и 1 нейрон в выходном слое. (Должен быть, по крайней мере, один скрытый слой, потому что простые и непростые числа не могут линейно разделяться в соответствии с их комбинациями битов.) В приведенном выше базовом примере размеры слоев составляют [20, 82025, 1].
Значения входных нейронов определяются входными данными. Как описано выше, это будут либо 0 и 1, соответствующие битам числа от 0 до 2 ^ 20, либо -1 и + 1 аналогичным образом.
Значения нейронов каждого последующего слоя, включая выходной слой, определяются из уровня заранее. Сначала применяется линейная функция, полностью связная или плотная . Одним из способов представления такой функции является использование матрицы весов . Например, переходы между первыми двумя слоями базовой линии могут быть представлены с помощью матрицы 82025 x 20. Количество весов - это количество записей в этой матрице, например, 1640500. Затем к каждой записи добавляется (отдельный) термин смещения. Это может быть представлено вектором, например, матрица 82025 x 1 в нашем случае. Количество смещений - это количество записей, например, 82025. (Обратите внимание, что веса и смещения вместе описывают аффинную линейную функцию .)
Вес или уклон учитываются, даже если он равен нулю. Для целей этого узкого определения смещения считаются весами, даже если все они равны нулю. Обратите внимание, что в базовом примере используются только два различных весовых коэффициента (+1 и -1) (и только немного более четкие смещения); тем не менее, размер составляет более миллиона, потому что повторение не помогает со счетом в любом случае.
Наконец, нелинейная функция, называемая функцией активации, применяется для каждого результата к этой аффинной линейной функции. Для целей этого узкого определения разрешенными функциями активации являются ReLU , tanh и sigmoid . Весь слой должен использовать одну и ту же функцию активации.
В базовом примере количество весов составляет 20 * 82025 + 82025 * 1 = 1722525, а количество смещений равно 82025 + 1 = 82026 для общего балла 1722525 + 82026 = 1804551. В качестве символического примера, если были еще один слой и размеры слоев были бы вместо [20, a, b, 1], тогда число весов было бы 20 * a + a * b + b * 1, а число смещений было бы a + b + 1.
Это определение нейронной сети хорошо поддерживается многими механизмами, включая Keras , scikit учиться и Tensorflow . Keras используется в базовом примере выше, с кодом, по существу, следующим:
from keras.models import Sequential
model = Sequential()
from keras.layers import Dense
model.add(Dense(units=82025, activation='relu', input_dim=20, weights=[weights1, biases1]))
model.add(Dense(units=1, activation='relu', weights=[weights2, biases2]))
score = numpy.size(weights1) + numpy.size(biases1) + numpy.size(weights2) + numpy.size(biases2)
Если матрицы весов и смещений являются массивами numpy , то numpy.size напрямую сообщит вам количество записей.
Существуют ли другие виды нейронных сетей?
Если вам нужно одно точное определение нейронной сети и оценки для этой задачи, используйте определение из предыдущего раздела. Если вы считаете, что «любая функция» при правильном подходе является нейронной сетью без параметров , используйте определение из предыдущего раздела.
Если вы более свободный дух, тогда я призываю вас исследовать дальше. Возможно, ваш ответ не будет учитываться в узкой задаче, но, возможно, вам будет веселее. Некоторые другие идеи, которые вы можете попробовать, включают более экзотические функции активации, рекуррентные нейронные сети (считывание по одному биту за раз), сверточные нейронные сети, более экзотические архитектуры, softmax и LSTM (!). Вы можете использовать любую стандартную функцию активации и любую стандартную архитектуру. Либеральное определение «стандартных» функций нейронной сети может включать в себя все, что опубликовано в архиве до публикации этого вопроса.
Ответы:
Пробное деление: оценка 59407, 6243 слоя, всего 16478 нейронов.
Данная программа на языке Python, которая генерирует и проверяет сеть. Смотрите комментарии
trial_division
для объяснения того, как это работает. Проверка выполняется довольно медленно (например, время выполнения измеряется в часах): я рекомендую использовать PyPy или Cython.Порог равен 1: все, что выше, является простым, все, что ниже, является составным или нулевым, и единственный вход, который дает выход 1, это сам 1.
Как в стороне, ре
источник
Оценка 984314, 82027 слоев, всего 246076 нейронов
Мы можем хранить вещи целиком в целых числах, если используем функцию активации ReLU, которая упрощает анализ.
Уровень 5: выходыAccum5= ( 221Accum3- ge5- ле5+ 1 )+ GE7= ( ge5- ( 7 - 5 ) )+ ле7= ( - ge5+ ( 7 - 5 ) )+
...
Уровень 82026: выходыAccum1048571= ( 221Accum1048559- ge1048571- ле1048571+ 1 )+ GE1048573= ( ge1048571- ( 1048573 - 1048571 ) )+ ле1048573= ( - ge1048571+ ( 1048573 - 1048571 ) )+
Оценка: (82026 - 3) * 12 + 21 + 4 + 9 + 4.
источник