Convert two numbers to binary arrays
Also convert the result to a binary array
Two input and one output subtracters simulated by rnn
Where i is the binary array of two numbers, j is the array after subtraction, and k is the simulation result
i: [[0. 0. 1. 0. 0. 1. 0. 1.] [0. 0. 1. 0. 0. 0. 0. 0.]] j [0. 0. 0. 0. 0. 1. 0. 1.] k [0. 0. 0. 0. 0. 1. 0. 1.]
Of course, you can also simulate addition, pay attention to not exceed the limit of digits when generating array, of course, you can also take truncation
i: [[0. 1. 0. 1. 0. 1. 1. 0.] [0. 1. 0. 1. 0. 0. 0. 1.]] j [1. 0. 1. 0. 0. 1. 1. 1.] k [1. 0. 1. 0. 0. 1. 1. 1.]
Tune in
Building a simple network
rnn -- full -- output
Output the rnn output sequence after a layer of full connection
The relu function is used to prevent negative numbers in the result
The loss function uses simple sum of squares
Finally, np is used to round the result to the final prediction sequence
import tensorflow as tf import numpy as np import random # Turning numbers into binary np arrays def int2bin(x, num_len): x = bin(x)[2:].zfill(num_len) return np.array( list(map(lambda i: float(i), x)) ).reshape((1, 1, num_len)) # Get data, number of data groups and maximum number of digits def get_data(batch_size, num_len): # Maximum number of subtraction max_num = (1 << num_len) - 1 # Maximum number of addition # max_num = (1 << num_len - 1) - 1 x_data = [] y_data = [] for i in range(batch_size): a, b = random.randint(0, max_num), random.randint(0, max_num) a, b = max(a, b), min(a, b) # print(a, b) c = np.concatenate([int2bin(a, num_len), int2bin(b, num_len)], axis=1) x_data.append(c) y_data.append(int2bin(a - b, num_len)) x_data = np.concatenate(x_data) y_data = np.concatenate(y_data).reshape(batch_size, -1) return x_data, y_data # x, y = get_data(10, 8) # print(x.shape, y.shape) # (10, 2, 8) (10, 8) input_n = 8 output_n = 8 train_steps = 40000 show_steps = 500 batch_size = 32 hidden_size = 128 full_size = 64 time_step = 2 learning_rate = .01 x_in = tf.placeholder(tf.float32, (None, time_step, input_n)) y_in = tf.placeholder(tf.float32, (None, output_n)) print(x_in.shape, y_in.shape) # (?, 2, 8) (?, 8) weight = tf.Variable(tf.truncated_normal([full_size, output_n], stddev=.1)) biase = tf.Variable(tf.constant(.1, shape=[output_n])) # Building network lstm -- full -- relu # cell = tf.contrib.rnn.BasicLSTMCell(hidden_size) # outputs, final_state = tf.nn.dynamic_rnn(cell, x_in, dtype=tf.float32) # print(final_state[1].shape) # (?, 128) # full = tf.layers.dense(final_state[1], full_size) # print(full.shape) # (?, 64) # result = tf.matmul(full, weight) + biase # result = tf.nn.relu(result) # print(result.shape) # (?, 8) # Simple network, after rnn output, directly connected to a full connection output, relu prevents negative numbers cell = tf.contrib.rnn.BasicLSTMCell(hidden_size) outputs, final_state = tf.nn.dynamic_rnn(cell, x_in, dtype=tf.float32) print(final_state[1].shape) # (?, 128) result = tf.contrib.slim.fully_connected(final_state[1], input_n, activation_fn=tf.nn.relu) # loss and train loss = tf.reduce_mean((result - y_in) ** 2) train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for epoch in range(train_steps): x_data, y_data = get_data(batch_size, input_n) sess.run(train_op, feed_dict={ x_in: x_data, y_in: y_data, }) if not (epoch + 1) % show_steps: x_data, y_data = get_data(batch_size, input_n) loss__val, res = sess.run([loss, result], feed_dict={ x_in: x_data, y_in: y_data, }) print('epoch:', epoch + 1, 'loss:', loss__val) for i, j, k in zip(x_data[:4], y_data[:4], res[:4]): print('i:', i) print('j', j) print('k', np.rint(k)) print('k', k)
After seeing that the loss is small, the prediction result is still very accurate
epoch: 39500 loss: 0.00060202624 i: [[1. 1. 0. 1. 0. 0. 1. 1.] [1. 1. 0. 1. 0. 0. 0. 1.]] j [0. 0. 0. 0. 0. 0. 1. 0.] k [0. 0. 0. 0. 0. 0. 1. 0.] k [0. 0. 0. 0. 0. 0. 1.0148226 0. ] i: [[1. 1. 1. 1. 1. 1. 1. 0.] [1. 1. 0. 1. 0. 0. 0. 1.]] j [0. 0. 1. 0. 1. 1. 0. 1.] k [0. 0. 1. 0. 1. 1. 0. 1.] k [0. 0. 1.0292125 0. 1.0081979 1.0195892 0. 1.0046306] i: [[1. 1. 0. 0. 1. 0. 0. 1.] [1. 0. 1. 0. 0. 0. 1. 1.]] j [0. 0. 1. 0. 0. 1. 1. 0.] k [0. 0. 1. 0. 0. 1. 1. 0.] k [0. 0. 1.0501771 0. 0. 1.0002633 0.98572767 0. ] i: [[1. 0. 1. 0. 1. 1. 0. 0.] [0. 1. 1. 0. 0. 0. 1. 0.]] j [0. 1. 0. 0. 1. 0. 1. 0.] k [0. 1. 0. 0. 1. 0. 1. 0.] k [0. 1.0481278 0. 0. 0.99072963 0. 0.99771726 0. ] epoch: 40000 loss: 0.00059128506 i: [[1. 1. 1. 1. 1. 0. 1. 0.] [0. 1. 1. 0. 0. 1. 0. 1.]] j [1. 0. 0. 1. 0. 1. 0. 1.] k [1. 0. 0. 1. 0. 1. 0. 1.] k [0.999081 0. 0. 1.0134556 0. 0.996073 0. 1.0186146] i: [[1. 0. 0. 1. 0. 1. 0. 1.] [0. 1. 1. 1. 0. 0. 1. 1.]] j [0. 0. 1. 0. 0. 0. 1. 0.] k [0. 0. 1. 0. 0. 0. 1. 0.] k [0. 0. 1.0294001 0. 0. 0. 1.0243944 0. ] i: [[1. 1. 1. 0. 0. 0. 1. 0.] [1. 1. 0. 1. 0. 1. 1. 0.]] j [0. 0. 0. 0. 1. 1. 0. 0.] k [0. 0. 0. 0. 1. 1. 0. 0.] k [0. 0. 0. 0. 0.99334943 1.0034381 0. 0. ] i: [[1. 0. 1. 0. 0. 0. 0. 0.] [1. 0. 0. 1. 1. 0. 1. 1.]] j [0. 0. 0. 0. 0. 1. 0. 1.] k [0. 0. 0. 0. 0. 1. 0. 1.] k [0. 0. 0. 0. 0. 0.98055166 0. 0.99823564]