[PYTHON] Chaos retour de la cartographie logistique par Petit RNN dans Tensorflow

Réseau neuronal récurrent

Pour les données qui semblent être corrélées avec des valeurs continues telles que les données de séries chronologiques, RNN qui traite les entrées une par une, conserve les valeurs d'état à l'intérieur du réseau et sort la sortie finale une fois toutes les entrées terminées. M.

Les données de séries temporelles du monde réel sont trop bruyantes et les données basées sur le langage telles que les didacticiels de Tensorflow sont difficiles à imaginer comme des «séries chronologiques». Et je ne peux pas saisir les spécifications de la classe RNNCell, alors je vais abandonner et créer un modèle d'auto-rétroaction expérimentalement simple.

Cible de vérification: dynamique du chaos

Le chaos est célèbre pour son effet papillon, mais il semble aléatoire à première vue, mais il est en fait utile pour analyser des événements qui ont quelque chose comme une certaine loi.

J'utiliserai la carte logistique, qui est la plus simple à comprendre personnellement, comme exemple.

Equation logistique discrète

Il y a une formule ultra-simple ci-dessous qui permet à la valeur de $ x (t) $ à un instant $ t $ d'être dérivée de la valeur du moment précédent $ x (t-1) $ et du paramètre unique $ r $.

x_t = rx_{t-1}(1-x_{t-1})

Ou si vous voulez prédire le prochain point dans le temps, ce sera comme ça.

x_{t+1} = rx_t(1-x_t)

$ x $ est 0 ≤ x ≤ 1 $ r $ est 0 ≤ r ≤ 4

Quelque part dans ce chaos, cette formule a une énorme augmentation de la valeur que $ x $ peut prendre d'environ «3,6».

Si vous regardez $ x $ comme des données de séries chronologiques, c'est un merveilleux nombre aléatoire. Si vous le comparez à une valeur complètement aléatoire dans l'ordre chronologique, vous ne connaîtrez la différence que si vous dites quoi que ce soit.

Le grand avantage du chaos est que si vous dispersez $ x_t $ et $ x_ {t + 1} $, vous obtiendrez des formes sympas (fractales). La différence est claire même par rapport à la valeur aléatoire. Il semble commencer à partir de $ r $. Ah magnifique.

Prédiction à court terme de la dynamique du chaos

Eh bien, c'est un si beau chaos, mais même si cela semble aléatoire, il semble facile de prédire si vous suivez les règles. Cependant, c'est fou. C'est la raison pour laquelle le chaos est le chaos, mais il est difficile de prédire des données continues car même une légère différence dans les valeurs initiales et les paramètres entraînera des valeurs complètement différentes.

Comparons-le de manière appropriée.

generator.py


           
def logistic(r, t_first, num_steps):
  array = []                        
  for i in range(num_steps):        
    if "t" not in locals():         
      t = t_first                   
    else:                           
      t = tt                        
    tt = r*t*(1-t)                  
                                    
    array.append(tt)                
  return array                      

initial = 0.5
data1 = logistic(3.91, initial, 100)
data2 = logistic(3.9100000000001, initial, 100)
data3 = logistic(3.91, initial+0.0000001, 100)

Même si l'erreur de la valeur estimée est une précision ultra-élevée de 1e à 10% ou moins, il sera difficile de prédire à 60 destinations de données.

** Inversement, si vous retournez chercher $ r $, vous pouvez faire des prédictions à court terme. ** **

logistic_rnn.py


import os, sys
import numpy as np
import tensorflow as tf

num_steps = 1 # Number of inputs. logistic map only needs a current input
batch_size = 100
epoch_size = 10000
initial = 0.5  # 0 <= x <= 1: to generate data

L = 0.01 # learing rate
PRE_STEPS = 30 # Number of predictions. how far do you want to predict?
N_HIDDEN = 30 # Hidden nodes


'''
generate data
'''
def logistic(r, t_first, num_steps):
	array = []
	for i in range(num_steps):
		if "t" not in locals():
			t = t_first
		else:
			t = tt
		tt = r*t*(1-t)
		
		array.append(tt)
	return array

def logmap_iterator(raw_data, batch_size, num_steps, prediction_steps):
	raw_data = np.array(raw_data)
	data_len = len(raw_data)
	batch_len = data_len // batch_size
	data = np.zeros([batch_size, batch_len])
	for i in range(batch_size):
		data[i] = raw_data[batch_len * i:batch_len * (i + 1)]

	epoch_size = (batch_len - 1) // num_steps
	if epoch_size == 0:
		raise ValueError("epoch_size == 0, decrease batch_size or num_steps")
	for i in range(epoch_size):
		x = data[:, i*num_steps:(i+1)*num_steps]
		y = data[:, (i+1)*num_steps:(i+1)*num_steps+(prediction_steps)]

		yield(x, y)

raw_data = logistic(3.91, initial, num_steps*batch_size*epoch_size)

'''
mini-RNN Model
'''
x = tf.placeholder("float", [None, num_steps])
y = tf.placeholder("float", [None, PRE_STEPS])

weights = {
  	        'hidden': tf.get_variable("hidden", shape=[1, N_HIDDEN], initializer=tf.truncated_normal_initializer(stddev=0.1)),
	        'out': tf.get_variable("out", shape=[N_HIDDEN, 1],  initializer=tf.truncated_normal_initializer(stddev=0.1))
}
biases = {
  	        'hidden': tf.get_variable("b_hidden", shape=[N_HIDDEN], initializer=tf.truncated_normal_initializer(stddev=0.1)),
  	        'out': tf.get_variable("b_out", shape=[1],  initializer=tf.truncated_normal_initializer(stddev=0.1))
}
	
def simple_reg(x, _weights, _biases, K = 1.0):
	with tf.variable_scope("weight"):
		h1 = tf.matmul(x, _weights['hidden']) + _biases['hidden'] 
		h1 = tf.nn.dropout(tf.nn.sigmoid(h1), K)
		o1 = tf.matmul(h1, _weights['out']) + _biases['out']

	with tf.variable_scope("weight", reuse=True):
		h2 = tf.matmul(o1, _weights['hidden']) + _biases['hidden'] 
		h2 = tf.nn.dropout(tf.nn.sigmoid(h2), K)
		o2 = tf.matmul(h2, _weights['out']) + _biases['out'] 

	o = tf.concat(1, [o1, o2])

	def more_step(predicted_value, o):
		with tf.variable_scope("weight", reuse=True):
			h = tf.matmul(predicted_value, _weights['hidden']) + _biases['hidden'] 
			h = tf.nn.dropout(tf.nn.sigmoid(h), K)
			o_v = tf.matmul(h, _weights['out']) + _biases['out'] 
		o = tf.concat(1, [o, o_v])
		return o, o_v
	
	for i in range(PRE_STEPS-2):
		if "o_v" not in locals():
			o, o_v = more_step(o2, o)
		else:
			print o_v
			o, o_v = more_step(o_v, o)
	return o, o1

o, o1 = simple_reg(x, weights, biases)
z = tf.split(1, PRE_STEPS, y) 
z = z[0]

cost = tf.reduce_sum(tf.square(o1 - z))
optimizer = tf.train.AdamOptimizer(L).minimize(cost)

init = tf.initialize_all_variables()

with tf.Session() as sess:
	saver = tf.train.Saver()
	sess.run(init)
	for step in range(10):
		gen = logmap_iterator(raw_data, batch_size, num_steps, PRE_STEPS)
		for i in range(epoch_size-batch_size):
			s, a  = gen.next()
			training = sess.run([optimizer, o, cost], {x:s, y:a})
			if i % 100 == 0:
				print "i", i, "cost", training[2]
				print "initial input", s[0][:5]
				print "pred", training[1][0][:5]
				print "answ", a[0][:5]
			if i % 2000 == 2000:
				L = L/2
    save_path = saver.save(sess, "dynamic_model.ckpt")

La forme du modèle ressemble à ceci. J'ai touché l'illustrateur pour la première fois depuis longtemps ...

Le nombre de couches cachées est raisonnable, et la raison de l'utilisation de $ sigmoid $ est simplement que la sortie se situe entre «0 et 1». Il n'y a qu'un seul nombre à saisir, car cela n'a aucun sens autre que $ x_t $ pour trouver $ x_ {t + 1} $. Par conséquent, il n'y a pas de partage des valeurs d'état à l'intérieur du réseau. (C'est un secret que la perte n'a pas bien diminué lorsque l'apport a été augmenté) Je ne pense pas que cela puisse être officiellement appelé RNN, mais c'est un Feedloop.

(En fait, il estime $ r $ à partir de $ \ in x_n $ consécutifs et génère $ x_ {n + 1} $, et ajoute à nouveau que $ x_ {n + 1} $ à l'entrée à $ x_ {n + ... Je pense qu'il serait plus précis de le définir sur} $, mais je ne pourrais pas utiliser correctement RNN Cell de Tensorflow.)

Pour le moment, j'étais personnellement satisfait des résultats.

Apprentissage précoce scatter.gif

line.gif

Finalement, la perte s'installera autour de «1e-5», et la meilleure prédiction ressemblera à ceci. 424700.png

42300.png 8300.png

Je n'ai pas essayé cela pour d'autres équations chaotiques telles que Lorenz, donc je ne suis pas sûr.

Recommended Posts

Chaos retour de la cartographie logistique par Petit RNN dans Tensorflow
Résumé des différentes opérations dans Tensorflow
Tracé de la droite de régression par tracé des résidus
Premier TensorFlow (édition révisée) - Régression linéaire et logistique
J'ai essayé d'implémenter la régression logistique de Cousera en Python