Я уже проверил эти три ответа на SO, но на самом деле они не дали решения моей проблемы, хотя, возможно, это поможет кому-то здесь помочь мне: Этот, этот и этот.
Я внес изменения в своего агента по торговле акциями Actor Critic, чтобы включить в свой фрейм данных гораздо больше функций / столбцов для обучения технических индикаторов, и теперь я получаю значения Nan
в качестве функции стоимости во время обучения. Не вставляя весь мой код, поскольку он довольно длинный, я опубликую некоторые соответствующие разделы, чтобы, надеюсь, помочь кому-то определить, что еще я могу попробовать.
Основная архитектура агента, которая дала мне хорошие результаты обучения, выглядит так:
class Actor:
def __init__(self, name, input_size, output_size, size_layer):
with tf.variable_scope(name):
self.X = tf.placeholder(tf.float32, (None, input_size)) # input_size = State Size = 405
feed_actor = tf.layers.dense(self.X, size_layer, activation = tf.nn.relu)
tensor_action, tensor_validation = tf.split(feed_actor,2,1)
feed_action = tf.layers.dense(tensor_action, output_size)
feed_validation = tf.layers.dense(tensor_validation, 1)
self.logits = feed_validation + tf.subtract(feed_action,
tf.reduce_mean(feed_action,axis=1,keep_dims=True))
class Critic:
def __init__(self, name, input_size, output_size, size_layer, learning_rate):
with tf.variable_scope(name):
self.X = tf.placeholder(tf.float32, (None, input_size))
self.Y = tf.placeholder(tf.float32, (None, output_size))
self.REWARD = tf.placeholder(tf.float32, (None, 1))
feed_critic = tf.layers.dense(self.X, size_layer, activation = tf.nn.relu)
tensor_action, tensor_validation = tf.split(feed_critic,2,1)
feed_action = tf.layers.dense(tensor_action, output_size)
feed_validation = tf.layers.dense(tensor_validation, 1)
feed_critic = feed_validation + tf.subtract(feed_action,tf.reduce_mean(feed_action,axis=1,keep_dims=True))
feed_critic = tf.nn.relu(feed_critic) + self.Y
feed_critic = tf.layers.dense(feed_critic, size_layer//2, activation = tf.nn.relu)
self.logits = tf.layers.dense(feed_critic, 1)
self.cost = tf.reduce_mean(tf.square(self.REWARD - self.logits))
self.optimizer = tf.train.AdamOptimizer(learning_rate).minimize(self.cost)
class Agent:
LEARNING_RATE = 0.0000001
BATCH_SIZE = 32
LAYER_SIZE = 256
OUTPUT_SIZE = 5 # Buy Call, Sell Call, Hold, Buy Put, Sell Put
EPSILON = 0.5
DECAY_RATE = 0.005
MIN_EPSILON = 0.05
GAMMA = 0.95
MEMORIES = deque()
MEMORY_SIZE = 500
COPY = 1000
T_COPY = 0
def __init__(self, state_size, window_size,
trend, close_price, high_price, low_price, volume_price, ma, atr, mom_price,
skip, stock_name, number):
self.state_size = state_size # 405
self.window_size = window_size # 50
self.half_window = window_size // 2
self.trend = trend # Open price
self.close = close_price # Yesterday's close price
self.high = high_price
self.low = low_price
self.volume = volume_price
self.ma = ma # Moving Average
self.atr_price = atr
self.mom_price = mom_price
self.skip = skip
self.stock_name = stock_name
self.number = number
tf.reset_default_graph()
self.actor = Actor('actor-original', self.state_size, self.OUTPUT_SIZE, self.LAYER_SIZE)
self.actor_target = Actor('actor-target', self.state_size, self.OUTPUT_SIZE, self.LAYER_SIZE)
self.critic = Critic('critic-original', self.state_size, self.OUTPUT_SIZE, self.LAYER_SIZE, self.LEARNING_RATE)
self.critic_target = Critic('critic-target', self.state_size, self.OUTPUT_SIZE,
self.LAYER_SIZE, self.LEARNING_RATE)
self.grad_critic = tf.gradients(self.critic.logits, self.critic.Y)
self.actor_critic_grad = tf.placeholder(tf.float32, [None, self.OUTPUT_SIZE])
weights_actor = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='actor')
self.grad_actor = tf.gradients(self.actor.logits, weights_actor, -self.actor_critic_grad)
grads = zip(self.grad_actor, weights_actor)
self.optimizer = tf.train.AdamOptimizer(self.LEARNING_RATE).apply_gradients(grads)
self.sess = tf.InteractiveSession()
Итак, в основном размер моего состояния в настоящее время представляет собой массив [-1, 405], который загружается в заполнитель self.X
. Также обратите внимание на скорость обучения, размер пакета и размер слоя. Это хорошо тренируется и уменьшает функцию стоимости, как и должно быть.
Теперь я внес изменение, которое превращает мой state_size
в колоссальный массив [-1, 2165] за счет добавления дополнительных функций/технических индикаторов в мой фрейм данных (а также размер окна/период ретроспективного анализа на 60 периодов).
По указанию других и из ответов, которые я уже нашел в Интернете, я попытался:
- Уменьшите скорость обучения (я пробовал диапазон от 0,0000001 до 0,000000000000000000000000000001)
- Увеличьте размер пакета (я пробовал 32, 64, 128, 256 и 512 с комбинацией скоростей обучения выше)
- Увеличьте размер слоя модели (я пробовал 256, 512, 1024 и 2048, пробуя пакет из 256 и 512)
Все они возвращали значения nan для моей переменной стоимости. Теперь мне повезло, и я получил другую ошибку, используя:
LEARNING_RATE = 0.000000000000000000000000000000000000000000000000000000000001
BATCH_SIZE = 256
LAYER_SIZE = 1500
...который сказал:
print('epoch: %d total rewards: %f cost: %f total money: %f prof:cost: %f winratio: %f averagewinner %f averageloser %f'%(i + 1, total_profit, cost, starting_money, total_profit/cost, win_ratio, avg_winner, avg_loser))
TypeError: only size-1 arrays can be converted to Python scalars
... поэтому я попытался распечатать переменную стоимости перед этой строкой, чтобы выяснить, почему она вызывает эту проблему сейчас, но я не смог воспроизвести ошибку при следующем тренировочном прогоне :(
Поэтому я в недоумении, как исследовать этот вопрос дальше. Что еще можно попробовать??? Нужно ли мне добавить еще один слой в модель (и как это будет выглядеть)? Спасибо!