Chúng tôi đã chứng minh rằng các mạng tuyến tính sâu—được triển khai bằng cách sử dụng số học dấu phẩy động—thực tế không phải là tuyến tính và có thể thực hiện tính toán phi tuyến tính. Chúng tôi đã sử dụng các chiến lược tiến hóa để tìm các tham số trong các mạng tuyến tính khai thác đặc điểm này, cho phép chúng tôi giải quyết các vấn đề không tầm thường.
Mạng nơ-ron bao gồm các chồng lớp tuyến tính theo sau là lớp phi tuyến tính như tanh hoặc đơn vị tuyến tính chỉnh lưu. Nếu không có lớp phi tuyến tính, về mặt lý thuyết, các lớp tuyến tính liên tiếp sẽ tương đương về mặt toán học với một lớp tuyến tính duy nhất. Vì vậy, thật bất ngờ khi số học dấu phẩy động lại phi tuyến tính đủ để tạo ra các mạng sâu có thể đào tạo được.
Lý lịch
Các số được máy tính sử dụng không phải là các đối tượng toán học hoàn hảo, mà là các biểu diễn gần đúng sử dụng số bit hữu hạn. Các số dấu phẩy động thường được máy tính sử dụng để biểu diễn các đối tượng toán học. Mỗi số dấu phẩy động được biểu diễn bằng sự kết hợp của một phân số và một số mũ. Trong tiêu chuẩn float32 của IEEE, 23 bit được sử dụng cho phân số và 8 bit cho số mũ, và một bit cho dấu.
Theo các quy ước này và định dạng nhị phân được sử dụng, số khác không bình thường nhỏ nhất (ở dạng nhị phân) là 1.0..0 x 2^-126 , mà chúng ta gọi là min từ nay về sau. Tuy nhiên, số có thể biểu diễn tiếp theo là 1.0..01 x 2^-126 , mà chúng ta có thể viết là min + 0.0..01 x 2^-126 . Rõ ràng là khoảng cách giữa số thứ 2 nhỏ hơn khoảng cách giữa 0 và min theo hệ số 2^20. Trong float32, khi các số nhỏ hơn số có thể biểu diễn nhỏ nhất, chúng sẽ được ánh xạ thành số không. Do 'tràn' này, xung quanh số không, mọi phép tính liên quan đến số dấu phẩy động đều trở nên phi tuyến tính.
Xem thêm: mua tài khoản ChatGPT Plus chính hãng giá rẻ
Một ngoại lệ cho những hạn chế này là số không bình thường, có thể bị vô hiệu hóa trên một số phần cứng máy tính. Trong khi GPU và cuBLAS có denormals được bật theo mặc định, TensorFlow xây dựng tất cả các nguyên hàm của nó với denormals tắt (với cờ ftz=true
được đặt). Điều này có nghĩa là bất kỳ phép nhân không phải ma trận nào được viết trong TensorFlow đều có tính phi tuyến tính ngầm định theo sau (với điều kiện là quy mô tính toán gần 1e-38).
Vì vậy, mặc dù nhìn chung sự khác biệt giữa bất kỳ số "toán học" nào và biểu diễn số thực thông thường của chúng là nhỏ, nhưng xung quanh số 0 lại có một khoảng cách lớn và lỗi xấp xỉ có thể rất đáng kể.
Điều này có thể dẫn đến một số hiệu ứng kỳ lạ khi các quy tắc toán học quen thuộc không còn áp dụng được nữa. Ví dụ, (Một+b)×c( Một+b )×ctrở nên không bằng một×c+b× c× c+b× c
Ví dụ nếu bạn thiết lập Một=0,4×tôiTôiN Một=0,4×phút, b=0,5×tôiTôiNb=0,5×phút, Và c=1/ tôiTôiNc=1/ phút.
Sau đó: (Một+b)×c=(0,4×tôiTôiN+0,5×tôiTôiN)×1/tôiTôiN=(0+0)×1/tôiTôiN=0( Một+b )×c=( 0,4×phút+0,5×phút )×1/ phút=( 0+0 )×1/ phút=0. Tuy nhiên: (Một×c)+(b×c)=0,4×tôiTôiN/tôiTôiN+0,5×tôiTôiN×1/tôiTôiN= 0,9( Một×c )+( b×c )=0,4×phút / phút+0,5×phút×1/ phút= 0,9.
Trong một ví dụ khác, chúng ta có thể thiết lập Một=2,5×tôiTôiNMột=2,5×phút, b=−1.6×tôiTôiNb=− 1,6×phút, Và c=1× tôiTôiN c=1× phút.
Sau đó: (Một+b)+c=(0)+1×tôiTôiN=tôiTôiN ( Một+b )+c=( 0 )+1×phút=phút. Tuy nhiên: (b+c)+Một=(0×tôiTôiN)+2,5×tôiTôiN=2,5× tôiTôiN( b+c )+Một=( 0×phút )+2,5×phút=2,5× phút.
Ở quy mô nhỏ nhất này, phép toán cộng cơ bản đã trở nên phi tuyến tính!
Khai thác tính phi tuyến tính với các chiến lược tiến hóa
Chúng tôi muốn biết liệu tính phi tuyến tính vốn có này có thể được khai thác như một tính phi tuyến tính tính toán hay không, vì điều này sẽ cho phép các mạng tuyến tính sâu thực hiện các phép tính phi tuyến tính. Thách thức là các thư viện phân biệt hiện đại không nhận ra các tính phi tuyến tính này ở quy mô nhỏ nhất. Do đó, sẽ rất khó hoặc không thể đào tạo một mạng nơ-ron để khai thác chúng thông qua truyền ngược.
Chúng ta có thể sử dụng các chiến lược tiến hóa (ES) để ước tính độ dốc mà không cần phải dựa vào phép phân biệt biểu tượng. Khi sử dụng ES, chúng ta thực sự có thể khai thác hành vi gần bằng không của float32 như một phi tuyến tính tính toán. Khi được đào tạo trên MNIST, một mạng tuyến tính sâu được đào tạo thông qua truyền ngược đạt được độ chính xác đào tạo là 94% và độ chính xác thử nghiệm là 92%. Ngược lại, cùng một mạng tuyến tính có thể đạt được độ chính xác đào tạo >99% và độ chính xác thử nghiệm là 96,7% khi được đào tạo bằng ES và đảm bảo rằng các kích hoạt đủ nhỏ để nằm trong phạm vi phi tuyến tính của float32. Sự gia tăng hiệu suất đào tạo này là do ES khai thác các phi tuyến tính trong biểu diễn float32. Các phi tuyến tính mạnh mẽ này cho phép bất kỳ lớp nào tạo ra các tính năng mới là các tổ hợp phi tuyến tính của các tính năng cấp thấp hơn. Sau đây là cấu trúc mạng:
12345678910111213141516171819
1
x = tf.placeholder(dtype=tf.float32, shape=[batch_size,784])
2
y = tf.placeholder(dtype=tf.float32, shape=[batch_size,10])
3
4
w1 = tf.Variable(np.random.normal(scale=np.sqrt(2./784),size=[784,512]).astype(np.float32))
5
b1 = tf.Variable(np.zeros(512,dtype=np.float32))
6
w2 = tf.Variable(np.random.normal(scale=np.sqrt(2./512),size=[512,512]).astype(np.float32))
7
b2 = tf.Variable(np.zeros(512,dtype=np.float32))
8
w3 = tf.Variable(np.random.normal(scale=np.sqrt(2./512),size=[512,10]).astype(np.float32))
9
b3 = tf.Variable(np.zeros(10,dtype=np.float32))
10
11
params = [w1,b1,w2,b2,w3,b3]
12
nr_params = sum([np.prod(p.get_shape().as_list()) for p in params])
13
scaling = 2**125
14
15
def get_logits(par):
16
h1 = tf.nn.bias_add(tf.matmul(x , par[0]), par[1]) / scaling
17
h2 = tf.nn.bias_add(tf.matmul(h1, par[2]) , par[3] / scaling)
18
o = tf.nn.bias_add(tf.matmul(h2, par[4]), par[5]/ scaling)*scaling
19
return o
Ngoài MNIST, chúng tôi nghĩ rằng các thí nghiệm thú vị khác có thể mở rộng công trình này sang mạng nơ-ron hồi quy hoặc khai thác tính toán phi tuyến tính để cải thiện các tác vụ học máy phức tạp như mô hình hóa ngôn ngữ và dịch thuật. Chúng tôi rất vui mừng được khám phá khả năng này với các nhà nghiên cứu đồng nghiệp của mình.
- Giải toán không khó với tài khoản ChatGPT 4