TPUの重み保存

qiita.com

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

CAM

画像のどの領域が特定のラベル予測に貢献したかを確認するアプローチの1つ。

qiita.com

GPU 節約

 

環境

Ubuntu 20.04

 

Chrome

Chrome のハードウェア・アクセラレーションをオフにすれば良いだけ。

pc-karuma.net

 

変更前 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 を再起動

 

qiita.com

 

変更前 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

askubuntu.com

 

変更後 nvidia-smi

+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+

 

Cassava Leaf Disease Classification

Kaggleの Cassava Leaf Disease Classification コンペの振り返り。

 

メダル獲得に不足していたこと

  • 2019年度のコンペのデータを使用していなかった
  • ブレンディングのモデル数が2つと少なかった
  • Cutmixを使用していなかった
  • labelsmoothingを行っていなかった

 

 

Private 14位 の方法

 

www.kaggle.com

 

[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操作が行われたときに出る。

 

discuss.pytorch.org


これらのバージョンは、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