নিউরাল নেটওয়ার্ক কেন তার নিজস্ব প্রশিক্ষণ ডেটাতে ভুল ভবিষ্যদ্বাণী করে?


11

ডেটা স্টক পূর্বাভাসের জন্য তদারকি করা শিক্ষার সাথে আমি একটি এলএসটিএম (আরএনএন) নিউরাল নেটওয়ার্ক তৈরি করেছি। সমস্যাটি কেন এটি তার নিজস্ব প্রশিক্ষণের ডেটাতে ভুল ভবিষ্যদ্বাণী করে? (দ্রষ্টব্য: নীচে পুনরুত্পাদনযোগ্য উদাহরণ )

আমি পরবর্তী 5 দিনের স্টক দামের পূর্বাভাস দেওয়ার জন্য সহজ মডেল তৈরি করেছি:

model = Sequential()
model.add(LSTM(32, activation='sigmoid', input_shape=(x_train.shape[1], x_train.shape[2])))
model.add(Dense(y_train.shape[1]))
model.compile(optimizer='adam', loss='mse')

es = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
model.fit(x_train, y_train, batch_size=64, epochs=25, validation_data=(x_test, y_test), callbacks=[es])

সঠিক ফলাফলগুলি y_test(5 টি মান) এ রয়েছে, সুতরাং মডেল ট্রেনগুলি 90 আগের দিনগুলি ফিরে দেখবে এবং তারপরে সেরা ( val_loss=0.0030) ফলাফল থেকে ওজন পুনরুদ্ধার করে patience=3:

Train on 396 samples, validate on 1 samples
Epoch 1/25
396/396 [==============================] - 1s 2ms/step - loss: 0.1322 - val_loss: 0.0299
Epoch 2/25
396/396 [==============================] - 0s 402us/step - loss: 0.0478 - val_loss: 0.0129
Epoch 3/25
396/396 [==============================] - 0s 397us/step - loss: 0.0385 - val_loss: 0.0178
Epoch 4/25
396/396 [==============================] - 0s 399us/step - loss: 0.0398 - val_loss: 0.0078
Epoch 5/25
396/396 [==============================] - 0s 391us/step - loss: 0.0343 - val_loss: 0.0030
Epoch 6/25
396/396 [==============================] - 0s 391us/step - loss: 0.0318 - val_loss: 0.0047
Epoch 7/25
396/396 [==============================] - 0s 389us/step - loss: 0.0308 - val_loss: 0.0043
Epoch 8/25
396/396 [==============================] - 0s 393us/step - loss: 0.0292 - val_loss: 0.0056

ভবিষ্যদ্বাণী ফলাফল খুব দুর্দান্ত, তাই না?

এখানে চিত্র বর্ণনা লিখুন

এটি কারণ যে # 5 কাল থেকে অ্যালগরিদম সেরা ওজন পুনরুদ্ধার করে। ওকে, আসুন এখন এই মডেলটি .h5ফাইল করার জন্য সংরক্ষণ করুন, -10 দিন পিছিয়ে যান এবং শেষ 5 দিনের পূর্বাভাস দিন (প্রথম উদাহরণে আমরা মডেল তৈরি করেছি এবং সপ্তাহান্তের ছুটি সহ 17-23 এপ্রিলটি বৈধতা দেব, এখন ২-৮ এপ্রিল পরীক্ষা করি)। ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

এটি একেবারে ভুল দিক দেখায়। আমরা দেখতে পাচ্ছি কারণ মডেলটি প্রশিক্ষিত হয়েছিল এবং ১ 5-২৩ এপ্রিল বৈধকরণের জন্য # 5 যুগের সেরা নিয়েছিল, তবে 2-8 এ নয়। আমি যদি আরও প্রশিক্ষণের চেষ্টা করি, কোন যুগকে বেছে নেওয়ার সাথে খেলতে খেলি, যাই যাই করুক না কেন, অতীতে সবসময় অনেক সময় অন্তর থাকে যার ভুল পূর্বাভাস থাকে।

মডেল কেন তার নিজস্ব প্রশিক্ষিত ডেটাতে ভুল ফলাফল দেখায়? আমি ডেটা প্রশিক্ষিত করেছি, এটি অবশ্যই এই সেট এর টুকরোতে ডেটা পূর্বাভাস দিতে হবে তা মনে রাখতে হবে, তবে ভুল পূর্বাভাস দিয়েছে। আমি যা চেষ্টা করেছি:

  • কম বেশি বৈশিষ্ট্য যুক্ত করে 50k + সারি, 20 বছরের স্টক মূল্য সহ বড় ডেটা সেট ব্যবহার করুন
  • আরও বিভিন্ন ধরণের মডেল তৈরি করুন, যেমন আরও লুকানো স্তর যুক্ত করুন, বিভিন্ন ব্যাচ_ আকারগুলি, বিভিন্ন স্তর সক্রিয়করণ, ড্রপআউটস, ব্যাচনারমালাইজেশন
  • কাস্টম আর্লিস্টপপিং কলব্যাক তৈরি করুন, অনেকগুলি বৈধতা ডেটা সেট থেকে গড় ভাল_লস পান এবং সেরাটি চয়ন করুন

আমি কিছু মিস করছি? আমি কী উন্নতি করতে পারি?

এখানে খুব সহজ এবং পুনরুত্পাদনযোগ্য উদাহরণ। yfinanceএস অ্যান্ড পি 500 স্টক ডেটা ডাউনলোড করে।

"""python 3.7.7
tensorflow 2.1.0
keras 2.3.1"""


import numpy as np
import pandas as pd
from keras.callbacks import EarlyStopping, Callback
from keras.models import Model, Sequential, load_model
from keras.layers import Dense, Dropout, LSTM, BatchNormalization
from sklearn.preprocessing import MinMaxScaler
import plotly.graph_objects as go
import yfinance as yf
np.random.seed(4)


num_prediction = 5
look_back = 90
new_s_h5 = True # change it to False when you created model and want test on other past dates


df = yf.download(tickers="^GSPC", start='2018-05-06', end='2020-04-24', interval="1d")
data = df.filter(['Close', 'High', 'Low', 'Volume'])

# drop last N days to validate saved model on past
df.drop(df.tail(0).index, inplace=True)
print(df)


class EarlyStoppingCust(Callback):
    def __init__(self, patience=0, verbose=0, validation_sets=None, restore_best_weights=False):
        super(EarlyStoppingCust, self).__init__()
        self.patience = patience
        self.verbose = verbose
        self.wait = 0
        self.stopped_epoch = 0
        self.restore_best_weights = restore_best_weights
        self.best_weights = None
        self.validation_sets = validation_sets

    def on_train_begin(self, logs=None):
        self.wait = 0
        self.stopped_epoch = 0
        self.best_avg_loss = (np.Inf, 0)

    def on_epoch_end(self, epoch, logs=None):
        loss_ = 0
        for i, validation_set in enumerate(self.validation_sets):
            predicted = self.model.predict(validation_set[0])
            loss = self.model.evaluate(validation_set[0], validation_set[1], verbose = 0)
            loss_ += loss
            if self.verbose > 0:
                print('val' + str(i + 1) + '_loss: %.5f' % loss)

        avg_loss = loss_ / len(self.validation_sets)
        print('avg_loss: %.5f' % avg_loss)

        if self.best_avg_loss[0] > avg_loss:
            self.best_avg_loss = (avg_loss, epoch + 1)
            self.wait = 0
            if self.restore_best_weights:
                print('new best epoch = %d' % (epoch + 1))
                self.best_weights = self.model.get_weights()
        else:
            self.wait += 1
            if self.wait >= self.patience or self.params['epochs'] == epoch + 1:
                self.stopped_epoch = epoch
                self.model.stop_training = True
                if self.restore_best_weights:
                    if self.verbose > 0:
                        print('Restoring model weights from the end of the best epoch')
                    self.model.set_weights(self.best_weights)

    def on_train_end(self, logs=None):
        print('best_avg_loss: %.5f (#%d)' % (self.best_avg_loss[0], self.best_avg_loss[1]))


def multivariate_data(dataset, target, start_index, end_index, history_size, target_size, step, single_step=False):
    data = []
    labels = []
    start_index = start_index + history_size
    if end_index is None:
        end_index = len(dataset) - target_size
    for i in range(start_index, end_index):
        indices = range(i-history_size, i, step)
        data.append(dataset[indices])
        if single_step:
            labels.append(target[i+target_size])
        else:
            labels.append(target[i:i+target_size])
    return np.array(data), np.array(labels)


def transform_predicted(pr):
    pr = pr.reshape(pr.shape[1], -1)
    z = np.zeros((pr.shape[0], x_train.shape[2] - 1), dtype=pr.dtype)
    pr = np.append(pr, z, axis=1)
    pr = scaler.inverse_transform(pr)
    pr = pr[:, 0]
    return pr


step = 1

# creating datasets with look back
scaler = MinMaxScaler()
df_normalized = scaler.fit_transform(df.values)
dataset = df_normalized[:-num_prediction]
x_train, y_train = multivariate_data(dataset, dataset[:, 0], 0,len(dataset) - num_prediction + 1, look_back, num_prediction, step)
indices = range(len(dataset)-look_back, len(dataset), step)
x_test = np.array(dataset[indices])
x_test = np.expand_dims(x_test, axis=0)
y_test = np.expand_dims(df_normalized[-num_prediction:, 0], axis=0)

# creating past datasets to validate with EarlyStoppingCust
number_validates = 50
step_past = 5
validation_sets = [(x_test, y_test)]
for i in range(1, number_validates * step_past + 1, step_past):
    indices = range(len(dataset)-look_back-i, len(dataset)-i, step)
    x_t = np.array(dataset[indices])
    x_t = np.expand_dims(x_t, axis=0)
    y_t = np.expand_dims(df_normalized[-num_prediction-i:len(df_normalized)-i, 0], axis=0)
    validation_sets.append((x_t, y_t))


if new_s_h5:
    model = Sequential()
    model.add(LSTM(32, return_sequences=False, activation = 'sigmoid', input_shape=(x_train.shape[1], x_train.shape[2])))
    # model.add(Dropout(0.2))
    # model.add(BatchNormalization())
    # model.add(LSTM(units = 16))
    model.add(Dense(y_train.shape[1]))
    model.compile(optimizer = 'adam', loss = 'mse')

    # EarlyStoppingCust is custom callback to validate each validation_sets and get average
    # it takes epoch with best "best_avg" value
    # es = EarlyStoppingCust(patience = 3, restore_best_weights = True, validation_sets = validation_sets, verbose = 1)

    # or there is keras extension with built-in EarlyStopping, but it validates only 1 set that you pass through fit()
    es = EarlyStopping(monitor = 'val_loss', patience = 3, restore_best_weights = True)

    model.fit(x_train, y_train, batch_size = 64, epochs = 25, shuffle = True, validation_data = (x_test, y_test), callbacks = [es])
    model.save('s.h5')
else:
    model = load_model('s.h5')



predicted = model.predict(x_test)
predicted = transform_predicted(predicted)
print('predicted', predicted)
print('real', df.iloc[-num_prediction:, 0].values)
print('val_loss: %.5f' % (model.evaluate(x_test, y_test, verbose=0)))


fig = go.Figure()
fig.add_trace(go.Scatter(
    x = df.index[-60:],
    y = df.iloc[-60:,0],
    mode='lines+markers',
    name='real',
    line=dict(color='#ff9800', width=1)
))
fig.add_trace(go.Scatter(
    x = df.index[-num_prediction:],
    y = predicted,
    mode='lines+markers',
    name='predict',
    line=dict(color='#2196f3', width=1)
))
fig.update_layout(template='plotly_dark', hovermode='x', spikedistance=-1, hoverlabel=dict(font_size=16))
fig.update_xaxes(showspikes=True)
fig.update_yaxes(showspikes=True)
fig.show()

3
প্রজননযোগ্য উদাহরণ আজকাল খুব বিরল (একই ধরণের প্রশ্নের গাজিলিয়ানের বিপরীতে) যা আপনার পোস্টের শুরুতে এর অস্তিত্বের বিজ্ঞাপন দেওয়া যুক্তিযুক্তভাবে ভাল ধারণা (যুক্ত);)
মরুভূমি

6
সমস্যাটি কেবল এমন হতে পারে যে আপনি শেয়ার বাজারের বাইরে খুব বেশি ভবিষ্যদ্বাণী আশা করছেন। আপনি যদি 1 মিলিয়ন মুদ্রা ফ্লিপের অনুক্রমের ভিত্তিতে কোনও মডেলকে প্রশিক্ষণ দেন এবং তারপরে এটি মুদ্রার ফ্লিপগুলি পূর্বাভাস দেওয়ার চেষ্টা করেন, তবে প্রশিক্ষণ ডেটা থেকে ফ্লিপগুলি এসেছিল এমন কি, মডেলটি এটি ভুল হওয়া অবাক করার মতো হবে না - মডেল এটির প্রশিক্ষণের ডেটা মুখস্ত করে পুনরায় সাজানোর আশা করা যায় না।
ব্যবহারকারী 2357112 13,99 এ মনিকা

1
@ ইউজার 2357112 সাপোর্টপোর্টসোনিকা যা বলেছে তা ছাড়াও, আপনার মডেলটি যথাযথভাবে সঠিকভাবে পেয়েছে, যা সত্যিই আমি আশা করি এর মতো একটি মডেল সত্যিই পাবেন (কমপক্ষে কোনও ধারাবাহিকতার সাথে), এবং আপনি 5 দিনের মধ্যে খুব বেশি আশা করছেন ডেটা। আপনার মডেলটিতে ত্রুটিটি কী তা তা কোনও তাত্পর্য সহ বলতে সক্ষম হওয়ার জন্য আপনার আরও অনেক বেশি ডেটা দরকার।
হারুন

মডেল টিউন করার জন্য আরও অনেকগুলি পরামিতি রয়েছে। আমি তাদের কয়েকটি চেষ্টা করেছিলাম যেমন তাড়াতাড়ি থামানো (ধৈর্য = 20), যুগের সংখ্যা বৃদ্ধি, এলএসটিএম ইউনিট 32 থেকে 64 বৃদ্ধি পেয়েছে। ফলাফল আরও ভাল ছিল। এখানে github.com/jvishnuvardhan/Stackoverflow_Questions/blob/master/… দেখুন । @ সিরজায় উল্লেখ করেছেন যে আরও বৈশিষ্ট্য যুক্ত করা হয়েছে (বর্তমানে কেবলমাত্র ৪), আরও বেশি স্তর যুক্ত (এলএসটিএম, ব্যাচনরম, ড্রপআউট, ইত্যাদি), হাইপার প্যারামিটার অপ্টিমাইজেশান চালিয়ে যাওয়ার ফলে আরও ভাল পারফরম্যান্স হতে পারে।
বিষ্ণুবর্ধন জনপতি

@ বিষ্ণুবর্ধন জনপতি সতর্কতার জন্য আপনাকে ধন্যবাদ আমি আপনার কোডটি সঙ্কলিত করেছি, সেভ মডেল, তারপরে সেট করুন df.drop(df.tail(10).index, inplace=True), এটি আমার মতো একই খারাপ ফলাফলটি দেখিয়েছিল।
সিরজয়

উত্তর:


3

মডেল কেন তার নিজস্ব প্রশিক্ষিত ডেটাতে ভুল ফলাফল দেখায়? আমি ডেটা প্রশিক্ষিত করেছি, এটি অবশ্যই এই সেট এর টুকরোতে ডেটা পূর্বাভাস দিতে হবে তা মনে রাখতে হবে, তবে ভুল পূর্বাভাস দিয়েছে।

আপনি চান মডেলটি মুখস্ত করার পরিবর্তে ইনপুট এবং আউটপুটটির মধ্যে সম্পর্কটি শিখুক। যদি কোনও মডেল প্রতিটি ইনপুটটির জন্য সঠিক আউটপুট মুখস্থ করে রাখে তবে আমরা বলতে পারি এটি প্রশিক্ষণের ডেটা ফিট করে। প্রায়শই আপনি ডেটার একটি ছোট উপসেট ব্যবহার করে মডেলটিকে অতিরিক্ত মানিয়ে নিতে বাধ্য করতে পারেন, তাই যদি এমন আচরণ হয় তবে আপনি দেখতে চান যে চেষ্টা করতে পারেন।


1

মূলত যদি আপনি প্রশিক্ষণের ডেটার জন্য আরও ভাল ফলাফল পেতে চান তবে আপনার প্রশিক্ষণের যথার্থতা যথাসম্ভব বেশি হওয়া উচিত। আপনার কাছে থাকা ডেটার ক্ষেত্রে আপনার আরও ভাল মডেল ব্যবহার করা উচিত। মূলত পরীক্ষার যথার্থতা নির্বিশেষে এই উদ্দেশ্যে আপনার প্রশিক্ষণের নির্ভুলতা পরীক্ষা করা উচিত। একে ওভারফিটিং হিসাবেও ডাকা হয় যা পরীক্ষার তথ্যের চেয়ে প্রশিক্ষণের ডেটাতে আরও সঠিকতা দেয়।

প্রাথমিক অবস্থায় থামানো এই দৃশ্যের জন্য প্রভাবিত হতে পারে যেখানে প্রশিক্ষণের নির্ভুলতার চেয়ে সেরা পরীক্ষা / বৈধতা নির্ভুলতা নেওয়া হয়।


1

সংক্ষিপ্ত উত্তর:

সেট করুন:

batch_size = 1
epochs = 200
shuffle = False

অন্তর্দৃষ্টি: আপনি প্রশিক্ষণের ডেটাতে উচ্চ নির্ভুলতার অগ্রাধিকার বর্ণনা করছেন। এটি overfitting বর্ণনা করা হয়। এটি করার জন্য, ব্যাচের আকারটি 1 এ সেট করুন, মহাকাশগুলি উচ্চতর এবং শাফলিং অফ।


0

মডেল কেন তার নিজস্ব প্রশিক্ষিত ডেটাতে ভুল ফলাফল দেখায়? আমি ডেটা প্রশিক্ষিত করেছি, এটি অবশ্যই এই সেট এর টুকরোতে ডেটা পূর্বাভাস দিতে হবে তা মনে রাখতে হবে, তবে ভুল পূর্বাভাস দিয়েছে।

আপনি কি করছেন দেখুন:

  1. কিছু স্তর সহ একটি মডেল তৈরি করা
  2. প্রশিক্ষণ_ডাটা সহ প্রশিক্ষণ মডেল
  3. আপনি যখন মডেলটিকে প্রশিক্ষণ দেবেন তখন সমস্ত প্রশিক্ষণযোগ্য প্যারামিটার প্রশিক্ষিত হয়ে যায় (অর্থাত্ মডেলের ওজনগুলি সংরক্ষিত হয়েছে)
  4. এই ওজনগুলি এখন ইনপুট এবং আউটপুটগুলির মধ্যে সম্পর্কের প্রতিনিধিত্ব করে।
  5. আপনি আবার একই প্রশিক্ষণ_ডেটাকে পূর্বাভাস দিলে, এই সময় প্রশিক্ষিত মডেল আউটপুট পেতে ওজন ব্যবহার করে।
  6. আপনার মডেলটির গুণমান এখন পূর্বাভাসগুলি স্থির করে এবং তাই এগুলি একই ফলাফল সত্ত্বেও মূল ফলাফল থেকে পৃথক।

0

এটি উপযুক্ত নয় এবং এটি উন্নত করার জন্য আপনাকে আপনার লুকানো স্তরগুলিতে নিউরন যুক্ত করতে হবে !! আরেকটি বিষয় হ'ল চেষ্টা করুন অ্যাক্টিভেশন ফাংশন 'রিলু'। সিগময়েড ভাল ফলাফল দেয় না। এছাড়াও আপনার আউটপুট স্তরে 'সফটম্যাক্স' সংজ্ঞায়িত করতে হবে!


আপনার কাছে মনে হচ্ছে বাজারটি পূর্বাভাস দেওয়ার জন্য গোপনীয়তাগুলি রয়েছে। তার আর কী করা উচিত?
ড্যানিয়েল স্কট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.