Фон
Визнання первинності здається поганим пристосуванням для (штучних) нейронних мереж. Однак теорема про універсальне наближення стверджує, що нейронні мережі можуть наближати будь-яку безперервну функцію, тому, зокрема, слід мати можливість представляти будь-яку бажану функцію, що підтримується кінцево. Тож спробуємо розпізнати всі прими серед перших мільйонів чисел.
Точніше, оскільки це веб-сайт з програмування, давайте до 2 ^ 20 = 1,048,576. Кількість простих розмірів нижче цього порогу становить 82,025 або приблизно 8%.
Виклик
Наскільки мало нейронної мережі можна визначити, що правильно класифікує всі 20-бітні цілі числа як прості чи непрості?
Для цілей цієї задачі розмір нейронної мережі - це загальна кількість ваг і ухилів, необхідних для її представлення.
Деталі
Мета - мінімізувати розмір єдиної явної нейронної мережі.
Вхід до вашої мережі буде вектором довжиною 20, що містить окремі біти цілого числа, представлені або 0s і 1s, або альтернативно -1s і +s. Упорядкування цих може бути найзначнішим бітом першим або найменш значущим бітом першим.
Вихід вашої мережі повинен бути єдиним числом, таким чином, що над деяким відсіканням вхід розпізнається як простий, а нижче одного і того ж відсікання вхід розпізнається як не основний. Наприклад, позитивний може означати простий (а негативний не простий), або, альтернативно, більше 0,5 може означати простий (і менше 0,5 не простий).
Мережа повинна бути на 100% точною на всіх 2 ^ 20 = 1,048,576 можливих входів. Як було сказано вище, зауважте, що в цьому діапазоні є 82 025 прайменів. (Звідси випливає, що виведення завжди "не просто" було б 92% точним.)
З точки зору стандартної термінології нейронної мережі, це, ймовірно, можна назвати надмірним . Іншими словами, ваша мета полягає в тому, щоб ідеально подолати праймери. Інші слова, які можна використати, - це те, що «навчальний набір» і «тестовий набір» однакові.
Цей виклик не враховує кількість параметрів, що «навчаються» або «навчаються». Дійсно, ваша мережа, ймовірно, містить жорсткі ваги, і наведений нижче приклад є повністю жорстким. Натомість всі ваги та ухили вважаються параметрами та підраховуються.
Довжина коду, необхідного для тренування або генерування вашої нейронної мережі, не відповідає вашому результату, однак розміщення відповідного коду, безумовно, цінується.
Базова лінія
В якості базової лінії можна "запам'ятати" всі 82,025 прайметів з загальною вагою та зміщеннями 1804,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].
Значення вхідних нейронів визначаються на вході. Як описано вище, це будуть або 0s і 1s, відповідні бітам числа між 0 і 2 ^ 20, або -1s і + 1s аналогічно.
Значення нейронів кожного наступного шару, включаючи вихідний шар, попередньо визначають із шару. Спочатку застосовується лінійна функція, повністю пов'язана або щільна . Один із способів подання такої функції - використання матриці ваг . Наприклад, переходи між першими двома шарами базової лінії можуть бути представлені матрицею 82025 x 20. Кількість ваг - це кількість записів у цій матриці, наприклад 1640500. Тоді до кожного запису додається (окремий) термін зміщення. Це може бути представлено вектором, наприклад, матрицею 82025 x 1 у нашому випадку. Кількість ухилів - це кількість записів, наприклад, 82025. (Зверніть увагу, що ваги та ухили разом описують афінну лінійну функцію .)
Вага або ухил рахуються, навіть якщо вони дорівнюють нулю. Для цілей цього вузького визначення ухили вважають вагами, навіть якщо всі вони дорівнюють нулю. Зауважимо, що в базовому прикладі використовуються лише два чіткі ваги (+1 і -1) (і лише трохи більш чіткі відхилення); тим не менше, розмір становить понад мільйон, тому що повторення жодним чином не допомагає складати рахунок.
Нарешті, нелінійна функція, яка називається функцією активації , застосовується вхідним шляхом до результату цієї афінної лінійної функції. Для цілей цього вузького визначення, дозволені функції активації є РЕЛУ , гіперболічний тангенс і сигмовидної . Весь шар повинен використовувати одну і ту ж функцію активації.
У базовому прикладі кількість ваг становить 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 . Керас використовується в наведеному вище прикладі базового сценарію з кодом по суті наступним чином:
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.size безпосередньо повідомить вам кількість записів.
Чи існують інші види нейронних мереж?
Якщо ви хочете отримати єдине, точне визначення нейронної мережі та оцінка для цілей цього виклику, то будь ласка, використовуйте визначення в попередньому розділі. Якщо ви вважаєте, що "будь-яка функція" виглядала правильно, це нейронна мережа без параметрів , то будь ласка, використовуйте визначення в попередньому розділі.
Якщо ви більш вільний дух, то я закликаю вас далі досліджувати. Можливо, ваша відповідь не враховуватиме вузький виклик, але, можливо, вам буде веселіше. Деякі інші ідеї, які ви можете спробувати, включають більш екзотичні функції активації, періодичні нейронні мережі (читання по одному біту), звивисті нейронні мережі, більш екзотичні архітектури, софтмакс та LSTM (!). Ви можете використовувати будь-яку стандартну функцію активації та будь-яку стандартну архітектуру. Ліберальне визначення "стандартних" функцій нейронної мережі може включати будь-що, розміщене в арксиві до початку публікації цього питання.