pyenv
~/.bashrcを変更
export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" export PATH="$PYENV_ROOT/shims:$PATH" eval "$(pyenv init -)"
source ~/.bashrc
TPUの重み保存
def get_model_weights_as_numpy(model): weights = {} for v in model.weights: # model.weightsで各Layerの重みを取り出し # 各variableはnumpyメソッドでnumpy配列に変換できる weights[v.name] = v.numpy() return {'model_name': model.name, 'weights': weights} def get_optimizer_weights_as_numpy(optimizer, model): weights = {} slot_names = optimizer.get_slot_names() for v in model.weights: try: # model.weightsで各Layerの重みを取り出し weights[v.name] = {} for slot in slot_names: # 各Slotに対し、optimizerのget_slotで値を取り出す weights[v.name][slot] = optimizer.get_slot(v, slot).numpy() except: pass return {'optimizer_name': optimizer._name, 'weights': weights} def save_weights_as_pickle(file_prefix, optimizer, model): model_weights = get_model_weights_as_numpy(model) optimizer_weights = get_optimizer_weights_as_numpy(optimizer, model) all_weights = {'model': model_weights, 'optimizer': optimizer_weights} with open(file_prefix + '.pkl', 'wb') as f: pickle.dump(all_weights, f) def set_model_weights_from_numpy(weights, model): for v in model.weights: if v.name in weights.keys(): v.assign(weights[v.name]) else: print('Not loaded weights: ' + v.name) def set_optimizer_weights_from_numpy(weights, optimizer, model): # optimizerの名前でscopeする with tf.name_scope(weights['optimizer_name']): optimizer_weights = weights['weights'] for v in model.weights: if v.name in optimizer_weights.keys(): for slot in optimizer_weights[v.name].keys(): # 学習済みの重みを初期値としてslotを作成 initializer = tf.initializers.Constant(optimizer_weights[v.name][slot]) optimizer.add_slot(v, slot, initializer=initializer) else: print('Not loaded optimizer weights: ' + v.name) def load_weights_from_pickle(file_prefix, optimizer, model): with open(file_prefix + '.pkl', 'rb') as f: weights = pickle.load(f) # modelの重みを復元(後述) # set_model_weights_from_numpy(weights['model'], model) # optimizerの重みを復元(後述) set_optimizer_weights_from_numpy(weights['optimizer'], optimizer, model) # モデル読み込み if epoch > 0: model.load_weights(f'{SAVE_MODEL_ROOT}/model.h5') load_weights_from_pickle(file_prefix, model.optimizer, model) # モデル保存 model.save_weights(f'{SAVE_MODEL_ROOT}/model.h5') save_weights_as_pickle(file_prefix, model.optimizer, model)
HumanProteinAtlasコンペ
タスクの内容
こんにちは。私は初心者なので、私の質問は非常に基本的なものに見えるかもしれません。
私は主催者から提供されたデータを持っています。そこで、セグメンテーションマスクを生成した後、
そのマスクはグランドトゥルースとして機能するのでしょうか?
インスタンス・セグメンテーションとシングルセル・セグメンテーションの違いは何ですか?
私の理解では、インスタンスセグメンテーションでは、セルとラベルを瞬時にマッピングできるということでしょうか?
これらは同じだと思います。
セルを分割して、それぞれのセルにラベルを割り当てる必要があります。
その意味では、今回の競技課題(シングルセルセグメンテーション)は、インスタンスセグメンテーションです。
通常のインスタンスセグメンテーションとの唯一の違いは、セグメント情報とセルレベルのラベルが学習データとして与えられておらず、
画像レベルのラベルのみが与えられていることです。
そのため、この課題は弱教師付きインスタンス・セグメンテーションと呼ばれます。
OKです。主催者が画像を提供してくれました。
私たちの仕事は、HPAのセグメンテーションを使用して、
トレーニング時に使用するグランドトゥルースを生成することです。私の理解は正しいでしょうか?
はい、そのような方法があります。
それ以外にも、弱い教師を使った方法を試すこともできます。
インスタンス・セグメンテーション・マスクのエンコード
インスタンス・セグメンテーション・マスクをエンコードするpython関数の例は以下の通りです。
import base64 import numpy as np from pycocotools import _mask as coco_mask import typing as t import zlib def encode_binary_mask(mask: np.ndarray) -> t.Text: """Converts a binary mask into OID challenge encoding ascii text.""" # check input mask -- if mask.dtype != np.bool: raise ValueError( "encode_binary_mask expects a binary mask, received dtype == %s" % mask.dtype) mask = np.squeeze(mask) if len(mask.shape) != 2: raise ValueError( "encode_binary_mask expects a 2d mask, received shape == %s" % mask.shape) # convert input mask to expected COCO API input -- mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1) mask_to_encode = mask_to_encode.astype(np.uint8) mask_to_encode = np.asfortranarray(mask_to_encode) # RLE encode mask -- encoded_mask = coco_mask.encode(mask_to_encode)[0]["counts"] # compress and base64 encoding -- binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION) base64_str = base64.b64encode(binary_str) return base64_str
GPU 節約
環境
Ubuntu 20.04
Chrome
Chrome のハードウェア・アクセラレーションをオフにすれば良いだけ。
変更前 nvidia-smi
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 965 G /usr/lib/xorg/Xorg 35MiB |
| 0 N/A N/A 1715 G /usr/lib/xorg/Xorg 112MiB |
| 0 N/A N/A 1843 G /usr/bin/gnome-shell 91MiB |
| 0 N/A N/A 33450 G ...AAAAAAAAA= --shared-files 65MiB |
+-----------------------------------------------------------------------------+
変更後 nvidia-smi
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 965 G /usr/lib/xorg/Xorg 35MiB |
| 0 N/A N/A 1715 G /usr/lib/xorg/Xorg 91MiB |
| 0 N/A N/A 1843 G /usr/bin/gnome-shell 85MiB |
+-----------------------------------------------------------------------------+
VSCode
- Cmd + Shift + P でコマンドパレットを起動する
- configure runtime arguments を入力し、 argv.json の編集画面に移動する
- "disable-hardware-acceleration": true を追記する
- VSCode を再起動
変更前 nvidia-smi
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 965 G /usr/lib/xorg/Xorg 35MiB |
| 0 N/A N/A 1715 G /usr/lib/xorg/Xorg 134MiB |
| 0 N/A N/A 1843 G /usr/bin/gnome-shell 83MiB |
| 0 N/A N/A 40447 G ...AAAAAAAA== --shared-files 36MiB |
+-----------------------------------------------------------------------------+
変更後 nvidia-smi
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 965 G /usr/lib/xorg/Xorg 35MiB |
| 0 N/A N/A 1715 G /usr/lib/xorg/Xorg 107MiB |
| 0 N/A N/A 1843 G /usr/bin/gnome-shell 87MiB |
+-----------------------------------------------------------------------------+
ディスプレイなど
$ sudo vim /usr/share/X11/xorg.conf.d/10-nvidia.conf
で全ての行をコメントアウト。
$ sudo systemctl restart display-manager
変更後 nvidia-smi
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
opencv
$ sudo apt-get install libopencv-* $ conda remove opencv $ conda install -c conda-forge opencv $ pip install opencv-contrib-python
Cassava Leaf Disease Classification
Kaggleの Cassava Leaf Disease Classification コンペの振り返り。
メダル獲得に不足していたこと
- 2019年度のコンペのデータを使用していなかった
- ブレンディングのモデル数が2つと少なかった
- Cutmixを使用していなかった
- labelsmoothingを行っていなかった
Private 14位 の方法
[0, 1, 2, 3, 4] という本来の分類モデルが33個、病気か否かの[0, 1] の分類を行うモデルが1個、ImageNetで事前学習された、[0, ... 999] の分類を行うモデルが1個。合計35個のモデルの出力値をLightGBMでスタッキングするというアーキテクチャ。最後の、1000classのモデルを使用している点が興味深かかった。
コードはこちら。
TabNetRegressorをRMSEで学習
torch.autograd.backward()時に、
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor []], which is output 0 of SqrtBackward, is at version 1; expected version 0 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later. Good luck!
のエラーが生じた。これはinplace操作が行われたときに出る。
これらのバージョンは、Tensorがインプレースで変更された回数を追跡します。変更するたびにバージョンが上がります。
手動でバージョンを変更することはできません。間違ったバージョンでエラーが発生した場合は、バージョンがぶつからないようにインプレース操作を削除する必要があります。
lossをいったんcopyして、それを返すとエラーが生じなくなった。
class RMSELoss(torch.nn.Module): def __init__(self): super(RMSELoss, self).__init__() def forward(self, x, y): criterion = nn.MSELoss() loss = torch.sqrt(criterion(x, y)) return loss