কেন ক্যারাস মডেল সংকলনের পরে ধীর ভবিষ্যদ্বাণী করে?


23

পূর্বাভাস গতি কেরাস

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

সম্পর্কিত পরীক্ষা দেখুন: https://nbviewer.jupyter.org/github/off99555/TensorFlowExperiments/blob/master/test-prediction-speed- after-compile.ipynb?flush_cache= true


আমি মনে করি সংকলনের পরে আপনাকে মডেল ফিট করতে হবে তারপরে ভবিষ্যদ্বাণী করার জন্য প্রশিক্ষিত মডেলটি ব্যবহার করুন। পড়ুন এখানে
সাদাসিধা

@ নায়েভ ফিটিং বিষয়টি সম্পর্কিত অপ্রাসঙ্গিক। আপনি যদি জানেন যে নেটওয়ার্কটি কীভাবে বাস্তবে কাজ করে তবে আপনি কী আগ্রহী হবেন কেন ভবিষ্যদ্বাণীটি ধীর slow ভবিষ্যদ্বাণী করার সময়, শুধুমাত্র ওজন ম্যাট্রিক্সের গুণণের জন্য ব্যবহৃত হয় এবং ভারগুলি সঙ্কলনের আগে এবং পরে অবশ্যই স্থির করা উচিত, সুতরাং পূর্বাভাসের সময়টি স্থির থাকতে হবে।
অফ 99555

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

3
@ নায়েভ সমস্যাটি মডেল পারফরম্যান্স সংকলিত বনাম অসম্পূর্ণ, যা সঠিকতা বা মডেল ডিজাইনের সাথে কিছুই করার নেই তা বোঝার উদ্বেগ। এটি একটি বৈধ ইস্যু যা টিএফ ব্যবহারকারীদের জন্য ব্যয় করতে পারে - আমার কাছে এই প্রশ্নটির হোঁচট দেওয়া পর্যন্ত এ সম্পর্কে কোনও ধারণা ছিল না।
ওভারলর্ডগোল্ডড্রাগন

1
@naive আপনি fitছাড়া পারবেন না compile; কোনও ওজন আপডেট করার জন্য অপ্টিমাইজারের উপস্থিতি নেই। আমার উত্তরে বর্ণিত বা বর্ণিত হিসাবে ব্যবহার করা predict যেতে পারে , তবে পারফরম্যান্সের পার্থক্যটি এই নাটকীয় হওয়া উচিত নয় - সুতরাং সমস্যাটি। fitcompile
ওভারলর্ডগোলড্রাগন

উত্তর:


22

আপডেট - 1/15/2020 : ছোট ব্যাচের আকারের জন্য বর্তমান সেরা অনুশীলনটি মডেলগুলিতে সরাসরি ইনপুটগুলি খাওয়ানো উচিত - অর্থাত্ preds = model(x), এবং যদি স্তরগুলি ট্রেন / অনুমানের ক্ষেত্রে আলাদাভাবে আচরণ করে model(x, training=False),। সর্বশেষ প্রতিশ্রুতিবদ্ধ হিসাবে, এটি এখন নথিভুক্ত করা হয়

আমি এগুলি বেঞ্চমার্ক করি না, তবে গিট আলোচনার ভিত্তিতে এটি চেষ্টা করার মতোও রয়েছেpredict_on_batch() - বিশেষত টিএফ ২.১-এর উন্নতি সহ।


চূড়ান্ত অভিযুক্ত ব্যক্তি : self._experimental_run_tf_function = True। এটি পরীক্ষামূলক । তবে এটি আসলে খারাপ নয়।

যে কোনও টেনসরফ্লো ডিডিং রিডিংয়ের জন্য: আপনার কোডটি পরিষ্কার করুন । এটি একটি জগাখিচুড়ি. এবং এটি গুরুত্বপূর্ণ কোডিং অনুশীলনগুলি লঙ্ঘন করে, যেমন একটি ফাংশন একটি কাজ করে ; _process_inputsএকটি করে অনেক বেশি "প্রসেস ইনপুট", একই আরো _standardize_user_data। "আমি অর্থ প্রদান করছি না যথেষ্ট" - কিন্তু আপনি কি অতিরিক্ত সময় আপনার নিজের কাপড় বুঝতে অতিবাহিত মধ্যে বেতন,, এবং ব্যবহারকারীদের বাগ সঙ্গে আপনার সমস্যাগুলির পৃষ্ঠা পূরণে সহজ একটা পরিষ্কার কোড সহ সমাধান।


সংক্ষিপ্তসার : এটি দিয়ে কিছুটা ধীরে ধীরে compile()

compile()একটি অভ্যন্তরীণ পতাকা সেট করে যা একটি আলাদা পূর্বাভাস ফাংশন নির্ধারণ করে predict। এই ফাংশনটি প্রতিটি কলের উপরে একটি নতুন গ্রাফ তৈরি করে, এটি কমপম্পেলের সাথে তুলনামূলকভাবে ধীর করে দেয়। তবে, পার্থক্যটি কেবল তখনই উচ্চারণ করা হয় যখন ডেটা প্রক্রিয়াকরণের সময়ের চেয়ে ট্রেনের সময় অনেক কম থাকে । আমরা যদি মডেলের আকারকে কমপক্ষে মাঝারি আকারে বাড়িয়ে তুলি তবে দুটি সমান হয়ে যায়। নীচে কোড দেখুন।

ডেটা প্রসেসিংয়ের সময় এই সামান্য বৃদ্ধি প্রশস্ত গ্রাফ ক্ষমতা দ্বারা ক্ষতিপূরণ চেয়ে বেশি। যেহেতু এটি কেবলমাত্র একটি মডেলের গ্রাফকে ঘিরে রাখা আরও দক্ষ, তাই একটি প্রাক-সংকলন বাতিল করা হয় ed তবুও : যদি আপনার মডেলটি ডেটার তুলনায় ছোট হয়, আপনি compile()মডেল অনুমিতি ছাড়াই ভাল । কর্মক্ষেত্রের জন্য আমার অন্যান্য উত্তর দেখুন।


আমার কি করা উচিৎ?

মডেলের পারফরম্যান্সের তুলনা করুন তুলনা করুন বনাম কমম্পাইল করা হিসাবে আমার নীচে কোড রয়েছে।

  • সংকলনটি দ্রুততর : predictএকটি সংকলিত মডেলটিতে চালান ।
  • সংকলনটি ধীর : predictএকটি অসম্পূর্ণ মডেলটিতে চালান ।

হ্যাঁ, উভয়ই সম্ভব এবং এটি (1) ডেটা আকারের উপর নির্ভর করবে; (2) মডেল আকার; (3) হার্ডওয়্যার। নীচের কোডটি আসলে সংকলিত মডেলটি দ্রুত হচ্ছে দেখায় , তবে 10 পুনরাবৃত্তি একটি ছোট নমুনা। "কীভাবে" এর জন্য আমার অন্য উত্তরে "ওয়ার্কআরউন্ডস" দেখুন।


বিশদ বিবরণ :

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

( FLAG == self.experimental_run_tf_function, ব্রিভিটি জন্য)

  1. Modelডিফল্ট দ্বারা ইনস্ট্যান্ট করে FLAG=Falsecompile()এটা সেট করে True
  2. predict() ভবিষ্যদ্বাণী ফাংশন অর্জন জড়িত, func = self._select_training_loop(x)
  3. কোনও বিশেষ কাওয়ার্গ ছাড়াই predictএবং এখানে ছাড়া compileঅন্য সমস্ত পতাকাগুলি এমন যে:
    • (ক) FLAG==True ->func = training_v2.Loop()
    • (খ) FLAG==False ->func = training_arrays.ArrayLikeTrainingLoop()
  4. থেকে সোর্স কোড docstring , (ক) প্রচন্ডভাবে, গ্রাফ-নির্ভরশীল আরো বিতরণ কৌশল ব্যবহার করে এবং অপস তৈরি & গ্রাফ উপাদান, যা (না) "হতে পারে" প্রভাব কর্মক্ষমতা অন্তক প্রবণ।

সত্য অভিযুক্ত ব্যক্তি : _process_inputs(), হিসাববিদ্যা রানটাইম এর 81% । এর প্রধান উপাদান? _create_graph_function(), রানটাইমের 72% । এই পদ্ধতি এমনকি নেই কোন অস্তিত্ব জন্য (বি) । একটি মধ্য আকারের মডেল ব্যবহার করে, কিন্তু, _process_inputsগঠিত রানটাইম কম 1% । নীচে কোড এবং প্রোফাইলিং ফলাফল অনুসরণ করে।


ডেটা প্রসেসর :

(ক) : <class 'tensorflow.python.keras.engine.data_adapter.TensorLikeDataAdapter'>ব্যবহৃত _process_inputs()প্রাসঙ্গিক উত্স কোড

(খ) : numpy.ndarrayদ্বারা ফিরে এসেছিল convert_eager_tensors_to_numpyপ্রাসঙ্গিক উত্স কোড এবং এখানে


মডেল এক্সিকিউশন ফাংশন (যেমন পূর্বাভাস)

(ক) : বিতরণ ফাংশন , এবং এখানে

(খ) : বিতরণ ফাংশন (বিভিন্ন) এবং এখানে


প্রোফিলার : আমার অন্য উত্তরের কোডের জন্য ফলাফল, "ক্ষুদ্র মডেল", এবং এই উত্তরে, "মাঝারি মডেল":

ক্ষুদ্র মডেল : 1000 পুনরাবৃত্তি,compile()

ক্ষুদ্র মডেল : 1000 পুনরাবৃত্তি, না compile()

মাঝারি মডেল : 10 পুনরাবৃত্তি


ডকুমেন্টেশন (অপ্রত্যক্ষভাবে) এর প্রভাবগুলির উপর compile(): উত্স

অন্যান্য টেনসরফ্লো অপারেশনের মতো আমরা পাইথন সংখ্যাসূচক ইনপুটগুলিকে টেনসারে রূপান্তর করি না। তদুপরি, প্রতিটি স্বতন্ত্র পাইথনের সংখ্যাসূচক মানের জন্য একটি নতুন গ্রাফ তৈরি করা হয় , উদাহরণস্বরূপ কল করা g(2)এবং g(3)দুটি নতুন গ্রাফ তৈরি করবে

function ইনপুট আকার এবং ডেটাটাইপগুলির প্রতিটি অনন্য সেটের জন্য একটি পৃথক গ্রাফ ইনস্ট্যান্ট করে । উদাহরণস্বরূপ, নিম্নলিখিত কোড স্নিপেটের ফলে তিনটি পৃথক গ্রাফ সনাক্ত করা যাবে, কারণ প্রতিটি ইনপুটটির আলাদা আকার থাকে

একটি একক tf.function অবজেক্ট হুড অধীনে একাধিক গণনা গ্রাফ মানচিত্র করা প্রয়োজন হতে পারে। এটি কেবল পারফরম্যান্স হিসাবে দৃশ্যমান হওয়া উচিত (ট্রেসিং গ্রাফগুলির একটি ননজারো কম্পিউটেশনাল এবং মেমরির ব্যয় থাকে ) তবে প্রোগ্রামটির যথার্থতা প্রভাবিত করা উচিত নয়


দেশ :

from tensorflow.keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from tensorflow.keras.layers import Flatten, Dropout
from tensorflow.keras.models import Model
import numpy as np
from time import time

def timeit(func, arg, iterations):
    t0 = time()
    for _ in range(iterations):
        func(arg)
    print("%.4f sec" % (time() - t0))

batch_size = 32
batch_shape = (batch_size, 400, 16)
ipt   = Input(batch_shape=batch_shape)
x     = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
x     = LSTM(512, activation='relu', return_sequences=True)(ipt)
x     = Conv1D(128, 400, 1, padding='same')(x)
x     = Flatten()(x)
x     = Dense(256, activation='relu')(x)
x     = Dropout(0.5)(x)
x     = Dense(128, activation='relu')(x)
x     = Dense(64,  activation='relu')(x)
out   = Dense(1,  activation='sigmoid')(x)
model = Model(ipt, out)

X = np.random.randn(*batch_shape)
timeit(model.predict, X, 10)
model.compile('adam', loss='binary_crossentropy')
timeit(model.predict, X, 10)

ফলাফল :

34.8542 sec
34.7435 sec

1
যে কোনও মডেল আকারের দ্রুততম পূর্বাভাস গতি পেতে আমাদের কী করা উচিত তার উপসংহারটি কী? এটা কি ঠিক না compile()?
অফ 99555

3
@ অফ99555 "কোনও মডেলের আকারের জন্য" - এমন কোনও জিনিস নেই। পুরো উত্তরটি পড়ুন - আমি এটি ডিবাগ করতে কয়েক ঘন্টা সময় নিলে প্রশ্নকারীর কাছ থেকে কয়েক মিনিট অযৌক্তিক হওয়া উচিত নয়।
ওভারলর্ডগোল্ডড্রাগন

আমি পুরো জিনিসটি পড়েছি তবে এটি বোঝা শক্ত কারণ কোডটি ডিবাগ করা আমিই নই। সুতরাং আপনাকে একটি উপসংহার দেওয়া দরকার যা ডিবাগিং পর্যায়ে আপনি যে মধ্যবর্তী ভেরিয়েবলগুলি জড়িত তা জড়িত না। যেমন "আপনার মডেল ছোট হয়, তাহলে কম্পাইল যে ভালো ব্যবহার করবেন না আপনার মডেল মাঝারি আকার হয়, তাহলে আপনি কম্পাইল ব্যবহার করতে পারেন`
off99555

1
@ অফ99555 যথেষ্ট মেলা; আপডেট করা হয়েছে। নতুন বিভাগটি মোটামুটি সাধারণ জ্ঞানের, তবে আমি এটি দেখতে পাচ্ছি যে এটি অবিলম্বে বাস্তবায়িত হচ্ছে না।
ওভারলর্ডগোলড্রাগন

1
@ off99555 নয় যে আমি পরীক্ষা করেছি, তবে খুব বড় মডেলগুলি (রেসনেট ইত্যাদি) উল্লেখযোগ্যভাবে দ্রুত সংকলিত চলতে পারে, esp। যদি অনেক ডিভাইসে বিতরণ করা হয় - যেমন (এ) আরও গ্রাফ- এবং বিতরণ-ভারী। সুনির্দিষ্ট পরীক্ষাটি হ'ল উত্তম, একটি পরীক্ষা - উত্তরের মতো। টিএফ লাইটের সাথে
অপরিচিত

15

আপডেট : প্রকৃত উত্তর পৃথক উত্তর হিসাবে পোস্ট দেখুন; এই পোস্টে পরিপূরক তথ্য রয়েছে


.compile() ক্ষতির পরিমাণ, মেট্রিক্স, গ্রেডিয়েন্টস এবং আংশিকভাবে অপ্টিমাইজার এবং এর ওজন সহ বেশিরভাগ টিএফ / কেরাস গ্রাফ সেট আপ করে - যা একটি উল্লেখযোগ্য মন্দার গ্যারান্টি দেয়।

কি হল অপ্রত্যাশিত মন্দার পরিমাণ হয় - আমার নিজের পরীক্ষা 10 ধা, এবং predict(), যা কোন ওজন আপডেট নেই। টিএফ 2 এর উত্স কোডটি দেখে, গ্রাফের উপাদানগুলি দৃ tight়ভাবে সংযুক্ত হয়ে দেখা যায়, প্রয়োজনীয় সংস্থানগুলি "সুষ্ঠুভাবে" বরাদ্দ করা হয় না with

উপর ডেভেলপারদের দ্বারা সম্ভাব্য Overlook predictএকটি uncompiled মডেল জন্য এর কর্মক্ষমতা, যেমন মডেলের সাধারণত কম্পাইল ব্যবহৃত হয় - কিন্তু বাস্তবে , এই একটি অগ্রহণযোগ্য পার্থক্য নেই। এটি একটি "প্রয়োজনীয় দুষ্টু" এটিও সম্ভব, কারণ এখানে একটি সাধারণ কাজ রয়েছে (নীচে দেখুন)।

এটি সম্পূর্ণ উত্তর নয়, এবং আমি আশা করি যে কেউ এখানে এটি সরবরাহ করতে পারে - যদি তা না হয় তবে আমি টেনসরফ্লোতে গিথুব ইস্যু খোলার পরামর্শ দেব। (ওপি রয়েছে; এখানে )


কার্যসংক্রান্ত : একটি মডেল প্রশিক্ষণ সংরক্ষণ তার, ওজন সংকলন ছাড়া মডেল, পুনরায় বিল্ড ওজন লোড করুন। সম্পূর্ণ মডেলটি সংরক্ষণ করবেন না (যেমন model.save()) এটি সংকলন লোড হবে - পরিবর্তে ব্যবহার করুন model.save_weights()এবং model.load_weights()

কার্যতালিকা 2 : উপরে, তবে ব্যবহার করুন load_model(path, compile=False); পরামর্শ ক্রেডিট: ডি মুলার


আপডেট : নির্মল, অপটিমাইজার হয় না সম্পূর্ণরূপে সঙ্গে instantiated compile, তার সহ weightsএবং updatestensors - এই কাজ করা হয় যখন একটি ঝুলানো ফাংশন প্রথম কল তৈরি করা হয় ( fit, train_on_batchইত্যাদি) মাধ্যমে model._make_train_function()

পর্যবেক্ষণ আচরণ এইভাবে আরও অদ্ভুত। আরও খারাপটি, অপ্টিমাইজারটি তৈরি করা কোনও আরও ধীরগতি বোঝায় না (নীচে দেখুন) - "গ্রাফের আকার" বোঝানো এখানে মূল ব্যাখ্যা নয়।


সম্পাদনা : কিছু মডেল, 30x মন্দা । টেনসরফ্লো, আপনি কি করেছেন? নীচে উদাহরণ:

from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
import numpy as np
from time import time

def timeit(func, arg, iterations):
    t0 = time()
    for _ in range(iterations):
        func(arg)
    print("%.4f sec" % (time() - t0))

ipt   = Input(shape=(4,))
x     = Dense(2, activation='relu')(ipt)
out   = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)

X = np.random.randn(32,4)

timeit(model.predict, X, 1000)
model.compile('adam', loss='binary_crossentropy')
timeit(model.predict, X, 1000)
model._make_train_function()  # build optimizer
timeit(model.predict, X, 1000)

ফলাফল :

0.9891 sec
29.785 sec
29.521 sec

1
এটা আকর্ষণীয়. model.fit()পারফরম্যান্সের ক্ষতি খুব বেশি কিনা তা দেখার জন্য আগ্রহী মৃত্যুদণ্ডের সাথে একটি স্থিতিশীল গ্রাফ বনাম একটি গতিশীল লুপের সাথে প্রশিক্ষণটি পরীক্ষা করতে চাইছি ...
ড্যানিয়েল মোলার

1
অতীতে আমি কেরাস এবং পাইটর্চের মধ্যে দ্রুত গতির পার্থক্য লক্ষ্য করতে পারছিলাম (পাইটর্চের উপায়ে দ্রুত হওয়া)।
ড্যানিয়েল মোলার

1
আমি এখানে একটি ইস্যু খুলেছি: github.com/tensorflow/tensorflow/issues/33340
99555

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

1
ইঙ্গিত, আপনি ব্যবহার করতে পারেন load_model(name, compile=False), এটি ওজন সংরক্ষণ / লোড করা এবং মডেলটি পুনরুদ্ধার করার চেয়ে সহজ।
ড্যানিয়েল মুলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.