Đang tiếp cận FizzBuzz
Tôi đang cố gắng ước tính hàm FizzBuzz khét tiếng:
def fizzbuzz(bắt đầu, kết thúc):
a = danh sách()
cho i trong phạm vi (bắt đầu, kết thúc + 1):
a.append(fb(i))
trả lại một
định nghĩa fb(i):
nếu tôi % 3 == 0 và tôi % 5 == 0:
quay lại "FizzBuzz"
Elif i% 3 == 0:
trả lại "Fizz"
Elif i% 5 == 0:
trả lại "Buzz"
khác:
trả lại tôi
Vấn đề là sau khi đào tạo, với tất cả các giá trị từ 1 đến 100, tôi chỉ nhận được các số làm đầu ra:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100]
Đầu ra đúng phải là:
['1' '2' 'Fizz' '4' 'Buzz' 'Fizz' '7' '8' 'Fizz' 'Buzz' '11' 'Fizz' '13'
'14' 'FizzBuzz' '16' '17' 'Fizz' '19' 'Buzz' 'Fizz' '22' '23' 'Fizz'
'Buzz' '26' 'Fizz' '28' '29' 'FizzBuzz' '31' '32' 'Fizz' '34' 'Buzz'
'Fizz' '37' '38' 'Fizz' 'Buzz' '41' 'Fizz' '43' '44' 'FizzBuzz' '46' '47'
'Fizz' '49' 'Buzz' 'Fizz' '52' '53' 'Fizz' 'Buzz' '56' 'Fizz' '58' '59'
'FizzBuzz' '61' '62' 'Fizz' '64' 'Buzz' 'Fizz' '67' '68' 'Fizz' 'Buzz'
'71' 'Fizz' '73' '74' 'FizzBuzz' '76' '77' 'Fizz' '79' 'Buzz' 'Fizz' '82'
'83' 'Fizz' 'Buzz' '86' 'Fizz' '88' '89' 'FizzBuzz' '91' '92' 'Fizz' '94'
'Buzz' 'Fizz' '97' '98' 'Fizz' 'Buzz']
Mạng lưới thần kinh của tôi phân loại mỗi số thành một trong bốn loại:
0. "Xì hơi"
1. "Tiếng vang"
2. "FizzBuzz"
3. Không có điều nào ở trên
Tôi nghĩ rằng mạng lưới thần kinh của tôi đang học cách phân loại từng số vào danh mục được gắn nhãn phổ biến nhất là danh mục chính xác (tức là # 3: không có danh mục nào ở trên) và tôi không biết cách giải quyết vấn đề này.
Chuẩn bị dữ liệu
Tôi mã hóa giá trị X (đầu vào) thành nhị phân 16 bit:
def nhị phân_encode_16b_array(a):
được mã hóa_a = danh sách()
cho phần tử trong a:
được mã hóa_a.append(binary_encode_16b(elem))
trả về np.array(encoded_a)
def nhị phân_encode_16b(val):
bin_arr = danh sách()
bin_str = định dạng(val, '016b')
cho bit trong bin_str:
bin_arr.append(bit)
trả về np.array(bin_arr)
Và mã hóa giá trị Y (đầu ra) thành một vectơ nóng:
def one_hot_encode_array(a):
được mã hóa_a = danh sách()
cho phần tử trong a:
được mã hóa_a.append(one_hot_encode(elem))
trả về np.array(encoded_a)
chắc chắn one_hot_encode(val):
nếu giá trị == 'Fizz':
trả về np.array([1, 0, 0, 0])
Elif giá trị == 'Buzz':
trả về np.array([0, 1, 0, 0])
elif val == 'FizzBuzz':
trả về np.array([0, 0, 1, 0])
khác:
trả về np.array([0, 0, 0, 1])
Điều này phân loại dữ liệu đầu vào nhị phân 16 bit thành một trong 4 loại có thể được chỉ định bởi quy tắc FizzBuzz.
Ví dụ, nếu bạn quay trở lại [0,03 -0,4 -0,4 0,4]
, chương trình sẽ không in bất kỳ "Fizz", "Buzz" hoặc "FizzBuzz" nào:
# giá trị giải mã của Y
def one_hot_decode_array(x, y):
giải mã_a = danh sách()
đối với chỉ mục, elem trong liệt kê (y):
giải mã_a.append(one_hot_decode(x[index], elem))
trả về np.array(decoded_a)
def one_hot_decode(x, val):
chỉ số = np.argmax(val)
nếu chỉ số == 0:
trả lại 'Fizz'
chỉ số Elif == 1:
trả lại 'Buzz'
chỉ số Elif == 2:
trả lại 'FizzBuzz'
chỉ số Elif == 3:
trả lại x
dữ liệu khởi tạo
Đây là cách tôi phân chia dữ liệu huấn luyện và kiểm tra:
# huấn luyện với dữ liệu sẽ không được kiểm tra
test_x_start = 1
test_x_end = 100
tàu_x_start = 101
tàu_x_end = 10000
test_x_raw = np.arange(test_x_start, test_x_end + 1)
test_x = nhị phân_encode_16b_array(test_x_raw).reshape([-1, 16])
test_y_raw = fizzbuzz(test_x_start, test_x_end)
test_y = one_hot_encode_array(test_y_raw)
train_x_raw = np.arange(train_x_start, train_x_end + 1)
train_x = nhị phân_encode_16b_array(train_x_raw).reshape([-1, 16])
train_y_raw = fizzbuzz(train_x_start, train_x_end)
train_y = one_hot_encode_array(train_y_raw)
Vì vậy, mô hình được huấn luyện bằng cách sử dụng các giá trị từ 101 đến 10000 và được kiểm tra bằng các giá trị từ 1 đến 100.
mô hình mạng lưới thần kinh
Kiến trúc mô hình của tôi rất đơn giản, với 100 nơ-ron ẩn trong một lớp:
#xác định thông số
đầu vào_dim = 16
đầu ra_dim = 4
h1_dim = 100
#xây dựng biểu đồ
X = tf.placeholder(tf.float32, [Không có, input_dim])
Y = tf.placeholder(tf.float32, [Không có, đầu ra_dim])
h1_w = tf.Variable(tf.zeros([input_dim, h1_dim]))
h1_b = tf.Variable(tf.zeros([h1_dim]))
h1_z = tf.nn.relu(tf.matmul(X, h1_w) + h1_b)
fc_w = tf.Variable(tf.zeros([h1_dim, out_dim]))
fc_b = tf.Variable(tf.zeros([output_dim]))
Z = tf.matmul(h1_z, fc_w) + fc_b
#xác định chi phí
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(nhãn=Y, logits=Z))
# xác định op
train_step = tf.train.AdamOptimizer(0,005).minimize(cross_entropy)
#xác định độ chính xác
Correct_prediction = tf.equal(tf.argmax(Z, 1), tf.argmax(Y, 1))
Correct_prediction = tf.cast(true_prediction, tf.float32)
độ chính xác = tf.reduce_mean(true_prediction)
Chạy mô hình
Để đơn giản, tôi đã chọn bỏ qua đào tạo theo đợt:
với tf.Session() là sess:
sess.run(tf.global_variables_initializer())
cho tôi trong phạm vi (1000):
sess.run(train_step, Feed_dict={X: train_x, Y: train_y})
train_accuracy = sess.run(độ chính xác, Feed_dict={X: train_x, Y: train_y})
print(i, ``, train_accuracy)
đầu ra = sess.run(Z, Feed_dict={X: test_x})
đã giải mã = one_hot_decode_array(test_x_raw, đầu ra)
in (đã giải mã)
Trong quá trình đào tạo, giá trị độ chính xác không vượt quá 0,533333
. Mạng được đào tạo để chỉ xuất số cho mỗi quy tắc !(i%3==0 || i%5==0) ?
, đây là câu trả lời phổ biến nhất cho hàm FizzBuzz.
CHỈNH SỬA: Đã giải quyết
Sử dụng giải pháp do @Blender cung cấp bên dưới, tôi đã thay đổi bộ khởi tạo của lớp ẩn và lớp đầu ra thành ngẫu nhiên thống nhất. Tăng số lần lặp và giảm tốc độ học của AdamOptimizer, mô hình của tôi hiện chạy hoàn hảo trên tập dữ liệu thử nghiệm. Tôi đã tải lên mã nguồn của mô hình hoạt động trong kho GitHub .
Tôi là một lập trình viên xuất sắc, rất giỏi!