Last active
June 18, 2020 06:34
-
-
Save yatszhash/83f1e9dc7eef273676a2620761d1c283 to your computer and use it in GitHub Desktop.
tips to manage or save the memory usage for kernel competitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"cells":[{"metadata":{"_uuid":"1449f1cbe3436d1f98c82429062dddc18e978bf6"},"cell_type":"markdown","source":"# Introduction \n\n***[kaggle Advent Calendar 2018](\"https://qiita.com/advent-calendar/2018/kaggle\") 9日目の記事です。***\n \n \nギリギリになりましたが、qiita kaggle アドベントカレンダー2018の記事を投稿いたします。 \nnotebokをわざわざmarkdownに変換するのもどうかと思うので、 \ngistに投稿させていただきます。 \n\nkaggleでは、メルカリは初めとしてカーネルだけで前処理・モデルのトレーニング・テストデータに基づく予測を完結させるカーネルコンペが行われるようになりました。 \n今もカーネルコンペが2つひらかれています。\n\nそこで、もはや何番煎じかわかりませんが、 \nカーネルコンペで役に立つ(かもしれない)pythonのメモリ使用量管理・節約のためのtipsをまとめてみました。 \nといってもほとんどは基本的な知識に基づくものです。\n<!--** Sorry, please wait for a while to translate the kenerl into English completely !!! **-->"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# some large memory data\ncreate_large_df = lambda : pd.DataFrame(np.random.rand(100, 100), columns=[ \"col_{}\".format(n) for n in range(100)])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"59b6c0fa1888a30c4ca7871f7619bd9f61847201"},"cell_type":"markdown","source":"# 1. メモリを計測する \n<!--measure usage or memory-->\n\n最適化のためには、まずは何より”計測すること”が基本です。 "},{"metadata":{"_uuid":"a1abd5ec051dbc8e6e623f53d2f7edcf3d13ad2a"},"cell_type":"markdown","source":"## 使用量と使用可能なメモリ \n<!--usage and available memory-->"},{"metadata":{"trusted":true,"_uuid":"b0c6700ba20af858d435c3de4f33a36a6052eed1"},"cell_type":"code","source":" df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c31ca4d0f8bb803765cf8b5c6275c10594bb10da"},"cell_type":"code","source":"import psutil","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e92ecaaff26192b1b9aab84c3f6ba928026e9a25"},"cell_type":"code","source":"# expressed in bytes\npsutil.virtual_memory()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9e543c46e2a9795c0aac8dd2eafc028404829620"},"cell_type":"markdown","source":"## オブジェクトのメモリー使用量\n<!--memory usage of a object-->"},{"metadata":{"trusted":true,"_uuid":"0cfd54a8d9abe95474186130cc052a26a17b47ef"},"cell_type":"code","source":"import sys","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c3967cdb0dffd0990a7ab605b31eb7cf726927cf"},"cell_type":"code","source":"sys.getsizeof(df)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3f5f4a15b417d18a7008f2c22067b1a59855bc77"},"cell_type":"markdown","source":"## グローバル・ローカルスコープのオブジェクトごとのメモリ使用量 \n<!--memory usage of each object in global and local scope -->"},{"metadata":{"trusted":true,"_uuid":"ab60f6363bb076c63cf87d7d2632d01afd1737e6"},"cell_type":"code","source":"global_obj_memory_usage = [(v, sys.getsizeof(eval(v))) for v in globals()] # 直接ループを回すと、途中でオブジェクト数が変わるのでエラーになる\nfor name, size in global_obj_memory_usage:\n print(\"{}: {} byte\".format(name, size))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"167b0c1f168bdbd16abcfa6b0a5a5d58f0f54beb"},"cell_type":"code","source":"# you can also use dir() instead of locals()\nlocal_obj_memory_usage = [(v, sys.getsizeof(eval(v))) for v in locals()] # 直接ループを回すと、途中でオブジェクト数が変わるのでエラーになる。\nfor name, size in local_obj_memory_usage:\n print(\"{}: {} byte\".format(name, size))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"109c0c108272655e26e78202f5559b5a6913fe5a"},"cell_type":"markdown","source":"# 2. アルゴリズムに合わせたデータ構造\n<!--data structures or data steps to meet algorithms you use--> "},{"metadata":{"_uuid":"97a93efc9ae95260c552a8130342c6d9d4742f33"},"cell_type":"markdown","source":"<!--Some libraries have more efficient data structures for thier algorithms.-->\nいくつかのライブラリはそのアルゴリズム用により効率が良いデータ構造を持っています。 \n例えばlight lgbを使う場合、*Dataset* classが使えます。 \n*Dataset*は離散ビンでデータを保持するため、numpyの連続値で保持するよりメモリ効率が良いです。\n参考: https://lightgbm.readthedocs.io/en/latest/Python-Intro.html#data-interface"},{"metadata":{"trusted":true,"_uuid":"0e12b29ffa0cf5785ed133a45b2177b8ea077599"},"cell_type":"code","source":"df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5e5f8b13cd7d7289e785830ea0e0c84655d723a6"},"cell_type":"code","source":"sys.getsizeof(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5117f1ffabf7ab215c9e265e09cbba9a12dc2c6f"},"cell_type":"code","source":"import lightgbm as lgb\nimport gc\ndataset = lgb.Dataset(df, free_raw_data=True)\ndataset.raw_data = None\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"02b48897416818dc0369c8b282e3ff55938d64aa"},"cell_type":"code","source":"sys.getsizeof(dataset)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"20d1c00c7f96eef4a365595a03ca61172d2c9331"},"cell_type":"markdown","source":"ただし、 numpyのndarrayのままsklearn-apiを使ったほうがpipelineなどが使えるので、可読性・保守性は上がるかもしれません。"},{"metadata":{"_uuid":"d89eef83b3438c83538c639ffb7bbfa2cd14d305"},"cell_type":"markdown","source":"# 3. よりメモリ量の少ないdata typeを選ぶ/に変換する"},{"metadata":{"_uuid":"a79444ae51d2f328886f4073a02f9952333a301b"},"cell_type":"markdown","source":"# 早めにlabel encoding/one hot encodingする"},{"metadata":{"_uuid":"0db39dc505f532151963107aceac23bdbab5ec4a"},"cell_type":"markdown","source":"テキストやクラスのフィールドは、カテゴリ化やlabel encoding/one hot encodingできるものがあります。\nデータタイプや内容によりますが、そうしたほうがメモリ使用量は減ります。\n例えばpandasなら以下のようになります。"},{"metadata":{"trusted":true,"_uuid":"96528e395f61eb6ddec22d13c75fa875f753c168"},"cell_type":"code","source":"x = pd.DataFrame(np.vstack([np.zeros((100, 1), dtype=\"int32\"), \n np.ones((100, 1),dtype=\"int32\"), \n np.ones((100, 1), dtype=\"int32\") * 2]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"24c1e3158da81997e5b87c55d59654ccb5fad7e9"},"cell_type":"code","source":"sys.getsizeof(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2e91b94e0b84570d2b31e1684618d36349da961d"},"cell_type":"code","source":"x[0] = x[0].astype(\"category\") ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"65b4124319601c0c67200648dfdfbbd0a5a14486"},"cell_type":"code","source":"sys.getsizeof(x)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"78a9500b766b19883eb26951b9dba5fb6648c87e"},"cell_type":"markdown","source":"## スパースなデータには、対応したデータ構造を選ぶ\n例えば、pandasのdataframeでスパースなデータを保持するよりもscipyのsparseで保持したほうがメモリ効率は良いです。"},{"metadata":{"trusted":true,"_uuid":"7072e458228be14b6d8637ee1182b1abfbd5fa09"},"cell_type":"code","source":"x = pd.DataFrame(np.vstack([np.zeros((100, 1), dtype=\"int32\"), \n np.ones((100, 1),dtype=\"int32\"), \n np.ones((100, 1), dtype=\"int32\") * 2]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e35ceb40c22371d91d8f344bf5869188cd495599"},"cell_type":"code","source":"x[[0, 1, 2]] = pd.get_dummies(x[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"25b9fb142ff9921b057001ca25b7f443e84f8023"},"cell_type":"code","source":"sys.getsizeof(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6c80e7854e16d68b488328980e266c5b0a5ee0ed"},"cell_type":"code","source":"import scipy.sparse as sparse","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c2c36f9d7739fbd6f79b9f009cda4f66849b71f8"},"cell_type":"code","source":"y = sparse.csr_matrix(x[[0, 1, 2]].values)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4947dcfe80c4b962629cd27bb97279cedd78a586"},"cell_type":"code","source":"sys.getsizeof(y)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7d598f7a71fddd9b014c0e78a1521b7155333667"},"cell_type":"markdown","source":"ただし、pandasのほうが取り回しはしやすいです。"},{"metadata":{"_uuid":"1d722c623a91697d21a934fa7fcafbebc71e87a2"},"cell_type":"markdown","source":" ## 有効数字の桁数を考えて、演算結果のデータタイプを選ぶ"},{"metadata":{"_uuid":"5b846f1d2275086ea73ee212faeef3d24a30a515"},"cell_type":"markdown","source":"int8同士の演算なのに、その結果を表すのにfloat64の精度は必要ありません。符号部・指数部を考慮してもせいぜいfloat16で十分でしょう。"},{"metadata":{"trusted":true,"_uuid":"7628cc4f37866e1df1e6b6d208dba4b59a85f36e"},"cell_type":"code","source":"x = np.arange(10, dtype=\"int8\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"26883fd589991c5a0ff72139c943bb35c8b32abb"},"cell_type":"code","source":"y = x / 8","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8c12548e8cc36f7ad113aedcdd2300a2e124b2e"},"cell_type":"code","source":"y.dtype","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9f20c5f2b0253fdcc30a7c7de8e2d6d24f6206f3"},"cell_type":"code","source":"for n in y:\n print(\"{:.32f}\".format(n))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"01a0a2ab18c7c762ea0b6dc4a3de0c773bbeb51b"},"cell_type":"code","source":"y = y.astype('float16')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cdf1cf43b09b6b3bb5e590975298b4f86da0e474"},"cell_type":"code","source":"for n in y:\n print(\"{:.32f}\".format(n))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"404759a5abc8d996e598c3d0464c8e072995703a"},"cell_type":"markdown","source":"# アルゴリズムに合わせてdown castする\nアルゴリズムによりますが、本当に入力データにそこまでの精度が必要か考えましょう。 \nnumpyのint/floatのデフォルトがint64/float64なので、気づかないうちに必要精度以上のメモリを確保していることがあります。 \ndeep learningなら、例えばchainerはそもそも多くの場所でfloat32でないと入力できないそうです。(参考: https://www.slideshare.net/beam2d/chainer-52369222 )\n"},{"metadata":{"_uuid":"fa66e5acec0f95fb2450722ff1600639303d00df"},"cell_type":"markdown","source":"## 3. ライブラリ内の処理でのデータコピーに注意する"},{"metadata":{"_uuid":"33b61a057884ef36ad715fd7e14520426680cb08"},"cell_type":"markdown","source":"ライブラリ内の処理の中には内部で元のデータをコピーして利用するものがあります。 \n\n例えば、numpy.ndarrayを引数としたときの[pytorchのtensor()](https://pytorch.org/docs/stable/tensors.html)が該当します。 \n逆にコピーしないものとしては、[torch.as_tensor()](https://pytorch.org/docs/stable/tensors.html)が該当します。 "},{"metadata":{"_uuid":"60b0c0a9de21d0de1d96afc77df36f3cda9b000f"},"cell_type":"markdown","source":"# 4. 変数のスコープに注意する \n<!--Be careful for variables in a scope -->\n"},{"metadata":{"_uuid":"8b024182d29307831b2ff6e944b1a219952d12f6"},"cell_type":"markdown","source":"## スコープを小さく保つ\nプログラミング的には非常に基本的なことですが、スコープ・変数の寿命は小さく保ちましょう。 \n\n当然スコープから抜けるとき(returnするときなど)オブジェクトが削除されるので(gcがすぐに走るとは限りませんが・・・), \n自分でメモリ上のオブジェクトを管理する必要がなくなります。 \n普段のプログラミングと違い、きれいなコードよりスピードが優先される分析の場合、ついついスコープが大きくなりがちです。 \n特にjupyter notebookの場合長くなってくると、 \nオブジェクトの削除を忘れて先に実行したセルのオブジェクトが残り続けていることがあるので要注意です。"},{"metadata":{"_uuid":"84a8f3ab7cb56ee891a2868937207a8373b73f9d"},"cell_type":"markdown","source":"# 5. 手動gc/reassign"},{"metadata":{"_uuid":"06d6cd779b306b936849d8da1fe3fd80121af749"},"cell_type":"markdown","source":"理想的には変数のスコープを小さくするなどで対処したいところですが、それができない場合も多々あります。 \nその時は自分でオブジェクトを削除したり、再代入したりします。"},{"metadata":{"trusted":true,"_uuid":"53e24019692cef74325ca1811435e83def7a3ec6"},"cell_type":"code","source":"import gc","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e159dc713612c7ef41a21a4bfcc5874013365c73"},"cell_type":"markdown","source":"## 手動gc"},{"metadata":{"trusted":true,"_uuid":"92be7b4c3cb4e0dff28a8c58f14da7bb6a8c46d4"},"cell_type":"code","source":"df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eefe995e590799f8e9abfeb2e1fa1d39ca7af88f"},"cell_type":"code","source":"del df\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"51b1b441673360f6067592487e39d6888f327a33"},"cell_type":"code","source":"try: \n sys.getsizeof(df)\nexcept NameError as e:\n print(e)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7c2e56ab57a18168b42c1a3f030970ccf22222f5"},"cell_type":"markdown","source":"## 再代入"},{"metadata":{"trusted":true,"_uuid":"1f0665c3f5c3a995f5cef3043bc84fcafbac9120"},"cell_type":"code","source":"df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"52abe6e8f5678acc38df53cccaeebc4ce21b5de7"},"cell_type":"code","source":"df = None","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ecd61692d0ea68e5cd6f0462f02cecda9578096a"},"cell_type":"markdown","source":"ただし、再代入の順番には注意が必要です。 \n例えば、以下の様な一時的に3つのarrayがメモリー上に存在することになります。"},{"metadata":{"trusted":true,"_uuid":"82f70918da87abdcdd82d24cfff88d2842beed66"},"cell_type":"code","source":"x = np.arange(100, 3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"50d53d16a2345f5ede10f45c7d0dd4a33cca5ff0"},"cell_type":"code","source":"x, y = x[:70], x[:30]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"18437b6aa4a876860ed0c4047714a2407591d077"},"cell_type":"markdown","source":"一時的なメモリ増加を押さえたいなら、冗長ですが以下のような順番にします。"},{"metadata":{"trusted":true,"_uuid":"b136ef2331f158c9215ccbdf93124f23253b1fd5"},"cell_type":"code","source":"y = x[:30]\nx = x[:70]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dc2a35edbded460e6400cdc8f61e84a634d24b47"},"cell_type":"markdown","source":"## local scope外のgc/reassign\nメソッドの中で、メモリーを確保するために、\n以下のように渡されたオブジェクトを削除したいことがあるかもしれません。 \n(副作用になるので設計的にはいいとは言えませんが・・・)"},{"metadata":{"_uuid":"5be885b770f159bdce5353a1588e2412ccaefab8"},"cell_type":"markdown","source":""},{"metadata":{"trusted":true,"_uuid":"b157481cb4a87bc0a0d5c3ebbedf712b40a35ff2"},"cell_type":"code","source":"df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8c819c63ce48f1c3c1683ad32c7bed16b46638b8"},"cell_type":"code","source":"def large_memory_usage_function(obj):\n # なんかの演算 computation part1\n \n # このdelはローカル変数の\"obj\"だけを削除する。外のスコープにある元のオブジェクトは残る\n # this \"del\" delete only local variable \"obj\" in this function scope. The original object in the outer scope remains. \n del obj\n gc.collect()\n \n # メモリーを使うなんかの演算 computation part2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f10227a75340832609f7f7cc6ad53391158a5c31"},"cell_type":"code","source":"sys.getsizeof(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a504d75c29e7c8c67fc1f5a4a6d33b0a2e26cd44"},"cell_type":"code","source":"large_memory_usage_function(df)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b2da6c633018619d91a8388e83211a231ab3b8b3"},"cell_type":"markdown","source":"しかし、これでは外のスコープにある変数は削除されません。"},{"metadata":{"trusted":true,"_uuid":"7e0fbfb92b9fc1ae5311d3b6117665f96a5b7b7a"},"cell_type":"code","source":"sys.getsizeof(df)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f32dcc154fa0da7aa7b6f6bdacac9a4809b69f56"},"cell_type":"markdown","source":"ではどうするかといいますと、methodを2つのパートに分けて外のスコープでgcか再代入をするしかありません。 \n<!--You should spilit the function into two function, one returns None or empty object (etc. list, array...) and the other part.--> "},{"metadata":{"trusted":true,"_uuid":"f1deb3ff8ed63a6a20d0843030f56a970542ff18"},"cell_type":"code","source":"def computation1_return_none(df):\n # computation part1\n return None","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bc44b0c652c193ec1ce328d131a7b0d992373082"},"cell_type":"code","source":"def computation2():\n # computation part2\n pass","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f2bc4f357940f70c65f66893256d7536c31782fc"},"cell_type":"code","source":"df = computation1_return_none(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a2c35b20efe82753ea74e91093dd8cf3ad19f2be"},"cell_type":"code","source":"sys.getsizeof(df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c08d66cb5ddfba8541e59cd2ae6b81950d5e2fc"},"cell_type":"code","source":"computation2()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c11c82e85f1f4df8c352b69636cf629e464f245f"},"cell_type":"markdown","source":"なんらかの理由でどうしてもglobal scopeの変数をメソッドの中から削除したいとき、 \n\"gloabal\" statementを使います。\n<!--If you wan to free an object of the outer scope in a function for some reason, please use \"global\" statement. (Of cource, it's not recommended for safe programming)-->"},{"metadata":{"trusted":true,"_uuid":"3743ec0b07fdba16dd6fbff83b17b2597b386815"},"cell_type":"code","source":"df = create_large_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f9d26cf32d1f21f4f14aad4ea00254fa0326e52d"},"cell_type":"code","source":"def gc_df():\n global df\n gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"46e8722297414bc76fad9147031c47b062f615a2"},"cell_type":"code","source":"gc_df()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"901a73866d8ed19f04baf60e8053a89f339f6570"},"cell_type":"markdown","source":"# 6. 一時的にディスクに書き出す・ディスクから少しずつロードする\n\nIOによる処理速度低下とのトレードオフですが、\nすぐに使わないオブジェクトはpickleなどで書き出してしまうのも常套手段です。 \n\nただしカーネルコンペの場合ディスク容量が5GB等少ないので注意です。 \nまた、データをディスクから少しずつロードすることも定番ですが、 \nコンペのルールによってはそれができないものもあります。 "},{"metadata":{"_uuid":"5b29a62ae632d788440d8a353b1d42e2a633abc4"},"cell_type":"markdown","source":"# 7. 処理の並列度を下げる\n\nどう並列化するかによりますが、\n例えばjoblibのparallelなどは必要なオブジェクトを\n並列度の分コピーしてしまうため、場合によっては並列度を下げたほうがよさそうです"},{"metadata":{"_uuid":"c2c7fa6af74457c96165c5946b8a4720298d5656"},"cell_type":"markdown","source":"# outro\n基本的なことが中心ですが、\nメモリーの管理ができていないとカーネルが落ちたりして大きなロスにつながります。 \n(2 stage コンペなら、errorでスコア無しになることも・・・) \n思い出すためにも役に立つと幸いです。 "},{"metadata":{"trusted":true,"_uuid":"a989a10827f41e55018a9e9e6884f8d31c47f9d8"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment