Проблемът
OpenAI наскоро публикува някои отворени изследователски въпроси. Като начинаещ в AI реших да се справя с „Warmups“ за начинаещи, които те предлагат. Можете да видите техния блог пост тук: https://blog.openai.com/requests-for-research-2/:
Обучете LSTM за решаване на проблема с XOR: тоест, дадена последователност от битове, определете нейния паритет. LSTM трябва да използва последователността, един бит наведнъж, и след това да изведе правилния отговор в края на последователността. Тествайте двата подхода по-долу:
- Генерирайте набор от данни от произволни 100 000 двоични низа с дължина 50. Обучете LSTM; какво представяне получаваш?
- Генерирайте набор от данни от произволни 100 000 двоични низа, където дължината на всеки низ е независимо и произволно избрана между 1 и 50. Обучете LSTM. Успява ли? Какво обяснява разликата?
Функцията XOR
| Вход | Вход 2 | Изход |
| — — — — — — — |: — — — — — — -:| — — -:|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Проблем 1: 100 000 двоични низа с дължина 50
Кодът за решаване на този проблем е благодарение на [christopher5106](https://github.com/christopher5106/grid-1D-LSTM-theano/blob/master/main.py)
Настройвам
python ‘’’ Trains a 1D Grid LSTM network to learn XOR answers. ‘’’ from __future__ import print_function import numpy as np import theano import theano.tensor as T import lasagne #Lasagne Seed for Reproducibility lasagne.random.set_rng(np.random.RandomState(1)) import argparse parser = argparse.ArgumentParser() parser.add_argument(‘ — iterations’, type=int, default=100000, help=’Number of iterations’) parser.add_argument(‘ — bits’, type=int, default=50, help=’Number of bits in the input strings’) parser.add_argument(‘ — hidden’, type=int, default=2, help=’Number of units in the two hidden (LSTM) layers’) parser.add_argument(‘ — learning_rate’, type=float, default=0.5, help=’Optimization learning rate’) #parser.add_argument(‘ — grad_clip’, type=int, default=100, help=’All gradients above this will be clipped’) parser.add_argument(‘ — print_freq’, type=int, default=500, help=’How often should we check the output?’) parser.add_argument(‘ — batch_size’, type=int, default=1, help=’Batch size’) parser.add_argument(‘ — layers’, type=int, default=2, help=’Number of layers’) args = parser.parse_args() print(“Parameters:”) print(args) args.print_batch_freq = args.print_freq / args.batch_size + 1
Генератор на произволни низове
python def gen_data(bits=args.bits, batch_size = args.batch_size): x = np.random.randint(2, size=(batch_size,bits)) y = x.sum(axis=1) % 2 return x, y ``` # Network ```python print(“Building network …”) l_in = lasagne.layers.InputLayer(shape=(None,1)) l_in_zero = lasagne.layers.InputLayer(shape=(None, args.layers, 1)) l_lin = lasagne.layers.DenseLayer(l_in, num_units = args.hidden, nonlinearity = None) l_forward = lasagne.layers.LSTMLayer( l_in_zero, args.hidden, nonlinearity=lasagne.nonlinearities.tanh, hid_init = l_lin, only_return_final=True) l_lin_out = lasagne.layers.DenseLayer(l_forward, num_units = 2, nonlinearity = None) l_out = lasagne.layers.DenseLayer(l_lin_out, num_units=2, nonlinearity=lasagne.nonlinearities.softmax) target_values = T.ivector(‘target_output’) network_output = lasagne.layers.get_output(l_out) cost = T.nnet.categorical_crossentropy(network_output,target_values).mean() accuracy = lasagne.objectives.categorical_accuracy(network_output,target_values).mean() all_params = lasagne.layers.get_all_params(l_out,trainable=True) all_params2 = lasagne.layers.get_all_params(l_out,trainable=False)
Теано функции
python print(“Computing updates …”) updates = lasagne.updates.adadelta(cost, all_params, args.learning_rate) updates2 = lasagne.updates.adagrad(cost, all_params2, args.learning_rate) print(“Compiling functions …”) train = theano.function([l_in.input_var, l_in_zero.input_var, target_values], cost, updates=updates, allow_input_downcast=True) train2 = theano.function([l_in.input_var, l_in_zero.input_var, target_values], cost, updates=updates2, allow_input_downcast=True) compute_cost = theano.function([l_in.input_var, l_in_zero.input_var, target_values], cost, allow_input_downcast=True) compute_accuracy = theano.function([l_in.input_var, l_in_zero.input_var, target_values], accuracy, allow_input_downcast=True) probs = theano.function([l_in.input_var, l_in_zero.input_var],network_output,allow_input_downcast=True)
обучение
python print(“Training …”) print(“The average loss and accuracy will be printed every {} iterations”.format(args.print_batch_freq*args.batch_size)) num_batch_print_iter = args.iterations / args.batch_size / args.print_batch_freq + 1 act_num_batches = int(num_batch_print_iter * args.print_batch_freq) all_cost = np.zeros((act_num_batches)) all_accuracy = np.zeros((act_num_batches)) for it_out in range(int(num_batch_print_iter)): for it_in in range(int(args.print_batch_freq)): x,y = gen_data() stoplen = (len(x[0])-1) for i in range(0,stoplen): x_zero = np.zeros((args.batch_size,args.layers,1),dtype=’int32') batch_cost = train2(np.reshape(x[0][i], newshape=(1,1)), x_zero, y) x_zero = np.zeros((args.batch_size, args.layers, 1), dtype=’int32') batch_iter = int(it_out * args.print_batch_freq + it_in + 1) batch_cost = train(np.reshape(x[0][len(x[0])-1], newshape=(1,1)), x_zero, y) batch_accuracy = compute_accuracy(np.reshape(x[0][len(x[0])-1], newshape=(1,1)), x_zero, y) all_cost[batch_iter — 1] = batch_cost all_accuracy[batch_iter — 1] = batch_accuracy start_index = int(it_out * args.print_batch_freq) end_index = int((it_out + 1) * args.print_batch_freq) av_cost = all_cost[start_index:end_index].mean() av_accuracy = all_accuracy[start_index:end_index].mean() np.savetxt(‘cost.txt’, all_cost[:end_index], delimiter=’,’) #average in batch np.savetxt(‘accuracy.txt’, all_accuracy[:end_index], delimiter=’,’) print(“Iteration {} average loss = {} average accuracy = {}”.format(batch_iter*args.batch_size, av_cost,av_accuracy))
Проблем 2: 100 000 двоични низа с произволна дължина 1:50
Кодови разлики
```python parser.add_argument(‘ — hidden’, type=int, default=100, help=’Number of units in the two hidden (LSTM) layers’) parser.add_argument(‘ — layers’, type=int, default=2, help=’Number of layers’) args = parser.parse_args() ``` ```python def gen_data(bits=args.bits, batch_size = args.batch_size): bitsran = np.random.randint(1, bits) x = np.random.randint(2, size=(batch_size,bitsran)) y = x.sum(axis=1) % 2 return x, y ```