เครือข่ายประสาทสามารถรับรู้เฉพาะช่วงเวลาได้หรือไม่?


26

พื้นหลัง

การตระหนักถึงความเป็นดั้งเดิมดูเหมือนว่าจะเหมาะสมสำหรับเครือข่ายประสาทเทียม อย่างไรก็ตามทฤษฎีบทการประมาณสากลระบุว่าเครือข่ายประสาทสามารถประมาณฟังก์ชันต่อเนื่องใด ๆ ดังนั้นโดยเฉพาะอย่างยิ่งมันควรจะเป็นไปได้ที่จะเป็นตัวแทนของฟังก์ชั่นการสนับสนุนที่มีขอบเขตอย่างใดอย่างหนึ่งปรารถนา งั้นลองพยายามจดจำช่วงเวลาทั้งหมดในจำนวนล้านแรก

แม่นยำยิ่งขึ้นเพราะนี่คือเว็บไซต์การเขียนโปรแกรมเราไปถึง 2 ^ 20 = 1,048,576 จำนวนช่วงเวลาที่ต่ำกว่าเกณฑ์นี้คือ 82,025 หรือประมาณ 8%

ท้าทาย

คุณจะพบว่าเครือข่ายประสาทมีขนาดเล็กเพียงใดซึ่งจำแนกประเภทจำนวนเต็ม 20 บิตทั้งหมดให้เป็นไพร์มหรือไม่ไพร์มได้อย่างถูกต้อง?

สำหรับวัตถุประสงค์ของการท้าทายนี้ขนาดของโครงข่ายประสาทเทียมคือจำนวนน้ำหนักและอคติทั้งหมดที่ต้องใช้ในการเป็นตัวแทน

รายละเอียด

เป้าหมายคือเพื่อลดขนาดของเครือข่ายประสาทเดี่ยวที่ชัดเจน

อินพุตไปยังเครือข่ายของคุณจะเป็นเวกเตอร์ที่มีความยาว 20 ซึ่งประกอบด้วยบิตแต่ละส่วนของจำนวนเต็มซึ่งแสดงด้วย 0s และ 1s หรืออีกทางเลือกด้วย -1s และ + 1s การเรียงลำดับเหล่านี้อาจเป็นบิตที่มีนัยสำคัญมากที่สุดก่อนหรือมีนัยสำคัญน้อยที่สุดก่อน

ผลลัพธ์ของเครือข่ายของคุณควรเป็นตัวเลขเดียวเช่นที่ด้านบนบางส่วนของการตัดออกที่ได้รับการยอมรับว่าดีที่สุดและต่ำกว่าการตัดสัญญาณเดียวกันที่ได้รับการยอมรับว่าไม่สำคัญ ตัวอย่างเช่นค่าบวกอาจหมายถึงค่านายก (และค่าลบไม่ถึงค่านายก) หรืออีกทางเลือกหนึ่งที่มากกว่า 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."

เครือข่ายประสาทคืออะไร

สำหรับความท้าทายนี้เราสามารถเขียนคำจำกัดความที่แคบ แต่แม่นยำของเครือข่ายประสาทเทียม สำหรับบางคนอ่านภายนอกผมขอแนะนำให้วิกิพีเดียในเครือข่ายประสาทเทียม , เครือข่ายประสาท feedforward , หลายตรอนและฟังก์ชั่นการเปิดใช้งานฟังก์ชั่นการเปิดใช้งาน

เครือข่ายประสาท feedforwardคือชุดของชั้นของเซลล์ประสาท จำนวนเซลล์ประสาทต่อชั้นแตกต่างกันไปด้วย 20 เซลล์ประสาทในชั้นข้อมูลเข้าจำนวนเซลล์ประสาทจำนวนหนึ่งในชั้นที่ซ่อนอยู่อย่างน้อยหนึ่งชั้นและ 1 เซลล์ประสาทในชั้นเอาท์พุท (ต้องมีอย่างน้อยหนึ่งเลเยอร์ที่ซ่อนอยู่เนื่องจากช่วงเวลาและช่วงเวลาไม่แยกเป็นเส้นตรงตามรูปแบบบิตของพวกเขา) ในตัวอย่างพื้นฐานด้านบนขนาดของชั้นคือ [20, 82025, 1]

ค่าของเซลล์ประสาทอินพุตจะถูกกำหนดโดยอินพุต ตามที่อธิบายไว้ข้างต้นสิ่งนี้จะเป็น 0 และ 1 ซึ่งสอดคล้องกับบิตของตัวเลขระหว่าง 0 และ 2 ^ 20, หรือ -1s และ + 1s ในทำนองเดียวกัน

ค่าของเซลล์ประสาทของแต่ละเลเยอร์ต่อไปนี้รวมถึงเลเยอร์เอาท์พุทจะถูกกำหนดจากเลเยอร์ก่อน ครั้งแรกที่ฟังก์ชั่นเชิงเส้นจะถูกนำไปใช้ในการอย่างเต็มที่ที่เชื่อมต่อหรือหนาแน่นแฟชั่น วิธีหนึ่งในการแสดงฟังก์ชั่นดังกล่าวคือการใช้เมทริกซ์น้ำหนัก ตัวอย่างเช่นการเปลี่ยนระหว่างสองชั้นแรกของพื้นฐานสามารถแสดงด้วยเมทริกซ์ 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 และจำนวนอคติจะเป็น + 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 (!) คุณสามารถใช้ฟังก์ชั่นการเปิดใช้งานมาตรฐานและสถาปัตยกรรมมาตรฐานใด ๆ นิยามเสรีของคุณสมบัติเครือข่ายประสาท "มาตรฐาน" อาจรวมถึงสิ่งที่โพสต์บน arxiv ก่อนที่จะโพสต์คำถามนี้


น้ำหนักเหล่านี้เป็นประเภทใด โดยทั่วไปแล้วคนเราใช้ Floats เราสามารถใช้ชนิดตัวเลขอื่น ๆ ได้หรือไม่ เช่นประเภทของความแม่นยำน้อยกว่ามากหรือไม่ จำกัด
ข้าวสาลี Wizard

@ SriotchilismO'Zaic: สำหรับจุดประสงค์ของคำจำกัดความแคบ ๆ ฉันคิดว่ามันสมเหตุสมผลที่จะ จำกัด การลอยตัวและดับเบิล (IEEE ตัวเลขจริงและความแม่นยำสองเท่าของทศนิยม) สำหรับน้ำหนักและค่ากลางทั้งหมด (ถึงแม้จะทราบว่าการใช้งานบางอย่างอาจจะใช้จำนวนเงินอื่นของความแม่นยำ - เช่น 80 บิต -. ระหว่างการประเมิน)
เอเร็กซ์

ฉันรักคำถามนี้ แต่ผิดหวังที่ไม่มีเครือข่ายประสาทที่เล็กกว่ามากในการหาเวลาฝึกฝนเพียงพอ
Anush

คำตอบ:


13

ส่วนทดลอง: คะแนน 59407, 6243 ชั้น, 16478 เซลล์ประสาทรวม

รับเป็นโปรแกรม Python ที่สร้างและตรวจสอบความถูกต้องของเน็ต ดูความคิดเห็นในtrial_divisionสำหรับคำอธิบายวิธีการทำงาน การตรวจสอบค่อนข้างช้า (เหมือนใน, เวลาทำงานวัดเป็นชั่วโมง): ฉันแนะนำให้ใช้ PyPy หรือ Cython

αmax(0,α) ) เป็นฟังก์ชั่นการเปิดใช้งาน

ธรณีประตูคือ 1: ทุกอย่างที่อยู่เหนือกว่าไพรม์อะไรก็ตามด้านล่างประกอบหรือเป็นศูนย์และมีเพียงอินพุตเดียวที่ให้เอาต์พุต 1 คือ 1 เอง

#!/usr/bin/python3

import math


def primes_to(n):
    ps = []
    for i in range(2, n):
        is_composite = False
        for p in ps:
            if i % p == 0:
                is_composite = True
                break
            if p * p > i:
                break
        if not is_composite:
            ps.append(i)
    return ps


def eval_net(net, inputs):
    for layer in net:
        inputs.append(1)
        n = len(inputs)
        inputs = [max(0, sum(inputs[i] * neuron[i] for i in range(n))) for neuron in layer]
    return inputs


def cost(net):
    return sum(len(layer) * len(layer[0]) for layer in net)


def trial_division(num_bits):
    # Overview: we convert the bits to a single number x and perform trial division.
    # x is also our "is prime" flag: whenever we prove that x is composite, we clear it to 0
    # At the end x will be non-zero only if it's a unit or a prime, and greater than 1 only if it's a prime.
    # We calculate x % p as
    #     rem = x - (x >= (p << a) ? 1 : 0) * (p << a)
    #     rem -= (rem >= (p << (a-1)) ? 1) : 0) * (p << (a-1))
    #     ...
    #     rem -= (rem >= p ? 1 : 0) * p
    #
    # If x % p == 0 and x > p then x is a composite multiple of p and we want to set it to 0

    N = 1 << num_bits
    primes = primes_to(1 + int(2.0 ** (num_bits / 2)))

    # As a micro-optimisation we exploit 2 == -1 (mod 3) to skip a number of shifts for p=3.
    # We need to bias by a multiple of 3 which is at least num_bits // 2 so that we don't get a negative intermediate value.
    bias3 = num_bits // 2
    bias3 += (3 - (bias3 % 3)) % 3

    # inputs: [bit0, ..., bit19]
    yield [[1 << i for i in range(num_bits)] + [0],
           [-1] + [0] * (num_bits - 1) + [1],
           [0] * 2 + [-1] * (num_bits - 2) + [1],
           [(-1) ** i for i in range(num_bits)] + [bias3]]

    for p in primes[1:]:
        # As a keyhole optimisation we overlap the cases slightly.
        if p == 3:
            # [x, x_is_even, x_lt_4, x_reduced_mod_3]
            max_shift = int(math.log((bias3 + (num_bits + 1) // 2) // p, 2))
            yield [[1, 0, 0, 0, 0], [0, 1, -1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, -1, p << max_shift]]
            yield [[1, -N, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, -1, 1]]
            yield [[1, 0, 0, 0], [0, 1, -p << max_shift, 0]]
        else:
            # [x, x % old_p]
            max_shift = int(num_bits - math.log(p, 2))
            yield [[1, 0, 0], [1, -N, -p_old], [-1, 0, p << max_shift]]
            yield [[1, -N, 0, 0], [0, 0, -1, 1]]
            yield [[1, 0, 0], [1, -p << max_shift, 0]]

        for shift in range(max_shift - 1, -1, -1):
            # [x, rem]
            yield [[1, 0, 0], [0, 1, 0], [0, -1, p << shift]]
            yield [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 1]]
            yield [[1, 0, 0, 0], [0, 1, -p << shift, 0]]
        # [x, x % p]
        p_old = p

    yield [[1, 0, 0], [1, -N, -p]]
    yield [[1, -N, 0]]


def validate_primality_tester(primality_tester, threshold):
    num_bits = len(primality_tester[0][0]) - 1
    primes = set(primes_to(1 << num_bits))
    errors = 0
    for i in range(1 << num_bits):
        expected = i in primes
        observed = eval_net(primality_tester, [(i >> shift) & 1 for shift in range(num_bits)])[-1] > threshold
        if expected != observed:
            errors += 1
            print("Failed test case", i)
        if (i & 0xff) == 0:
            print("Progress", i)

    if errors > 0:
        raise Exception("Failed " + str(errors) + " test case(s)")


if __name__ == "__main__":
    n = 20

    trial_div = list(trial_division(n))
    print("Cost", cost(trial_div))
    validate_primality_tester(trial_div, 1)

เป็นอีกครั้ง

ทฤษฎีบทประมาณสากลระบุว่าเครือข่ายประสาทสามารถประมาณฟังก์ชันใด ๆ ที่ต่อเนื่อง

max(0,1ai)max(0,1+(ai1))แต่ทำงานได้อย่างถูกต้องหากอินพุตของมันรับประกันว่าจะเป็น 0 หรือ 1 และอาจส่งออกจำนวนเต็มขนาดใหญ่กว่า ประตูอื่น ๆ ที่หลากหลายเป็นไปได้ในชั้นเดียว แต่ NOR โดยตัวของมันเองนั้นเป็นทัวริงที่สมบูรณ์ดังนั้นจึงไม่จำเป็นต้องพูดถึงรายละเอียด


นอกจากนี้ฉันเริ่มทำงานกับการทดสอบของออยเลอร์ก่อนที่ฉันจะลองหารทดลองเพราะฉันคิดว่ามันจะมีประสิทธิภาพมากขึ้น แต่การเพิ่มจำนวน (7 เป็นผู้สมัครที่ดีที่สุด) ถึงพลังของ (x- (x mod 2) ) จะต้องมี 38 การคูณตามด้วยการลด mod x และเครือข่ายที่ดีที่สุดที่ฉันพบสำหรับการคูณตัวเลข 20 บิตมีค่าใช้จ่าย 1,135 ดังนั้นจึงไม่สามารถแข่งขันได้
Peter Taylor

7

คะแนน 984314, 82027 เลเยอร์, ​​246076 เซลล์ประสาทรวม

เราสามารถเก็บทุกอย่างไว้ในจำนวนเต็มถ้าเราใช้ฟังก์ชั่นการเปิดใช้งาน ReLU ซึ่งทำให้การวิเคราะห์ง่ายขึ้น

xx=a

  1. GEa=(x-a)+lea=(-x+a)+
  2. อีคิวa=(-GEa-lea+1)+อีคิวa1x=a0

x

GE2=(x-2)+le2=(-x+2)+ +ราคา (1 + 1) * 2 = 4

accum2=(-GE2-le2+1)+GE3=(GE2-(3-2))+le3=(-GE2+(3-2))+

accum3=(221accum2-GE3-le3+1)+GE5=(GE3-(5-3))+le5=(-GE3+(5-3))+ . ราคา (3 + 1) * 3 = 12

accum5=(221accum3-GE5-le5+1)+, GE7=(GE5-(7-5))+, le7=(-GE5+(7-5))+. ราคา (3 + 1) * 3 = 12

...

ชั้น 82026: เอาท์พุท accum1048571=(221accum1048559-GE1048571-le1048571+1)+, GE1048573=(GE1048571-(1048573-1048571))+, le1048573=(-GE1048571+(1048573-1048571))+. ราคา (3 + 1) * 3 = 12

ชั้น 82027: เอาท์พุท accum1048573=(221accum1048571-GE1048573-le1048573+1)+. ราคา (3 + 1) * 1 = 4

ขีด จำกัด คือ 0 หากทำงานกับคู่เป็นมากเกิน + ค่อนข้างเป็นไปได้ แต่ดูเหมือนว่าจะเป็นไปตามกฎอย่างสมบูรณ์แบบ

คะแนนคือ (82026 - 3) * 12 + 21 + 4 + 9 + 4


เย็น. ดังที่ฉันเข้าใจแล้วสิ่งนี้ยัง "จดจำ" ช่วงเวลาเฉพาะ แต่เป็นการทดสอบเพื่อความเท่าเทียม "เรียงตามลำดับ" แทนที่จะเป็น "ขนาน" (อีกวิธีหนึ่งก็เหมือนกับทรานซิชั่นพื้นฐาน) ขั้นตอนแรกคือการย้ายออกจากรูปแบบบิตทันทีและทำงานร่วมกับจำนวนเต็มจริง ดังนั้นจึงไม่มีโทษ 20 เท่าในการตรวจสอบความเท่าเทียมกัน ขอบคุณสำหรับการส่งของคุณ
A. Rex

ตัวยกบวกคืออะไร
feersum

1
@feersum นั่นเป็นสัญกรณ์จากหน้า Wikipedia บน ReLU ที่เชื่อมโยงกับคำถาม x+=สูงสุด(0,x)
Peter Taylor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.