SlideShare a Scribd company logo
NumPy闇入門
2016/1/28 PFIセミナー
(株)Preferred Networks
奥田 遼介
自己紹介
奥田 遼介
 -2014東北大学 修士
 文字列処理など
 2014 (株)プリファードインフラストラクチャー
 2014- (株)プリファードネットワークス
 映像解析系、製造業系にかかわる研究開発
 ChainerやCuPyの開発
 趣味
 読書、高速化
NumPyとはなにか
 Python上で数値計算を効率的に行うためのライブラリ
 NumPyがあるからPythonを使うくらい重要
In [1]: import numpy as np
In [2]: np.ones((2, 1)) + np.arange(3)
Out[2]:
array([[ 1., 2., 3.],
[ 1., 2., 3.]])
NumPy闇入門とは
 Chainer開発勢がChainerやCuPyを作る過程で遭遇した
NumPyのちょっと変な挙動(闇)を集めたもの
 バグ、仕様なのか不明な場合も・・・
NumPy闇入門とは
 Chainer開発勢がChainerやCuPyを作る過程で遭遇した
NumPyのちょっと変な挙動(闇)を集めたもの
 バグ、仕様なのか不明な場合も・・・
 普通の人々はたいてい気づかないものばかりです
 ずっと気づかずにいた方が幸せです
 今回はクイズ形式で10問の闇を用意しました
 クイズの作りが悪いのでだいぶ簡単です(たぶん)
 何問正解できるか挑戦してみてください
 断りが無い場合以下の環境を想定しています
 x86_64+Ubuntu64bit + Python 2.7 + NumPy 1.10.4
注意事項
 変な挙動を「闇」と表現してしますが、NumPyを貶める
ような意図はありません。NumPyはすばらしいです
 紹介する闇に関しては解説をしていますが、NumPyの
ソースコードを読まないと(読んでも)理解できない箇
所があると思います。ご了承ください
型の闇
Pythonの型、NumPyの型
 Pythonの数値型は少ない
 bool
 int, (long)
 float
 complex
 NumPyはたくさん
 NumPyはPure Cのライブラリ
 演算効率のためにC互換の型が沢山
 CとPythonの融合した型システム
 →闇の温床
NumPyの型の表現
 2~3種類の表現がある
 np.int32 # Python type
 np.dtype(‘int32’) # dtype
 ‘i’ # Character code
 お互いに変換可能
 np.dtype(np.int32) #=> dtype(‘int32’)
 np.dtype(‘i’) #=> dtype(‘int32’)
 np.dtype(‘int32’).type #=> np.int32
 np.dtype(‘int32’).char #=> ‘i’
型の闇 練習問題
 np.zeros(2, np.int32) + np.zeros(2, float) の演算結果のdtype
は?
 A. dtype(‘float32’)
 B. dtype(‘float64’)
 C. dtype(‘float’)
 D. わからない
型の闇 練習問題
 np.zeros(2, np.int32) + np.zeros(2, float) の演算結果のdtype
は?
 A. dtype(‘float32’)
 B. dtype(‘float64’)
 C. dtype(‘float’)
 D. わからない
 正解はB
 int32を十分に表現可能なfloat64にキャストされて演算が行われ
ます
 選択肢C のようなdtypeは無いです dtype(‘float64’)になります
型の闇 その1
 np.zeros(2, np.int64) + np.zeros(2, np.float64) の演算結果の
dtypeは?
 A. dtype(‘float32’)
 B. dtype(‘float64’)
 C. dtype(‘float128’)
 D. わからない
型の闇 その1
 np.zeros(2, np.int64) + np.zeros(2, np.float64) の演算結果の
dtypeは?
 A. dtype(‘float32’)
 B. dtype(‘float64’)
 C. dtype(‘float128’)
 D. わからない
 正解はB
 np.float128は実在します
 C言語相当なので自動でnp.float128にはならない
 np.can_cast(np.zeros(2,np.int32), np.float32) # => False
 np.can_cast(np.zeros(2,np.int64), np.float64) # => True
型の闇 その2
 0 + np.float16(0) の演算結果のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
型の闇 その2
 0 + np.float16(0) の演算結果のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
 正解はC
 0はint つまりこの環境ではnp.int64となる
 np.int64(0) + np.float16(0)という計算に相当するため、np.float64が
正解
型の闇 その3
 変数aの型がintの時、a + np.zeros(2, np.float32) の演算結
果のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
型の闇 その3
 変数aの型がintの時、a + np.zeros(2, np.float32) の演算結
果のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
 正解:D
 変数aの値の大きさによってnp.float32か、np.float64になる
 例えば -32768<= a <= 65535 であればnp.float32
 変数aがスカラー相当の値の場合は同じ挙動
 Chainerではまることが多いケースなので注意
型の闇 その4
 np.array([10], np.int32)+ np.zeros(2, np.float32) の演算結果
のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
型の闇 その4
 np.array([10], np.int32) + np.zeros(2, np.float32) の演算結果
のdtypeは?
 A. dtype(‘float16’)
 B. dtype(‘float32’)
 C. dtype(‘float64’)
 D. わからない
 正解:C
 np.array([10], np.int32)はスカラー相当ではないので、普通のキャ
ストが行われる
型の昇格の話
 スカラー相当の値とは?
 Pythonのbool, int,np.int32, np.float64・・・
 0次元のndarray:shapeが長さ0であるもの
 1次元以上だとスカラー相当ではないので注意
 スカラー、ベクトル同士の規則は表現精度に基づき決定
 スカラーとベクトルの場合は以下の通り
 Kindの大きさを比較(bool -> 0, int, uint -> 1, float ->2)
 スカラー側のkindが大きい→dtypeの表現精度に基づき決定
 それ以外→ スカラー値を表現可能な最小の型を利用
 (np.array([10,10], np.int16) + np.float16(10)).dtype # => dtype('float32')
 (np.array([10,10], np.float16) + np.int16(10)).dtype # => dtype('float16')
 255まではnp.float16になる
型の闇 その5
 np.longlong, np.int_, np.intp はnp.dtype化すると全て
「dtype(‘int64’)」になる。正しいのはどれ?
 A. np.longlong は np.int64 と等しくない
 B. np.int_ は np.int64 と等しくない
 C. np.intp は np.int64 と等しくない
 D. 全部 np.int64 と等しい
型の闇 その5
 np.longlong, np.int_, np.intp はnp.dtype化すると全て
「dtype(‘int64’)」になる。正しいのはどれ?
 A. np.longlong は np.int64 と等しくない
 B. np.int_ は np.int64 と等しくない
 C. np.intp は np.int64 と等しくない
 D. 全部 np.int64 と等しい
 正解:A
 numpyには、nump.int64が2つある(こともある)
 Windowsだとnumpy.int32が2つある(こともある)
 C言語でlong long とintと longが分かれている事に由来する
なぜこんなに複雑になってしまったのか?
 わかりません
 推測:使っていて良い感じになるようにしたかった
 ちなみに0次元ndarrayは気づくと単なるスカラー変数になってい
たりします
 type(np.array(10) + 10) #=> numpy.int64
 CuPyはどこまで同じ挙動を再現しているのか?
 0次元ndarrayと1次元以上のndarrayの演算の時のみ違う挙動
 GPU上にある値で型が変わる挙動は性能への影響が大きいため
 どうやってこの挙動を再現したのか?
 本家のコードを読みました
 バージョンが変わると結構変わったりします
 v1.10でデフォルトのcasting ruleが変わったり
関数の闇
関数の闇 その1 expand_dimsの闇
 expand_dimsは長さ1の次元を挿入する関数である
 np.expand_dims(np.zeros((2,3,4)), -1).shape
 #=>(2, 3, 4, 1)
 -1の時は一番後ろに次元を挿入してくれる
 np.expand_dims(np.zeros((2,3,4)),-5).shape は?
 A. (1, 2, 3, 4)
 B. (2, 3, 4, 1)
 C. (2, 3, 1, 4)
 D. 例外で落ちる
関数の闇 その1 expand_dimsの闇
 expand_dimsは長さ1の次元を挿入する関数である
 np.expand_dims(np.zeros((2,3,4)), -1).shape
 #=>(2, 3, 4, 1)
 -1の時は一番後ろに次元を挿入してくれる
 np.expand_dims(np.zeros((2,3,4)),-5).shape は?
 A. (1, 2, 3, 4)
 B. (2, 3, 4, 1)
 C. (2, 3, 1, 4)
 D. 例外で落ちる
 正解はC
関数の闇 その1 expand_dimsの闇
 expand_dimsの正の方向は循環せず止まる
 0 #=> (1, 2, 3, 4)
 1 #=> (2, 1, 3, 4)
 2 #=> (2, 3, 1, 4)
 3 #=> (2, 3, 4, 1)
 4 #=> (2, 3, 4, 1)
 マイナスの方は不完全な2週目がある
 -3 #=> (2, 1, 3, 4)
 -4 #=> (1, 2, 3, 4)
 -5 #=> (2, 3, 1, 4)
 推測: Pythonの配列では普通に負のインデックスが使える
 -1を特別扱いした→なんか変な挙動になった
関数の闇 その2 choose
 np.chooseはnp.whereの3引数以上対応の関数です
 np.choose([0, 2, 2, 1], [10, 20, 30])
 # => array([10, 30, 30, 20])
 この関数の第2引数にはある制約があります。それは何?
 A. dtypeがnp.float系だと使えない
 B. 配列の長さが1だと使えない
 C. 配列の長さが50以上だと使えない
 D. A,B,Cは間違い
関数の闇 その2 choose
 np.chooseはnp.whereの3引数以上対応の関数です
 np.choose([0, 2, 2, 1], [10, 20, 30])
 # => array([10, 30, 30, 20])
 この関数の第2引数にはある制約があります。それは何?
 A. dtypeがnp.float系だと使えない
 B. 配列の長さが1だと使えない
 C. 配列の長さが50以上だと使えない
 D. A,B,Cは間違い
 正解はC
 np.chooseが中で第2引数を展開して関数を呼び出している
 その時の引数の数の制限( NPY_MAXARGS)により、最大31択ま
でしかできない
関数の闇 その3 真偽値演算
 次の真偽値演算のうち正しいのはどれ?
 A
 True + True #=> True
 np.bool_(True) + np.bool_(True) #=> 2
 B
 True + True #=> 2
 np.bool_(True) + np.bool_(True) #=> True
 C:環境依存でAかBのどちらかになる
 D:環境依存でAかBかそれ以外の何かになる
関数の闇 その3 真偽値演算
 次の真偽値演算のうち正しいのはどれ?
 A
 True + True #=> True
 np.bool_(True) + np.bool_(True) #=> 2
 B
 True + True #=> 2
 np.bool_(True) + np.bool_(True) #=> True
 C:環境依存でAかBのどちらかになる
 D:環境依存でAかBかそれ以外の何かになる
 正解B
 Pythonの真偽値はほぼ整数型です(True * True = 1)
 numpy ではboolに対する加算、減算、乗算、符号反転は論理演算に
なる
関数の闇 その3 真偽値演算
 関数のドキュメントには説明がない・・・
関数の闇 その4 power
 次のうち正しいのはどれ?
 A. np.bool_(True) ** 0 # => bool_(True)
 B. np.bool_(True) ** 1 # => bool_(True)
 C. np.bool_(True) ** 2 # => bool_(True)
 D. ABCの全部
関数の闇 その4 power
 次のうち正しいのはどれ?
 A. np.bool_(True) ** 0 # => bool_(True)
 B. np.bool_(True) ** 1 # => bool_(True)
 C. np.bool_(True) ** 2 # => bool_(True)
 D. ABCの全部
 正解はC
 他は全部1。Pythonのboolも1になる
 True ** 2 # => 1
 乗数が2.0 の時に分岐してかけ算を呼び出している
 →つまりAND演算なのでnp.bool_(True)になる
 高速化したい気持ちは分かるが、バグである
関数の闇 その5 sqrt
 np.sqrt(np.ones(10, ???)).dtype #=> ??? が成立しないのは
次のうちどれ?
 A. np.float16
 B. np.float32
 C. np.float64
 D. A,B両方のケース
関数の闇 その5 sqrt
 np.sqrt(np.ones(10, ???)).dtype #=> ??? が成立しないのは
次のうちどれ?
 A. np.float16
 B. np.float32
 C. np.float64
 D. A,B両方のケース
 正解はA
関数の闇 その5 sqrt
 sqrtの型判定にバグ?がある
 numpy.sqrt.typesを見ると・・・
 #=>['f->f', 'd->d', 'e->e', 'f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G',
'O->O']
 ['f->f', 'd->d‘]が2回登場している
 e->eのルール(np.float16)はdtypeを指定しないと使えない
 Issueが2個上がっているが、スルー状態
 #6134, #6255
 PRじゃないと修正してもらえない?
 CuPyはsqrtとsqrt_fixedの二つが用意されている
関数の闇 power + sqrt
 ちなみにpowerは0.5乗の時にsqrtを呼び出す・・・
 つまり?
 np.ones(2, np.float16)**0.5
 #=> array([ 1., 1.], dtype=float32)
 闇の連鎖が発生
クイズにしなかった闇
 numpy.dtypeオブジェクトは常にFalse
 [()] でscalarと0次元配列を行ったりきたり(v1.8)
 a #=> array(0.)
 a[()] #=> 0.0
 a[()][()] #=> array(0.)
 a[()] [()] [()] #=> 0.0
 np.splitはぎりぎりで分割すると挙動が変
 対称性のない挙動
 np.true_divide でdtypeを指定すると計算精度が変
 ufuncの仕様上しかないのかもしれないが
 Macでnumpyをimportするとシグナルハンドラとシグナル
マスクを勝手に変更される
まとめ
 NumPyの様々な闇を紹介しました
 他にも闇?を見つけた方は是非教えて下さい
 納得がいかない闇がありましたら、ぜひNumPyにIssue、
PRを送っていただければと思います
 闇の無いライブラリを頑張って作っていきたいです

More Related Content

What's hot

モデル高速化百選
モデル高速化百選モデル高速化百選
モデル高速化百選
Yusuke Uchida
 
Layer Normalization@NIPS+読み会・関西
Layer Normalization@NIPS+読み会・関西Layer Normalization@NIPS+読み会・関西
Layer Normalization@NIPS+読み会・関西
Keigo Nishida
 
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
Shota Imai
 
強化学習 DQNからPPOまで
強化学習 DQNからPPOまで強化学習 DQNからPPOまで
強化学習 DQNからPPOまで
harmonylab
 
不均衡データのクラス分類
不均衡データのクラス分類不均衡データのクラス分類
不均衡データのクラス分類
Shintaro Fukushima
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方
joisino
 
差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)
Kentaro Minami
 
BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装
Deep Learning Lab(ディープラーニング・ラボ)
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情
Yuta Kikuchi
 
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Yusuke Uchida
 
グラフニューラルネットワークとグラフ組合せ問題
グラフニューラルネットワークとグラフ組合せ問題グラフニューラルネットワークとグラフ組合せ問題
グラフニューラルネットワークとグラフ組合せ問題
joisino
 
【DL輪読会】時系列予測 Transfomers の精度向上手法
【DL輪読会】時系列予測 Transfomers の精度向上手法【DL輪読会】時系列予測 Transfomers の精度向上手法
【DL輪読会】時系列予測 Transfomers の精度向上手法
Deep Learning JP
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -
MITSUNARI Shigeo
 
強化学習その3
強化学習その3強化学習その3
強化学習その3
nishio
 
Triplet Loss 徹底解説
Triplet Loss 徹底解説Triplet Loss 徹底解説
Triplet Loss 徹底解説
tancoro
 
NLPにおけるAttention~Seq2Seq から BERTまで~
NLPにおけるAttention~Seq2Seq から BERTまで~NLPにおけるAttention~Seq2Seq から BERTまで~
NLPにおけるAttention~Seq2Seq から BERTまで~
Takuya Ono
 
【DL輪読会】ViT + Self Supervised Learningまとめ
【DL輪読会】ViT + Self Supervised Learningまとめ【DL輪読会】ViT + Self Supervised Learningまとめ
【DL輪読会】ViT + Self Supervised Learningまとめ
Deep Learning JP
 
劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章
Hakky St
 
最適輸送の計算アルゴリズムの研究動向
最適輸送の計算アルゴリズムの研究動向最適輸送の計算アルゴリズムの研究動向
最適輸送の計算アルゴリズムの研究動向
ohken
 
POMDP下での強化学習の基礎と応用
POMDP下での強化学習の基礎と応用POMDP下での強化学習の基礎と応用
POMDP下での強化学習の基礎と応用
Yasunori Ozaki
 

What's hot (20)

モデル高速化百選
モデル高速化百選モデル高速化百選
モデル高速化百選
 
Layer Normalization@NIPS+読み会・関西
Layer Normalization@NIPS+読み会・関西Layer Normalization@NIPS+読み会・関西
Layer Normalization@NIPS+読み会・関西
 
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
強化学習エージェントの内発的動機付けによる探索とその応用(第4回 統計・機械学習若手シンポジウム 招待公演)
 
強化学習 DQNからPPOまで
強化学習 DQNからPPOまで強化学習 DQNからPPOまで
強化学習 DQNからPPOまで
 
不均衡データのクラス分類
不均衡データのクラス分類不均衡データのクラス分類
不均衡データのクラス分類
 
最適輸送の解き方
最適輸送の解き方最適輸送の解き方
最適輸送の解き方
 
差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)
 
BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装BlackBox モデルの説明性・解釈性技術の実装
BlackBox モデルの説明性・解釈性技術の実装
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情
 
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
Swin Transformer (ICCV'21 Best Paper) を完璧に理解する資料
 
グラフニューラルネットワークとグラフ組合せ問題
グラフニューラルネットワークとグラフ組合せ問題グラフニューラルネットワークとグラフ組合せ問題
グラフニューラルネットワークとグラフ組合せ問題
 
【DL輪読会】時系列予測 Transfomers の精度向上手法
【DL輪読会】時系列予測 Transfomers の精度向上手法【DL輪読会】時系列予測 Transfomers の精度向上手法
【DL輪読会】時系列予測 Transfomers の精度向上手法
 
暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -暗号文のままで計算しよう - 準同型暗号入門 -
暗号文のままで計算しよう - 準同型暗号入門 -
 
強化学習その3
強化学習その3強化学習その3
強化学習その3
 
Triplet Loss 徹底解説
Triplet Loss 徹底解説Triplet Loss 徹底解説
Triplet Loss 徹底解説
 
NLPにおけるAttention~Seq2Seq から BERTまで~
NLPにおけるAttention~Seq2Seq から BERTまで~NLPにおけるAttention~Seq2Seq から BERTまで~
NLPにおけるAttention~Seq2Seq から BERTまで~
 
【DL輪読会】ViT + Self Supervised Learningまとめ
【DL輪読会】ViT + Self Supervised Learningまとめ【DL輪読会】ViT + Self Supervised Learningまとめ
【DL輪読会】ViT + Self Supervised Learningまとめ
 
劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章劣モジュラ最適化と機械学習1章
劣モジュラ最適化と機械学習1章
 
最適輸送の計算アルゴリズムの研究動向
最適輸送の計算アルゴリズムの研究動向最適輸送の計算アルゴリズムの研究動向
最適輸送の計算アルゴリズムの研究動向
 
POMDP下での強化学習の基礎と応用
POMDP下での強化学習の基礎と応用POMDP下での強化学習の基礎と応用
POMDP下での強化学習の基礎と応用
 

Viewers also liked

数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ
Shuyo Nakatani
 
数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013
Shuyo Nakatani
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
Ryosuke Okuta
 
111015 tokyo scipy2_ディスカッション
111015 tokyo scipy2_ディスカッション111015 tokyo scipy2_ディスカッション
111015 tokyo scipy2_ディスカッション
Shohei Hido
 
多次元配列の効率的利用法の検討
多次元配列の効率的利用法の検討多次元配列の効率的利用法の検討
多次元配列の効率的利用法の検討
Yu Sato
 
実世界の人工知能@DeNA TechCon 2017
実世界の人工知能@DeNA TechCon 2017 実世界の人工知能@DeNA TechCon 2017
実世界の人工知能@DeNA TechCon 2017
Preferred Networks
 
猫に教えてもらうルベーグ可測
猫に教えてもらうルベーグ可測猫に教えてもらうルベーグ可測
猫に教えてもらうルベーグ可測
Shuyo Nakatani
 
Lighting talk chainer hands on
Lighting talk chainer hands onLighting talk chainer hands on
Lighting talk chainer hands on
Ogushi Masaya
 
ボケるRNNを学習したい (Chainer meetup 01)
ボケるRNNを学習したい (Chainer meetup 01)ボケるRNNを学習したい (Chainer meetup 01)
ボケるRNNを学習したい (Chainer meetup 01)
Motoki Sato
 
ディープラーニングにおける学習の高速化の重要性とその手法
ディープラーニングにおける学習の高速化の重要性とその手法ディープラーニングにおける学習の高速化の重要性とその手法
ディープラーニングにおける学習の高速化の重要性とその手法
Yuko Fujiyama
 
Chainer Contribution Guide
Chainer Contribution GuideChainer Contribution Guide
Chainer Contribution Guide
Kenta Oono
 
Chainer meetup lt
Chainer meetup ltChainer meetup lt
Chainer meetup lt
Ace12358
 
Introduction to Chainer
Introduction to ChainerIntroduction to Chainer
Introduction to Chainer
Shunta Saito
 
Simple perceptron by TJO
Simple perceptron by TJOSimple perceptron by TJO
Simple perceptron by TJO
Takashi J OZAKI
 

Viewers also liked (14)

数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ数式をnumpyに落としこむコツ
数式をnumpyに落としこむコツ
 
数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013数式を綺麗にプログラミングするコツ #spro2013
数式を綺麗にプログラミングするコツ #spro2013
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
 
111015 tokyo scipy2_ディスカッション
111015 tokyo scipy2_ディスカッション111015 tokyo scipy2_ディスカッション
111015 tokyo scipy2_ディスカッション
 
多次元配列の効率的利用法の検討
多次元配列の効率的利用法の検討多次元配列の効率的利用法の検討
多次元配列の効率的利用法の検討
 
実世界の人工知能@DeNA TechCon 2017
実世界の人工知能@DeNA TechCon 2017 実世界の人工知能@DeNA TechCon 2017
実世界の人工知能@DeNA TechCon 2017
 
猫に教えてもらうルベーグ可測
猫に教えてもらうルベーグ可測猫に教えてもらうルベーグ可測
猫に教えてもらうルベーグ可測
 
Lighting talk chainer hands on
Lighting talk chainer hands onLighting talk chainer hands on
Lighting talk chainer hands on
 
ボケるRNNを学習したい (Chainer meetup 01)
ボケるRNNを学習したい (Chainer meetup 01)ボケるRNNを学習したい (Chainer meetup 01)
ボケるRNNを学習したい (Chainer meetup 01)
 
ディープラーニングにおける学習の高速化の重要性とその手法
ディープラーニングにおける学習の高速化の重要性とその手法ディープラーニングにおける学習の高速化の重要性とその手法
ディープラーニングにおける学習の高速化の重要性とその手法
 
Chainer Contribution Guide
Chainer Contribution GuideChainer Contribution Guide
Chainer Contribution Guide
 
Chainer meetup lt
Chainer meetup ltChainer meetup lt
Chainer meetup lt
 
Introduction to Chainer
Introduction to ChainerIntroduction to Chainer
Introduction to Chainer
 
Simple perceptron by TJO
Simple perceptron by TJOSimple perceptron by TJO
Simple perceptron by TJO
 

Similar to NumPy闇入門

2023_freshman
2023_freshman2023_freshman
2023_freshman
TakaakiYonekura
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du
 
ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装
Ryosuke Okuta
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Yasutomo Kawanishi
 
Python基礎その1
Python基礎その1Python基礎その1
Python基礎その1
大貴 末廣
 
DS Exercise Course 2
DS Exercise Course 2DS Exercise Course 2
DS Exercise Course 2
大貴 末廣
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
Shiqiao Du
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
Shiqiao Du
 
はてなインターン「機械学習」
はてなインターン「機械学習」はてなインターン「機械学習」
はてなインターン「機械学習」
Hatena::Engineering
 
130323 slide all
130323 slide all130323 slide all
130323 slide all
ikea0064
 
Django_fukuoka
Django_fukuokaDjango_fukuoka
Django_fukuoka
ShuyaMotouchi1
 
Django_Fukuoka
Django_FukuokaDjango_Fukuoka
Django_Fukuoka
Shuya Motouchi
 
TensorflowとKerasによる深層学習のプログラム実装実践講座
TensorflowとKerasによる深層学習のプログラム実装実践講座TensorflowとKerasによる深層学習のプログラム実装実践講座
TensorflowとKerasによる深層学習のプログラム実装実践講座
Ruo Ando
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
Seiya Tokui
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi
 
El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613
RCCSRENKEI
 
Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編
Etsuji Nakai
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
Eugene Yokota
 
Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)
Jun MITANI
 
FHE in Action
FHE in ActionFHE in Action
FHE in Action
文杰 陆
 

Similar to NumPy闇入門 (20)

2023_freshman
2023_freshman2023_freshman
2023_freshman
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装ディープラーニングフレームワーク とChainerの実装
ディープラーニングフレームワーク とChainerの実装
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
 
Python基礎その1
Python基礎その1Python基礎その1
Python基礎その1
 
DS Exercise Course 2
DS Exercise Course 2DS Exercise Course 2
DS Exercise Course 2
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
はてなインターン「機械学習」
はてなインターン「機械学習」はてなインターン「機械学習」
はてなインターン「機械学習」
 
130323 slide all
130323 slide all130323 slide all
130323 slide all
 
Django_fukuoka
Django_fukuokaDjango_fukuoka
Django_fukuoka
 
Django_Fukuoka
Django_FukuokaDjango_Fukuoka
Django_Fukuoka
 
TensorflowとKerasによる深層学習のプログラム実装実践講座
TensorflowとKerasによる深層学習のプログラム実装実践講座TensorflowとKerasによる深層学習のプログラム実装実践講座
TensorflowとKerasによる深層学習のプログラム実装実践講座
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613El text.tokuron a(2019).watanabe190613
El text.tokuron a(2019).watanabe190613
 
Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編Python 機械学習プログラミング データ分析ライブラリー解説編
Python 機械学習プログラミング データ分析ライブラリー解説編
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
 
Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)
 
FHE in Action
FHE in ActionFHE in Action
FHE in Action
 

NumPy闇入門

  • 2. 自己紹介 奥田 遼介  -2014東北大学 修士  文字列処理など  2014 (株)プリファードインフラストラクチャー  2014- (株)プリファードネットワークス  映像解析系、製造業系にかかわる研究開発  ChainerやCuPyの開発  趣味  読書、高速化
  • 3. NumPyとはなにか  Python上で数値計算を効率的に行うためのライブラリ  NumPyがあるからPythonを使うくらい重要 In [1]: import numpy as np In [2]: np.ones((2, 1)) + np.arange(3) Out[2]: array([[ 1., 2., 3.], [ 1., 2., 3.]])
  • 5. NumPy闇入門とは  Chainer開発勢がChainerやCuPyを作る過程で遭遇した NumPyのちょっと変な挙動(闇)を集めたもの  バグ、仕様なのか不明な場合も・・・  普通の人々はたいてい気づかないものばかりです  ずっと気づかずにいた方が幸せです  今回はクイズ形式で10問の闇を用意しました  クイズの作りが悪いのでだいぶ簡単です(たぶん)  何問正解できるか挑戦してみてください  断りが無い場合以下の環境を想定しています  x86_64+Ubuntu64bit + Python 2.7 + NumPy 1.10.4
  • 8. Pythonの型、NumPyの型  Pythonの数値型は少ない  bool  int, (long)  float  complex  NumPyはたくさん  NumPyはPure Cのライブラリ  演算効率のためにC互換の型が沢山  CとPythonの融合した型システム  →闇の温床
  • 9. NumPyの型の表現  2~3種類の表現がある  np.int32 # Python type  np.dtype(‘int32’) # dtype  ‘i’ # Character code  お互いに変換可能  np.dtype(np.int32) #=> dtype(‘int32’)  np.dtype(‘i’) #=> dtype(‘int32’)  np.dtype(‘int32’).type #=> np.int32  np.dtype(‘int32’).char #=> ‘i’
  • 10. 型の闇 練習問題  np.zeros(2, np.int32) + np.zeros(2, float) の演算結果のdtype は?  A. dtype(‘float32’)  B. dtype(‘float64’)  C. dtype(‘float’)  D. わからない
  • 11. 型の闇 練習問題  np.zeros(2, np.int32) + np.zeros(2, float) の演算結果のdtype は?  A. dtype(‘float32’)  B. dtype(‘float64’)  C. dtype(‘float’)  D. わからない  正解はB  int32を十分に表現可能なfloat64にキャストされて演算が行われ ます  選択肢C のようなdtypeは無いです dtype(‘float64’)になります
  • 12. 型の闇 その1  np.zeros(2, np.int64) + np.zeros(2, np.float64) の演算結果の dtypeは?  A. dtype(‘float32’)  B. dtype(‘float64’)  C. dtype(‘float128’)  D. わからない
  • 13. 型の闇 その1  np.zeros(2, np.int64) + np.zeros(2, np.float64) の演算結果の dtypeは?  A. dtype(‘float32’)  B. dtype(‘float64’)  C. dtype(‘float128’)  D. わからない  正解はB  np.float128は実在します  C言語相当なので自動でnp.float128にはならない  np.can_cast(np.zeros(2,np.int32), np.float32) # => False  np.can_cast(np.zeros(2,np.int64), np.float64) # => True
  • 14. 型の闇 その2  0 + np.float16(0) の演算結果のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない
  • 15. 型の闇 その2  0 + np.float16(0) の演算結果のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない  正解はC  0はint つまりこの環境ではnp.int64となる  np.int64(0) + np.float16(0)という計算に相当するため、np.float64が 正解
  • 16. 型の闇 その3  変数aの型がintの時、a + np.zeros(2, np.float32) の演算結 果のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない
  • 17. 型の闇 その3  変数aの型がintの時、a + np.zeros(2, np.float32) の演算結 果のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない  正解:D  変数aの値の大きさによってnp.float32か、np.float64になる  例えば -32768<= a <= 65535 であればnp.float32  変数aがスカラー相当の値の場合は同じ挙動  Chainerではまることが多いケースなので注意
  • 18. 型の闇 その4  np.array([10], np.int32)+ np.zeros(2, np.float32) の演算結果 のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない
  • 19. 型の闇 その4  np.array([10], np.int32) + np.zeros(2, np.float32) の演算結果 のdtypeは?  A. dtype(‘float16’)  B. dtype(‘float32’)  C. dtype(‘float64’)  D. わからない  正解:C  np.array([10], np.int32)はスカラー相当ではないので、普通のキャ ストが行われる
  • 20. 型の昇格の話  スカラー相当の値とは?  Pythonのbool, int,np.int32, np.float64・・・  0次元のndarray:shapeが長さ0であるもの  1次元以上だとスカラー相当ではないので注意  スカラー、ベクトル同士の規則は表現精度に基づき決定  スカラーとベクトルの場合は以下の通り  Kindの大きさを比較(bool -> 0, int, uint -> 1, float ->2)  スカラー側のkindが大きい→dtypeの表現精度に基づき決定  それ以外→ スカラー値を表現可能な最小の型を利用  (np.array([10,10], np.int16) + np.float16(10)).dtype # => dtype('float32')  (np.array([10,10], np.float16) + np.int16(10)).dtype # => dtype('float16')  255まではnp.float16になる
  • 21. 型の闇 その5  np.longlong, np.int_, np.intp はnp.dtype化すると全て 「dtype(‘int64’)」になる。正しいのはどれ?  A. np.longlong は np.int64 と等しくない  B. np.int_ は np.int64 と等しくない  C. np.intp は np.int64 と等しくない  D. 全部 np.int64 と等しい
  • 22. 型の闇 その5  np.longlong, np.int_, np.intp はnp.dtype化すると全て 「dtype(‘int64’)」になる。正しいのはどれ?  A. np.longlong は np.int64 と等しくない  B. np.int_ は np.int64 と等しくない  C. np.intp は np.int64 と等しくない  D. 全部 np.int64 と等しい  正解:A  numpyには、nump.int64が2つある(こともある)  Windowsだとnumpy.int32が2つある(こともある)  C言語でlong long とintと longが分かれている事に由来する
  • 23. なぜこんなに複雑になってしまったのか?  わかりません  推測:使っていて良い感じになるようにしたかった  ちなみに0次元ndarrayは気づくと単なるスカラー変数になってい たりします  type(np.array(10) + 10) #=> numpy.int64  CuPyはどこまで同じ挙動を再現しているのか?  0次元ndarrayと1次元以上のndarrayの演算の時のみ違う挙動  GPU上にある値で型が変わる挙動は性能への影響が大きいため  どうやってこの挙動を再現したのか?  本家のコードを読みました  バージョンが変わると結構変わったりします  v1.10でデフォルトのcasting ruleが変わったり
  • 25. 関数の闇 その1 expand_dimsの闇  expand_dimsは長さ1の次元を挿入する関数である  np.expand_dims(np.zeros((2,3,4)), -1).shape  #=>(2, 3, 4, 1)  -1の時は一番後ろに次元を挿入してくれる  np.expand_dims(np.zeros((2,3,4)),-5).shape は?  A. (1, 2, 3, 4)  B. (2, 3, 4, 1)  C. (2, 3, 1, 4)  D. 例外で落ちる
  • 26. 関数の闇 その1 expand_dimsの闇  expand_dimsは長さ1の次元を挿入する関数である  np.expand_dims(np.zeros((2,3,4)), -1).shape  #=>(2, 3, 4, 1)  -1の時は一番後ろに次元を挿入してくれる  np.expand_dims(np.zeros((2,3,4)),-5).shape は?  A. (1, 2, 3, 4)  B. (2, 3, 4, 1)  C. (2, 3, 1, 4)  D. 例外で落ちる  正解はC
  • 27. 関数の闇 その1 expand_dimsの闇  expand_dimsの正の方向は循環せず止まる  0 #=> (1, 2, 3, 4)  1 #=> (2, 1, 3, 4)  2 #=> (2, 3, 1, 4)  3 #=> (2, 3, 4, 1)  4 #=> (2, 3, 4, 1)  マイナスの方は不完全な2週目がある  -3 #=> (2, 1, 3, 4)  -4 #=> (1, 2, 3, 4)  -5 #=> (2, 3, 1, 4)  推測: Pythonの配列では普通に負のインデックスが使える  -1を特別扱いした→なんか変な挙動になった
  • 28. 関数の闇 その2 choose  np.chooseはnp.whereの3引数以上対応の関数です  np.choose([0, 2, 2, 1], [10, 20, 30])  # => array([10, 30, 30, 20])  この関数の第2引数にはある制約があります。それは何?  A. dtypeがnp.float系だと使えない  B. 配列の長さが1だと使えない  C. 配列の長さが50以上だと使えない  D. A,B,Cは間違い
  • 29. 関数の闇 その2 choose  np.chooseはnp.whereの3引数以上対応の関数です  np.choose([0, 2, 2, 1], [10, 20, 30])  # => array([10, 30, 30, 20])  この関数の第2引数にはある制約があります。それは何?  A. dtypeがnp.float系だと使えない  B. 配列の長さが1だと使えない  C. 配列の長さが50以上だと使えない  D. A,B,Cは間違い  正解はC  np.chooseが中で第2引数を展開して関数を呼び出している  その時の引数の数の制限( NPY_MAXARGS)により、最大31択ま でしかできない
  • 30. 関数の闇 その3 真偽値演算  次の真偽値演算のうち正しいのはどれ?  A  True + True #=> True  np.bool_(True) + np.bool_(True) #=> 2  B  True + True #=> 2  np.bool_(True) + np.bool_(True) #=> True  C:環境依存でAかBのどちらかになる  D:環境依存でAかBかそれ以外の何かになる
  • 31. 関数の闇 その3 真偽値演算  次の真偽値演算のうち正しいのはどれ?  A  True + True #=> True  np.bool_(True) + np.bool_(True) #=> 2  B  True + True #=> 2  np.bool_(True) + np.bool_(True) #=> True  C:環境依存でAかBのどちらかになる  D:環境依存でAかBかそれ以外の何かになる  正解B  Pythonの真偽値はほぼ整数型です(True * True = 1)  numpy ではboolに対する加算、減算、乗算、符号反転は論理演算に なる
  • 32. 関数の闇 その3 真偽値演算  関数のドキュメントには説明がない・・・
  • 33. 関数の闇 その4 power  次のうち正しいのはどれ?  A. np.bool_(True) ** 0 # => bool_(True)  B. np.bool_(True) ** 1 # => bool_(True)  C. np.bool_(True) ** 2 # => bool_(True)  D. ABCの全部
  • 34. 関数の闇 その4 power  次のうち正しいのはどれ?  A. np.bool_(True) ** 0 # => bool_(True)  B. np.bool_(True) ** 1 # => bool_(True)  C. np.bool_(True) ** 2 # => bool_(True)  D. ABCの全部  正解はC  他は全部1。Pythonのboolも1になる  True ** 2 # => 1  乗数が2.0 の時に分岐してかけ算を呼び出している  →つまりAND演算なのでnp.bool_(True)になる  高速化したい気持ちは分かるが、バグである
  • 35. 関数の闇 その5 sqrt  np.sqrt(np.ones(10, ???)).dtype #=> ??? が成立しないのは 次のうちどれ?  A. np.float16  B. np.float32  C. np.float64  D. A,B両方のケース
  • 36. 関数の闇 その5 sqrt  np.sqrt(np.ones(10, ???)).dtype #=> ??? が成立しないのは 次のうちどれ?  A. np.float16  B. np.float32  C. np.float64  D. A,B両方のケース  正解はA
  • 37. 関数の闇 その5 sqrt  sqrtの型判定にバグ?がある  numpy.sqrt.typesを見ると・・・  #=>['f->f', 'd->d', 'e->e', 'f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O']  ['f->f', 'd->d‘]が2回登場している  e->eのルール(np.float16)はdtypeを指定しないと使えない  Issueが2個上がっているが、スルー状態  #6134, #6255  PRじゃないと修正してもらえない?  CuPyはsqrtとsqrt_fixedの二つが用意されている
  • 38. 関数の闇 power + sqrt  ちなみにpowerは0.5乗の時にsqrtを呼び出す・・・  つまり?  np.ones(2, np.float16)**0.5  #=> array([ 1., 1.], dtype=float32)  闇の連鎖が発生
  • 39. クイズにしなかった闇  numpy.dtypeオブジェクトは常にFalse  [()] でscalarと0次元配列を行ったりきたり(v1.8)  a #=> array(0.)  a[()] #=> 0.0  a[()][()] #=> array(0.)  a[()] [()] [()] #=> 0.0  np.splitはぎりぎりで分割すると挙動が変  対称性のない挙動  np.true_divide でdtypeを指定すると計算精度が変  ufuncの仕様上しかないのかもしれないが  Macでnumpyをimportするとシグナルハンドラとシグナル マスクを勝手に変更される
  • 40. まとめ  NumPyの様々な闇を紹介しました  他にも闇?を見つけた方は是非教えて下さい  納得がいかない闇がありましたら、ぜひNumPyにIssue、 PRを送っていただければと思います  闇の無いライブラリを頑張って作っていきたいです