めも

これはメモ。

human pose estimation(人の姿勢推定)関係の論文のリスト

メモ。タイトルと最近のものから適当に抽出。

CVPR2018

Detect-and-Track: Efficient Pose Estimation in Videos

2D/3D Pose Estimation and Action Recognition Using Multitask Deep Learning

Jointly Optimize Data Augmentation and Network Training: Adversarial Data Augmentation in Human Pose Estimation

PoseTrack: A Benchmark for Human Pose Estimation and Tracking

Cascaded Pyramid Network for Multi-Person Pose Estimation

DensePose: Dense Human Pose Estimation in the Wild

Ordinal Depth Supervision for 3D Human Pose Estimation

AAAI2018

A Cascaded Inception of Inception Network With Attention Modulated Feature Fusion for Human Pose Estimation

ICLR2019

ECCV2018

Deeply Learned Compositional Models for Human Pose Estimation

Deeply Learned Compositional Models for Human Pose Estimation

Multi-Scale Structure-Aware Network for Human Pose Estimation

[1803.09894] Multi-Scale Structure-Aware Network for Human Pose Estimation

www.youtube.com

DL輪読会, Human Pose Estimation @ ECCV2018

www.slideshare.net

pythonでKL距離(KLダイバージェンス)

データを生成

N=10000個だけ正規分布、パレート分布(自由度10)、べき分布からサンプルを生成。

import matplotlib.pyplot as plt
import numpy as np

# サンプル数
N=10000

# 各分布からサンプルをN個生成
x = np.random.normal(size=N)
x2 = np.random.normal(size=N)

y = np.random.pareto(10, size=N)
y2 = np.random.pareto(10, size=N)

z = np.random.power(5, size=N)
z2 = np.random.power(5, size=N)

# 各分布から生成した点のヒストグラムをプロット
plt.figure(figsize=(10, 5))
hist, _ = np.histogram(x)
plt.plot(hist, label="normal")
hist, _ = np.histogram(x2)
plt.plot(hist, label="normal2")
hist, _ = np.histogram(y)
plt.plot(hist, label="pareto")
hist, _ = np.histogram(y2)
plt.plot(hist, label="pareto2")
hist, _ = np.histogram(z)
plt.plot(hist, label="powar")
hist, _ = np.histogram(z2)
plt.plot(hist, label="powar2")
plt.legend(title="distribution")
plt.grid()

f:id:misos:20181013164603p:plain

KL-divergence

本来ならば aの分布(a_hist)に0が含まれると0にしないといけないが、 簡易的に分布全体に小さい値 epsilon=.00001 を足して計算できるようにする。

def KLD(a, b, bins=10, epsilon=.00001):
    # サンプルをヒストグラムに, 共に同じ数のビンで区切る
    a_hist, _ = np.histogram(a, bins=bins) 
    b_hist, _ = np.histogram(b, bins=bins)
    
    # 合計を1にするために全合計で割る
    a_hist = (a_hist+epsilon)/np.sum(a_hist)
    b_hist = (b_hist+epsilon)/np.sum(b_hist)
    
    # 本来なら a の分布に0が含まれているなら0, bの分布に0が含まれているなら inf にする
    return np.sum([ai * np.log(ai / bi) for ai, bi in zip(a_hist, b_hist)])

実行結果

x~x2, y~y2, z~z2間は同じ分布同士なので小さくなる。

print(KLD(x, y), KLD(y, z), KLD(z, x))
print(KLD(x, x2), KLD(y, y2), KLD(z, z2))
4.853129620306818 7.017965941238099 2.9077428243608163
0.003968976036639689 0.01426772591715473 0.012341556339116544

Ubuntuにてディスク容量の確認、ファイルサイズの検索

ncdu

apt install ncduにてインストール後、ncduを実行。 ヒストグラムで容量の分布を見れる。 dfコマンドの結果をパイプして sortしたような表示になる。

43.0 GiB [#####     ] /main
4.0 GiB [##        ] /works
1.5 GiB [          ] /.cache
892.6 MiB [          ] /torch

※詳細のオプションはNCurses Disk Usageを参照。

du

du -sh ./*にてカレントディレクトリ以下のディレクトリの容量を確認する。

例えばcudaライブラリの容量を確認する場合は sudo du -sh /var/cuda-repo-*など。

使用例:指定ディレクトリに含まれるディレクトリをソートして出力

xxxディレクトリから 4階層下まで、ディレクトリ名に ABCを含むものをソートして表示する場合は du xxx/ --max-depth=4 -h | sort -n | grep ABCとなる。

使用例:容量が大きいディレクトリ上位X件の名前をファイルに出力

sudo du xxx/--max-depth=2 -h | sort -rn | head -10 > du_result.md

du_result.md内部の結果は

540K xxx/aaa
424K    xxx/vvv/.ipynb_checkpoints
412K    xxx/sss/.git
...

などとなる。

※詳細のオプションは Linuxコマンド集:du を参照。

df

df -hにてパーティションごとのディスク容量を確認する。

dfで容量がいっぱいのディスクを調べ、duでサイズが大きいディレクトリを特定するように使っている。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
xxx             16G     0   16G   0% /dev
yyy             3.2G  9.5M  3.2G   1% /dev2
zzz             76G   63G  9.3G  88% /dev3

pandas.Dataframe からユニークな要素とその数を数えてプロットする

説明

pandas.Series.sort_values など pandas.Series の関数を使用する。

  • dummy_data.value_counts(): Seriesデータに含まれる要素ごとの出現回数をカウント
  • dummy_data.value_counts().index.values: 各要素ごとの名前(indexの名前)の値を.valuesから取得

コード

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

%matplotlib inline # jupyter notebookを使用する場合

dummy_data = pd.Series([np.random.randint(0, 30) for i in range(1000)],
                       index=["sampledata"+str(i) for i in range(1000)])

ind_vals = dummy_data.value_counts().values
ind_names = dummy_data.value_counts().index.values # 各要素の名前
ind_N = dummy_data.value_counts().values.shape[0] # ユニークな要素の数
ind = np.arange(ind_N) # ラベルを配置するための配列

plt.figure(figsize=(10, 20))
plt.subplot(211)
plt.bar(ind, ind_vals)
plt.xticks(ind, ind_names, rotation=90)
plt.tight_layout()
plt.xlim(-1, ind_N+1)

plt.subplot(212)
plt.pie(ind_vals,
        labels=ind_names,
        startangle=0)

plt.savefig("result.png")

結果

f:id:misos:20180919194107p:plain

Python 標準ライブラリの組み込み関数のメモ

リーダブルコードのどこかの章で「たまには15分くらいかけてドキュメントに目を通すといい」みたいなことが書かれていた気がするので、Python 標準ライブラリ( Python 標準ライブラリ — Python 3.6.5 ドキュメント ) に目を通す。ざっとpython・C++・C#のドキュメントに目を通したい。

数値

x = 2
y = 3

print("x と y の商",x/y)
print("x と y の商を切り下げたもの", x//y)
print("剰余", x%y)
print("複素数", complex(x, y))
print("共役複素数", complex(x,y).conjugate())
print("乗数", x**y)
print("尚・剰余", divmod(x, y))
x と y の商 0.6666666666666666
x と y の商を切り下げたもの 0
剰余 2
複素数 (2+3j)
共役複素数 (2-3j)
乗数 8
尚・剰余 (0, 2)

浮動小数点数(float)

  • a.is_integer()は整数の場合のみ True
  • float.fromhex("~")の引数にはスペースが含まれていても実行される
a = 2.0
b = 2.1

print("整数か?", a.is_integer())
print("16 進文字列表現", b.hex())
print("16 進文字列表現からfloat型へ", float.fromhex("0x1.0cccccccccccdp+1"))
整数か? True
16 進文字列表現 0x1.0cccccccccccdp+1
16 進文字列表現からfloat型へ 2.1

リスト(list), タプル(tuple), レンジ(range)

  • s[0:100:10]はインデックス0〜100を10刻みで取得

  • s.index(19, 10, 20)はインデックス10〜20の範囲で19がある箇所のインデックスを返します。

  • s.count(0)0sの中に出現した回数を数え上げる

  • instrbytearrayの部分列の判定にも利用できる

#  0~99までのリスト
s = [i for i in range(100)]

print("0 in s", 0 in s)
print("100 in s", 100 in s)
print("s * 2", len(s*2))
print("s[0:100:10]", s[0:100:10])
print("s.index(19, 10, 20)", s.index(19, 10, 20))
print("s.count(0)", s.count(0))
0 in s True
100 in s False
s * 2 200
s[0:100:10] [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
s.index(19, 10, 20) 19
s.count(0) 1
  • s.clear()sの要素を全て削除する
  • t.reverse()tの順番を逆にする
#  0~99までのリスト
s = [i for i in range(15)]
t = [j for j in range(15)]

# 要素を全て削除する
s.clear()
print("空リスト", s) 

# 順番を逆転させる
t.reverse()
print("t", t)

# 0~10の要素を二つ飛ばしで削除
del t[0:10:2]
print("t[0:10:2]", t)
空リスト []
t [14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
t[0:10:2] [13, 11, 9, 7, 5, 4, 3, 2, 1, 0]

リストのソートについては以下のドキュメントを参照。

ソート HOW TO — Python 3.6.5 ドキュメント

文字列

文字列を編集する

置き換え・スペースで埋める・大文字や小文字に変換するなど。

  • sample.rpartition(".")は文字列を末尾から見て、初めに発見した文字列 . で文字列を区切ってリストにして返す。このようなr~(文字列を末尾から見る)の関数もいくつか存在する
# 文字列
sample = "abcd_EFGH_ijkl_ABcd.csv"

print("初めの一文字を大文字にする:", sample.capitalize())
print("全て小文字にする:", sample.casefold())
print("中央寄せして残りをスペースで埋める:", sample.center(30))
print("左寄せして残りをスペースで埋める:", sample.ljust(30))
print("文字列のフォーマット:", "サンプル {0}".format(10*10))
print("文字列の置換, csvをmdに:", sample.replace(".csv", ".md"))
print("文字列を初めに発見したdotで区切る:", sample.partition("."))
print("文字列を最後に発見したdotで区切る:", sample.rpartition("."))
print("文字列を指定した文字で区切ってリストにする:", sample.split("_"))
初めの一文字を大文字にする: Abcd_efgh_ijkl_abcd.csv
全て小文字にする: abcd_efgh_ijkl_abcd.csv
中央寄せして残りをスペースで埋める:    abcd_EFGH_ijkl_ABcd.csv    
左寄せして残りをスペースで埋める: abcd_EFGH_ijkl_ABcd.csv       
文字列のフォーマット: サンプル 100
文字列の置換, csvをmdに: abcd_EFGH_ijkl_ABcd.md
文字列を初めに発見したdotで区切る: ('abcd_EFGH_ijkl_ABcd', '.', 'csv')
文字列を最後に発見したdotで区切る: ('abcd_EFGH_ijkl_ABcd', '.', 'csv')
文字列を指定した文字で区切ってリストにする: ['abcd', 'EFGH', 'ijkl', 'ABcd.csv']

条件分岐

文字の数え上げ・含み判定など。

  • sample.find(".txt")sampletxtが含まれていればそのインデックスを返し、ない場合は-1を返す
    • インデックスを知る必要がない場合以外は基本的に in を使用する
  • sample.endswith(".csv")は末尾が指定した文字列 .csv なら真になる
# 文字列(str)
sample = "abcd_EFGH_ijkl_ABcd.csv"

print("文字列の出現回数を数え上げる:", sample.count("cd"))
print("末尾が.csvなら真:", sample.endswith(".csv"))
print("文字列.csvがあるインデックスを返す:", sample.find(".csv"))
print("> 見つからない場合は-1になる:", sample.find(".txt"))
print("> インデックスを知る必要がない場合はinを使う:", ".txt" in sample)

print("全て英文字ならTrue:", sample.isalpha())
print("全て英文字ならTrue:", "aaaa".isalpha())
print("全て数字ならTrue:", sample.isdigit())
print("全て数字ならTrue:", "12345".isdigit())
文字列の出現回数を数え上げる: 2
末尾が.csvなら真: True
文字列.csvがあるインデックスを返す: 19
> 見つからない場合は-1になる: -1
> インデックスを知る必要がない場合はinを使う: False
全て英文字ならTrue: False
全て英文字ならTrue: True
全て数字ならTrue: False
全て数字ならTrue: True

集合(set)

# 集合を作る
set_2n = set([i*2 for i in range(30)]) # 2の倍数を30個
set_3n = set([i*3 for i in range(30)]) # 3の倍数を30個
set_minus2n = set([i*-2 - 2 for i in range(30)]) # -2の倍数を30個

print("2N:", set_2n)
print("3N:", set_3n)
print("-2N:", set_minus2n)
2N: {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58}
3N: {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87}
-2N: {-60, -58, -56, -54, -52, -50, -48, -46, -44, -42, -40, -38, -36, -34, -32, -30, -28, -26, -24, -22, -20, -18, -16, -14, -12, -10, -8, -6, -4, -2}

条件分岐

print("要素数", len(set_2n))
set_4n = set([i*4 for i in range(4)]) # 4の倍数を4個

# 条件分岐
print("要素が存在するか?:", 10 in set_2n, 11 in set_2n)
print("互いに素の時のみ真:", set_2n.isdisjoint(set_3n), set_2n.isdisjoint(set_minus2n))
print("部分集合なら真:", set_4n.issubset(set_2n))
要素数 30
要素が存在するか?: True False
互いに素の時のみ真: False True
部分集合なら真: True
どちらかに含まれる要素: {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58}

演算

# 演算
print("どちらかに含まれる要素:", set_2n | set_4n)
print("共通要素:", set_2n & set_4n)
print("set_4nの要素を消す:", set_2n - set_4n)
print("一方だけに含まれる要素:", set_2n ^ set_4n)
共通要素: {0, 8, 4, 12}
set_4nの要素を消す: {2, 6, 10, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58}
一方だけに含まれる要素: {2, 6, 10, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58}

辞書(dict)

dict型のドキュメントより引用すると以下の記述は全て同じものになる。

# https://docs.python.jp/3/library/stdtypes.html#dict より引用
a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)])
e = dict({'three': 3, 'one': 1, 'two': 2})

a == b == c == d == e

>>> True