Changes 2.3.1 => 2.4.1

Modified

#1. GPUメモリ上で__getitem__, __setitem__を実行するよう変更.

パフォーマンスが向上

(1000, 1000)の行列'n'に対して__getitem__を1000回実行した結果.

getitem v2.3.1[sec] v2.4.1[sec]
n[0, 0] 0.51686 0.08107
n[0] 0.52871 0.08351
n[:, :] 1.50995 0.16364

#2. renom.concat() が可変引数に対応.

下記のようなコードが実行可能となった.

>>> import renom
>>> import renom as rm
>>> import numpy as np
>>>
>>> a = np.random.rand(2, 1)
>>> b = np.random.rand(2, 2)
>>> c = np.random.rand(2, 3)
>>>
>>> out = rm.concat(a, b, c) # Variable length argument can be passed.
>>> out.shape
(2, 6)

#3. renom.sum() に対し引数'axis'を指定可能.

下記のようなコードが実行可能となった.

>>> import renom as rm
>>> import numpy as np
>>>
>>> a = np.random.rand(2, 1)
>>> out = rm.sum(a)
>>> out.shape
()
>>> out = rm.sum(a, axis=0)
>>> out.shape
(1,)
>>> out = rm.sum(a, axis=1)
>>> out.shape
(2,)

#4. Nodeオブジェクトが持つメソッド 'T', 'transpose', 'reshape'が自動微分に対応.

下記のようなコードが実行可能となった.

>>> import renom as rm
>>> import numpy as np
>>>
>>> a = np.random.rand(2, 1)
>>> va = rm.Variable(a)
>>>
>>> print(rm.sum(va.T).grad().get(va)) # Auto differentiation of 'T'.
[[ 1.]
 [ 1.]]
>>> print(rm.sum(va.transpose(1, 0)).grad().get(va)) # AD of 'transpose'.
[[ 1.]
 [ 1.]]
>>> print(rm.sum(va.reshape(1, 1, 2)).grad().get(va) # AD of 'reshape'.
[[ 1.]
 [ 1.]]

#5. Yoloクラスの__init__メソッドにおける, 使用されなくなった引数'image_size'を削除.

Yoloクラスのインスタンス化時には 'image_size'引数を与えないよう注意. YoloクラスのAPIリファレンスを参照.

#6. Modelクラスのsaveメソッドを用いた重みパラメータ保存において重みパラメータ以外にもオブジェクトの属性を保存可能.

ModelクラスのAPIリファレンスを参照.

**#7.**TDAモジュールはReNomTDAレポジトリへ移動されました.

ReNomTDAモジュールは以下のURLからダウンロードすることができます./ReNom-dev-team/ReNomTDA

New features

#1. 自動微分に対応したrenom.amax, renom.aminを追加. APIリファレンスを参照.

GPUメモリプールを開放するための関数'renom.cuda.release_mem_pool'を実装.

Removed modules

Nothing

Bug fix

GPU上における, ブロードキャストが実行される行列の四則演算を修正.

v2.3.1では、下記の様なブロードキャストが行われる演算において正しい結果が返らないバグが見られた.

Bug example:
>>> import renom as rm
>>> import numpy as np
>>> from renom.cuda import set_cuda_active
>>>
>>> set_cuda_active(False)
>>> a = rm.Variable(np.arange(2).reshape(1, 2))
>>> print(a)
[[ 0.,  1.]]
>>>
>>> b = rm.Variable(np.arange(2).reshape(2, 1))
>>> print(b)
[[ 0.],
 [ 1.]]
>>>
>>> c = a + b # CPU is correct.
>>> print(c)
[[ 0.,  1.],
 [ 1.,  2.]]
>>>
>>> set_cuda_active(True)
>>> c = a + b # GPU was not correct.
>>> print(c)
[[ 0.,  2.],
 [ 0.,  0.]]

このバグは以下の条件をすべて満たした場合に発生する.

  1. Sequentialモデルを使わず, Variableの四則演算を用いて計算グラフを作成.
  2. GPUを用いて計算を実行.
  3. ブロードキャストが行われる(サイズが異なる行列同士の演算).
  4. 片方の行列の最後の次元が1かつ, もう片方の行列の最後の次元が1でない.

Sequentialモデルを用いてニューラルネットワークを構築していた場合, このバグは影響しない.

#2. 推論時におけるバッチ正規化層のエラー.

v2.3.1では推論計算時, バッチ正規化層においてCUDNN_STATUS_BAD_PARAMエラーが発生し, 計算が停止するbugがあった.

Bug example:
>>> import renom as rm
>>> import numpy as np
>>> from renom.cuda import set_cuda_active
>>>
>>> layer = rm.BatchNormalize()
>>> layer.set_models(inference=True) # Setting the layer as inference mode.
>>> a = rm.Variable(np.arange(2).reshape(2, 1))
>>> c = layer(a).as_ndarray()
Exception: b'CUDNN_STATUS_BAD_PARAM'

このバグは以下の条件をすべて満たした場合に発生する.

  1. GPUを用いて計算を実行.
  2. 学習計算を一度も実行せずに推論計算を実行.