Прогнозирование цены криптовалюты с Tensorflow и Keras — TechCave

Криптовалюты, особенно Bitcoin, недавно стали одним из трендов в социальных сетях и поисковых системах. Их высокая волатильность приводит к большому потенциалу высокой прибыли, если использовать разумные стратегии инвестирования.

Прогнозирование цены криптовалюты с Tensorflow и Keras

Machine Learning/Data Mining/Big Data

Прогнозирование цены криптовалюты с Tensorflow и Keras

Криптовалюты, особенно Bitcoin, недавно стали одним из трендов в социальных сетях и поисковых системах. Их высокая волатильность приводит к большому потенциалу высокой прибыли, если использовать разумные стратегии инвестирования. К сожалению, из-за отсутствия индексов, криптовалюты относительно непредсказуемы по сравнению с традиционными финансовыми инструментами. Эта статья призвана научить вас, как предсказать цену этих криптовалют с помощью Deep Learning. В качестве примера будем использовать Bitcoin.

Давайте начнем

Чтобы запустить код, убедитесь, что вы установили следующие библиотеки:

  1. Python 2.7
  2. Tensorflow=1.2.0
  3. Keras=2.1.1
  4. Pandas=0.20.3
  5. Numpy=1.13.3
  6. h5py=2.7.0
  7. sklearn=0.19.1

Сбор данных

Данные для предсказания могут быть собраны из Kaggle или Poloniex. Чтобы обеспечить совместимость, имена столбцов для данных, собранных из Poloniex, изменяются в соответствии с данными Kaggle.

import json
import numpy as np
import os
import pandas as pd
import urllib2

# connect to poloniex's API
url = 'https://poloniex.com/public?command=returnChartData¤cyPair=USDT_BTC&start=1356998100&end=9999999999&period=300'

# parse json returned from the API to Pandas DF
openUrl = urllib2.urlopen(url)
r = openUrl.read()
openUrl.close()
d = json.loads(r.decode())
df = pd.DataFrame(d)

original_columns=[u'close', u'date', u'high', u'low', u'open']
new_columns = ['Close','Timestamp','High','Low','Open']
df = df.loc[:,original_columns]
df.columns = new_columns
df.to_csv('data/bitcoin2015to2017.csv',index=None)

Подготовка данных

Данные, собираемые из источника, должны быть проанализированы для отправки в модель прогнозирования. Класс PastSampler был взят из этого блога для разделения данных на список данных и меток. Входной размер (N) равен 256, а выходной размер (K) равен 16. Обратите внимание, что данные, полученные от Poloniex, были взяты с периодичностью в 5 минут. Это указывает на то, что входные данные содержат 1280 минут, а выходные 80 минут.

import numpy as np
import pandas as pd
class PastSampler:
    '''
    Forms training samples for predicting future values from past value
    '''
    def __init__(self, N, K, sliding_window = True):
        '''
        Predict K future sample using N previous samples
        '''
        self.K = K
        self.N = N
        self.sliding_window = sliding_window
    def transform(self, A):
        M = self.N + self.K     #Number of samples per row (sample + target)
        #indexes
        if self.sliding_window:
            I = np.arange(M) + np.arange(A.shape[0] - M + 1).reshape(-1, 1)
        else:
            if A.shape[0]%M == 0:
                I = np.arange(M)+np.arange(0,A.shape[0],M).reshape(-1,1)
            else:
                I = np.arange(M)+np.arange(0,A.shape[0] -M,M).reshape(-1,1)
        B = A[I].reshape(-1, M * A.shape[1], A.shape[2])
        ci = self.N * A.shape[1]    #Number of features per sample
        return B[:, :ci], B[:, ci:] #Sample matrix, Target matrix
#data file path
dfp = 'data/bitcoin2015to2017.csv'
#Columns of price data to use
columns = ['Close']
df = pd.read_csv(dfp)
time_stamps = df['Timestamp']
df = df.loc[:,columns]
original_df = pd.read_csv(dfp).loc[:,columns]

После создания класса PastSampler я применил его к собранным данным. Поскольку исходные данные колеблются от 0 до 10000 и даже больше, требуется масштабирование данных, чтобы нейронная сеть могла легче понять данные.

file_name='bitcoin2015to2017_close.h5'
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# normalization
for c in columns:
    df[c] = scaler.fit_transform(df[c].values.reshape(-1,1))
#Features are input sample dimensions(channels)
A = np.array(df)[:,None,:]
original_A = np.array(original_df)[:,None,:]
time_stamps = np.array(time_stamps)[:,None,None]
#Make samples of temporal sequences of pricing data (channel)
NPS, NFS = 256, 16         #Number of past and future samples
ps = PastSampler(NPS, NFS, sliding_window=False)
B, Y = ps.transform(A)
input_times, output_times = ps.transform(time_stamps)
original_B, original_Y = ps.transform(original_A)
import h5py
with h5py.File(file_name, 'w') as f:
    f.create_dataset("inputs", data = B)
    f.create_dataset('outputs', data = Y)
    f.create_dataset("input_times", data = input_times)
    f.create_dataset('output_times', data = output_times)
    f.create_dataset("original_datas", data=np.array(original_df))
    f.create_dataset('original_inputs',data=original_B)
    f.create_dataset('original_outputs',data=original_Y)

Создание модели

CNN

Иллюстрация CNN (Изображение взято из http://cs231n.github.io/convolutional-networks/)

import pandas as pd
import numpy as numpy
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv1D, MaxPooling1D, LeakyReLU, PReLU
from keras.utils import np_utils
from keras.callbacks import CSVLogger, ModelCheckpoint
import h5py
import os
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
# Make the program use only one GPU
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))
with h5py.File(''.join(['bitcoin2015to2017_close.h5']), 'r') as hf:
    datas = hf['inputs'].value
    labels = hf['outputs'].value
output_file_name='bitcoin2015to2017_close_CNN_2_relu'
step_size = datas.shape[1]
batch_size= 8
nb_features = datas.shape[2]
epochs = 100
#split training validation
training_size = int(0.8* datas.shape[0])
training_datas = datas[:training_size,:]
training_labels = labels[:training_size,:]
validation_datas = datas[training_size:,:]
validation_labels = labels[training_size:,:]
#build model
# 2 layers
model = Sequential()
model.add(Conv1D(activation='relu', input_shape=(step_size, nb_features), strides=3, filters=8, kernel_size=20))
model.add(Dropout(0.5))
model.add(Conv1D( strides=4, filters=nb_features, kernel_size=16))
'''
# 3 Layers
model.add(Conv1D(activation='relu', input_shape=(step_size, nb_features), strides=3, filters=8, kernel_size=8))
#model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Conv1D(activation='relu', strides=2, filters=8, kernel_size=8))
#model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Conv1D( strides=2, filters=nb_features, kernel_size=8))
# 4 layers
model.add(Conv1D(activation='relu', input_shape=(step_size, nb_features), strides=2, filters=8, kernel_size=2))
#model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Conv1D(activation='relu', strides=2, filters=8, kernel_size=2))
#model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Conv1D(activation='relu', strides=2, filters=8, kernel_size=2))
#model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Conv1D( strides=2, filters=nb_features, kernel_size=2))
'''
model.compile(loss='mse', optimizer='adam')
model.fit(training_datas, training_labels,verbose=1, batch_size=batch_size,validation_data=(validation_datas,validation_labels), epochs = epochs, callbacks=[CSVLogger(output_file_name+'.csv', append=True),ModelCheckpoint('weights/'+output_file_name+'-{epoch:02d}-{val_loss:.5f}.hdf5', monitor='val_loss', verbose=1,mode='min')])

Первая модель, которую я построил, — это сверточная нейронная сеть. В коде ниже устанавливается номер GPU «1», который будет использоваться (поскольку у меня их 4, вы можете использовать любой GPU, который вы предпочитаете). Поскольку при работе на нескольких графических процессорах Tensorflow не очень хорошо работает, разумнее ограничить его работой только на одном графическом процессоре. Если у вас нет GPU просто игнорируйте эти строки.

os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] ='1'
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

Код для построения модели CNN очень прост. Dropout слой предназначен для предотвращения проблемы переобучения. Функция потерь определяется как средняя квадратичная ошибка (MSE), а оптимизатор — это современный Adam.

model = Sequential()
model.add(Conv1D(activation='relu', input_shape=(step_size, nb_features), strides=3, filters=8, kernel_size=20))
model.add(Dropout(0.5))
model.add(Conv1D( strides=4, filters=nb_features, kernel_size=16))
model.compile(loss='mse', optimizer='adam')

Единственное, о чем вам нужно беспокоиться, это размер входа и выхода между каждым слоем. Уравнение для вычисления выхода определенного сверточного слоя:

Output time step = (Input time step — Kernel size) / Strides + 1

В конце файла я добавил две функции обратного вызова, CSVLogger и ModelCheckpoint. Первый помогает мне отслеживать все результаты обучения и проверки, в то время как последний позволяет мне сохранить веса модели для каждой эпохи.

model.fit(training_datas, training_labels,verbose=1, batch_size=batch_size,validation_data=(validation_datas,validation_labels), epochs = epochs, callbacks=[CSVLogger(output_file_name+'.csv', append=True),ModelCheckpoint('weights/'+output_file_name+'-{epoch:02d}-{val_loss:.5f}.hdf5', monitor='val_loss', verbose=1,mode='min')]

LSTM

Long Short Term Memory (LSTM) сеть представляет собой вариацию реккурентной нейронной сети (RNN). Она была изобретена для решения проблемы затухающего градиента в классической RNN. Утверждается, что LSTM способна запоминать входы с более длинными временными интервалами.

LSTM иллюстрация (взято с http://colah.github.io/posts/2015-08-Understanding-LSTMs/)

import pandas as pd
import numpy as numpy
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten,Reshape
from keras.layers import Conv1D, MaxPooling1D
from keras.utils import np_utils
from keras.layers import LSTM, LeakyReLU
from keras.callbacks import CSVLogger, ModelCheckpoint
import h5py
import os
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))
with h5py.File(''.join(['bitcoin2015to2017_close.h5']), 'r') as hf:
    datas = hf['inputs'].value
    labels = hf['outputs'].value
step_size = datas.shape[1]
units= 50
second_units = 30
batch_size = 8
nb_features = datas.shape[2]
epochs = 100
output_size=16
output_file_name='bitcoin2015to2017_close_LSTM_1_tanh_leaky_'
#split training validation
training_size = int(0.8* datas.shape[0])
training_datas = datas[:training_size,:]
training_labels = labels[:training_size,:,0]
validation_datas = datas[training_size:,:]
validation_labels = labels[training_size:,:,0]
#build model
model = Sequential()
model.add(LSTM(units=units,activation='tanh', input_shape=(step_size,nb_features),return_sequences=False))
model.add(Dropout(0.8))
model.add(Dense(output_size))
model.add(LeakyReLU())
model.compile(loss='mse', optimizer='adam')
model.fit(training_datas, training_labels, batch_size=batch_size,validation_data=(validation_datas,validation_labels), epochs = epochs, callbacks=[CSVLogger(output_file_name+'.csv', append=True),ModelCheckpoint('weights/'+output_file_name+'-{epoch:02d}-{val_loss:.5f}.hdf5', monitor='val_loss', verbose=1,mode='min')])

LSTM относительно проще, чем CNN для реализации, поскольку вам даже не нужно заботиться о соотношении между размером ядра, шагом, размером входа и размером выхода. Просто убедитесь, что размер входа и выхода определены правильно.

model = Sequential()
model.add(LSTM(units=units,activation='tanh', input_shape=(step_size,nb_features),return_sequences=False))
model.add(Dropout(0.8))
model.add(Dense(output_size))
model.add(LeakyReLU())
model.compile(loss='mse', optimizer='adam')

GRU

Gated Recurrent Units (GRU) — это еще один вариант RNN. Его сетевая структура менее сложна, чем LSTM с одним сбросом и затвором. Считается, что производительность GRU сравнима с LSTM, но более эффективна. (что также верно в этом блоге, поскольку обучение LSTM занимает около 45 секунд на эпоху, а GRU занимает менее 40 секунд на эпоху)


GRU иллюстрация (изображение взято с http://www.jackdermody.net/brightwire/article/GRU_Recurrent_Neural_Networks)

import pandas as pd
import numpy as numpy
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten,Reshape
from keras.layers import Conv1D, MaxPooling1D, LeakyReLU
from keras.utils import np_utils
from keras.layers import GRU,CuDNNGRU
from keras.callbacks import CSVLogger, ModelCheckpoint
import h5py
import os
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))
with h5py.File(''.join(['bitcoin2015to2017_close.h5']), 'r') as hf:
    datas = hf['inputs'].value
    labels = hf['outputs'].value
output_file_name='bitcoin2015to2017_close_GRU_1_tanh_relu_'
step_size = datas.shape[1]
units= 50
batch_size = 8
nb_features = datas.shape[2]
epochs = 100
output_size=16
#split training validation
training_size = int(0.8* datas.shape[0])
training_datas = datas[:training_size,:]
training_labels = labels[:training_size,:,0]
validation_datas = datas[training_size:,:]
validation_labels = labels[training_size:,:,0]
#build model
model = Sequential()
model.add(GRU(units=units, input_shape=(step_size,nb_features),return_sequences=False))
model.add(Activation('tanh'))
model.add(Dropout(0.2))
model.add(Dense(output_size))
model.add(Activation('relu'))
model.compile(loss='mse', optimizer='adam')
model.fit(training_datas, training_labels, batch_size=batch_size,validation_data=(validation_datas,validation_labels), epochs = epochs, callbacks=[CSVLogger(output_file_name+'.csv', append=True),ModelCheckpoint('weights/'+output_file_name+'-{epoch:02d}-{val_loss:.5f}.hdf5', monitor='val_loss', verbose=1,mode='min')])
<code>

Просто замените вторую строку в модели LSTM

model.add(LSTM(units=units,activation='tanh', input_shape=(step_size,nb_features),return_sequences=False))

на

model.add(GRU(units=units,activation='tanh', input_shape=(step_size,nb_features),return_sequences=False))

Отображение результатов

Поскольку построение результатов аналогично для трех моделей, я покажу только версию для CNN. Во-первых, нам нужно восстановить модель и загрузить в модель обученные веса.

from keras import applications
from keras.models import Sequential
from keras.models import Model
from keras.layers import Dropout, Flatten, Dense, Activation
from keras.callbacks import CSVLogger
import tensorflow as tf
from scipy.ndimage import imread
import numpy as np
import random
from keras.layers import LSTM
from keras.layers import Conv1D, MaxPooling1D, LeakyReLU
from keras import backend as K
import keras
from keras.callbacks import CSVLogger, ModelCheckpoint
from keras.backend.tensorflow_backend import set_session
from keras import optimizers
import h5py
from sklearn.preprocessing import MinMaxScaler
import os
import pandas as pd
# import matplotlib
import matplotlib.pyplot as plt
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
with h5py.File(''.join(['bitcoin2015to2017_close.h5']), 'r') as hf:
    datas = hf['inputs'].value
    labels = hf['outputs'].value
    input_times = hf['input_times'].value
    output_times = hf['output_times'].value
    original_inputs = hf['original_inputs'].value
    original_outputs = hf['original_outputs'].value
    original_datas = hf['original_datas'].value
scaler=MinMaxScaler()
#split training validation
training_size = int(0.8* datas.shape[0])
training_datas = datas[:training_size,:,:]
training_labels = labels[:training_size,:,:]
validation_datas = datas[training_size:,:,:]
validation_labels = labels[training_size:,:,:]
validation_original_outputs = original_outputs[training_size:,:,:]
validation_original_inputs = original_inputs[training_size:,:,:]
validation_input_times = input_times[training_size:,:,:]
validation_output_times = output_times[training_size:,:,:]
ground_true = np.append(validation_original_inputs,validation_original_outputs, axis=1)
ground_true_times = np.append(validation_input_times,validation_output_times, axis=1)
step_size = datas.shape[1]
batch_size= 8
nb_features = datas.shape[2]
model = Sequential()
# 2 layers
model.add(Conv1D(activation='relu', input_shape=(step_size, nb_features), strides=3, filters=8, kernel_size=20))
# model.add(LeakyReLU())
model.add(Dropout(0.25))
model.add(Conv1D( strides=4, filters=nb_features, kernel_size=16))
model.load_weights('weights/bitcoin2015to2017_close_CNN_2_relu-44-0.00030.hdf5')
model.compile(loss='mse', optimizer='adam')

Затем нам нужно инвертировать масштабированные предсказанные данные, которые варьируются от [0,1] из-за использованного ранее MinMaxScaler.

predicted = model.predict(validation_datas)
predicted_inverted = []
for i in range(original_datas.shape[1]):
    scaler.fit(original_datas[:,i].reshape(-1,1))
    predicted_inverted.append(scaler.inverse_transform(predicted[:,:,i]))
print np.array(predicted_inverted).shape
#get only the close data
ground_true = ground_true[:,:,0].reshape(-1)
ground_true_times = ground_true_times.reshape(-1)
ground_true_times = pd.to_datetime(ground_true_times, unit='s')
# since we are appending in the first dimension
predicted_inverted = np.array(predicted_inverted)[0,:,:].reshape(-1)
print np.array(predicted_inverted).shape
validation_output_times = pd.to_datetime(validation_output_times.reshape(-1), unit='s')

Оба датафрейма для истинных данных и прогнозируемой цены биткоина получены. На графике показаны только данные с августа 2017 года.

ground_true_df = pd.DataFrame()
ground_true_df['times'] = ground_true_times
ground_true_df['value'] = ground_true
prediction_df = pd.DataFrame()
prediction_df['times'] = validation_output_times
prediction_df['value'] = predicted_inverted
prediction_df = prediction_df.loc[(prediction_df["times"].dt.year == 2017 )&(prediction_df["times"].dt.month > 7 ),: ]
ground_true_df = ground_true_df.loc[(ground_true_df["times"].dt.year == 2017 )&(ground_true_df["times"].dt.month > 7 ),:]

Строим график с помощью pyplot. В результате здесь предсказанные данные отображаются как красная точка, на это указывает «ro» в третьей строке. Синяя линия на приведенном ниже графике представляет истинные значения (фактические данные), тогда как красные точки представляют предсказанную цену биткоина.

plt.figure(figsize=(20,10))
plt.plot(ground_true_df.times,ground_true_df.value, label = 'Actual')
plt.plot(prediction_df.times,prediction_df.value,'ro', label='Predicted')
plt.legend(loc='upper left')
plt.show()

Как видно из приведенного выше графика, предсказание напоминает фактическую цену биткоина. Чтобы выбрать лучшую модель, я решил протестировать несколько видов конфигурации сети, получив приведенную ниже таблицу.

Каждая строка приведенной выше таблицы является моделью, которая выводит наилучшее значение функции потери из 100 эпох обучения. Из приведенного выше результата мы можем заметить, что LeakyReLU всегда, кажется, дает лучшее значение потери по сравнению с классическим ReLU. Тем не менее, 4-слойный CNN с Leaky ReLU в качестве функции активации дает большее значении функции потери. Лучшей моделью кажется LSTM с tanh и Leaky ReLU в качестве функции активации, хотя трехслойный CNN, по-видимому, лучше фиксирует локальную временную зависимость данных.


LSTM с tanh и Leaky ReLu в качестве функции активации

3-слойная CNN с Leaky ReLu в качестве функции активации.

Хотя предсказание кажется довольно хорошим, существует озабоченность по поводу переобучения. Существует разрыв между тренировкой и потерей на валидации (5.97E-06 против 3.92E-05) при обучении LSTM с LeakyReLU, для минимизации дисперсии следует применять регуляризацию.

Регуляризация

Чтобы узнать о лучшей стратегии регуляризации, я провел несколько экспериментов с разными значениями L1 и L2. Здесь я использую bias regularizer.

def fit_lstm(reg):
    global training_datas, training_labels, batch_size, epochs,step_size,nb_features, units
    model = Sequential()
    model.add(CuDNNLSTM(units=units, bias_regularizer=reg, input_shape=(step_size,nb_features),return_sequences=False))
    model.add(Activation('tanh'))
    model.add(Dropout(0.2))
    model.add(Dense(output_size))
    model.add(LeakyReLU())
    model.compile(loss='mse', optimizer='adam')
    model.fit(training_datas, training_labels, batch_size=batch_size, epochs = epochs, verbose=0)
    return model

Эксперимент проводится путем повторного обучения моделей 30 раз и каждый раз с 30 эпохами.

def experiment(validation_datas,validation_labels,original_datas,ground_true,ground_true_times,validation_original_outputs, validation_output_times, nb_repeat, reg):
    error_scores = list()
    #get only the close data
    ground_true = ground_true[:,:,0].reshape(-1)
    ground_true_times = ground_true_times.reshape(-1)
    ground_true_times = pd.to_datetime(ground_true_times, unit='s')
    validation_output_times = pd.to_datetime(validation_output_times.reshape(-1), unit='s')
    for i in range(nb_repeat):
        model = fit_lstm(reg)
        predicted = model.predict(validation_datas)
        predicted_inverted = []
        scaler.fit(original_datas[:,0].reshape(-1,1))
        predicted_inverted.append(scaler.inverse_transform(predicted))
        # since we are appending in the first dimension
        predicted_inverted = np.array(predicted_inverted)[0,:,:].reshape(-1)
        error_scores.append(mean_squared_error(validation_original_outputs[:,:,0].reshape(-1),predicted_inverted))
    return error_scores
regs = [regularizers.l1(0),regularizers.l1(0.1), regularizers.l1(0.01), regularizers.l1(0.001), regularizers.l1(0.0001),regularizers.l2(0.1), regularizers.l2(0.01), regularizers.l2(0.001), regularizers.l2(0.0001)]
nb_repeat = 30
results = pd.DataFrame()
for reg in regs:
    name = ('l1 %.4f,l2 %.4f' % (reg.l1, reg.l2))
    print "Training "+ str(name)
    results[name] = experiment(validation_datas,validation_labels,original_datas,ground_true,ground_true_times,validation_original_outputs, validation_output_times, nb_repeat,reg)
results.describe().to_csv('result/lstm_bias_reg.csv')
results.describe()

Если вы используете ноутбук Jupyter, вы можете увидеть таблицу.

Чтобы визуализировать сравнение, мы можем использовать boxplot:

results.describe().boxplot()
plt.show()

Согласно сравнению, кажется, что L2-регуляризатор с коэффициентом 0.01 дает лучший результат.

Вывод

Мы узнали:

  1. Как собрать данные биткойнов в реальном времени.
  2. Как подготовить данные для обучения и тестирования.
  3. Как предсказать цену биткойна с помощью Deep Learning.
  4. Как визуализировать результат предсказания.
  5. Как применить регуляризацию к модели.

Для получения дополнительной информации, пожалуйста, посмотрите github.

Перевод статьи " Predicting Cryptocurrency Price With Tensorflow and Keras"

07:37
187

Нет комментариев. Ваш будет первым!

Авторизация

Пользователи

Keyleas
Kirby
Имя Фамилия
lunchcalllina1978
Sever
stopresniebots1983
tekino
templide
Seangle