# PointNet_Reg **Repository Path**: kotte/PointNet_Reg ## Basic Information - **Project Name**: PointNet_Reg - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-02-11 - **Last Updated**: 2022-02-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PointNet_Reg 卒業研究で使ったコード置き場 RealSenseで撮影した深度画像を元に頭部の点群データを作り、頭部がカメラに対してどこを向いているか推定します。 研究で使った点群データ、論文、参考にしたサイトとかは一通り研究室のNASにあります。 **探せ!この世の全てをそこに置いてきた!** 最悪、GoogleDriveのダウンロードリンクを送ります。 # 大体の使い方 ## 頭部のスキャン ``` # 顔のデータを撮影して指定のディレクトリにpcdファイルを保存 # Usage: -> % python3 head_scan.py TestData/five_position_classes/r45/valid # 第二引数で保存名を指定 # Usage: -> % python3 head_scan.py TestData/five_position_classes/r45/valid test ``` ## データ構造 データ構造の説明については、研究室のNASにあります。 `研究資料→ソースコード→notes→notes.md`を読んでください。 研究に使ったデータは、`研究資料→ソースコード→TestData.zip`にあります。 ## 学習 `nbs/PointNetClass_five_heads.ipynb`で実行。 `train(pointnet, train_loader, valid_loader, save=False)`ここと、 `torch.save(pointnet.state_dict(), "pnt_model_500_3.pth")`ここで、saveするか、保存するモデルの名称はどうするかを手動で設定しておくこと! ## その他のファイル `dataset.py` - データセットの構造がわかります - 事前に学習したモデルを元に、混合行列も表示してくれます。 `estimate.py` - 推定したいpcdファイルを元にどこを向いているか推定してくれます。 ``` # Usage: -> % python -B estimate.py Data/five_position_classes_head/r45/valid/6.pcd ``` `model.py` - PointNetがどんな入力に対して、どんな出力が出てくるかが確認できます。 `scanner.py` - シンプルなコードで手っ取り早くRealSenseで撮影して、3次元データを確認できます。 RealSenseやOpen3dの動作を把握する時に使えます。 `show_pcd.py` - pcdファイルを読み込んで、データの可視化をします。 ``` # Usage: -> % python3 show_pcd.py TestData/five_position_classes/0/train/0.pcd ``` # Note ## transpose https://pytorch.org/docs/stable/generated/torch.transpose.html#torch.transpose torch.transpose(input, dim0, dim1) → Tensor - input(Tensor)–入力テンソル。 - dim0(int)–転置される最初の次元 - dim1(int)–転置される2番目の次元 2* 3行4列 の 1次元目と2次元目を入れ替えて 2* 4行3列に転置している ```python >>> x = torch.randn(2, 3, 4) >>> x tensor([[[ 0.9807, 0.0329, -0.3041, -1.0789], [-0.1989, 0.5325, 0.9603, 1.6502], [-1.4203, 0.3572, -0.0059, -1.6910]], [[-0.5305, 0.3733, 0.4158, 0.0045], [-0.2104, 0.1885, 0.0040, 0.1256], [-0.4915, 0.2189, -1.1648, 0.0640]]]) >>> torch.transpose(x, 1, 2) tensor([[[ 0.9807, -0.1989, -1.4203], [ 0.0329, 0.5325, 0.3572], [-0.3041, 0.9603, -0.0059], [-1.0789, 1.6502, -1.6910]], [[-0.5305, -0.2104, -0.4915], [ 0.3733, 0.1885, 0.2189], [ 0.4158, 0.0040, -1.1648], [ 0.0045, 0.1256, 0.0640]]]) ``` ## view 一つ目の引数に`-1`を入れることで、2つ目の引数で指定した値にサイズ数を自動的に調整してくれる ```python # ex) 5つのpointを持つ点群データ 2つ >>> x = torch.randn(2, 5, 3) >>> x tensor([[[ 0.3104, -1.5533, -0.4214], [ 0.1752, -0.1765, -0.0746], [-0.6158, 0.4281, -0.1702], [ 2.0274, 2.3959, 0.5081], [ 0.1707, -0.5628, -2.4552]], [[ 0.8340, -0.4241, -0.4802], [-1.6821, -0.5301, 1.2178], [ 2.2584, -0.0460, 1.7543], [-0.9705, -0.4540, 0.6339], [ 0.1246, -0.0607, 0.9205]]]) >>> x.view(-1, 3, 5) tensor([[[ 0.3104, -1.5533, -0.4214, 0.1752, -0.1765], [-0.0746, -0.6158, 0.4281, -0.1702, 2.0274], [ 2.3959, 0.5081, 0.1707, -0.5628, -2.4552]], [[ 0.8340, -0.4241, -0.4802, -1.6821, -0.5301], [ 1.2178, 2.2584, -0.0460, 1.7543, -0.9705], [-0.4540, 0.6339, 0.1246, -0.0607, 0.9205]]]) ``` ### viewをtransposeの違い viewはテンソルの形を変えます.要素の並び順は変わりません. transposeはテンソルのランクを入れ替えます.要素の並び順が変わります. ```python >>> x tensor([[[ 0.3104, -1.5533, -0.4214], [ 0.1752, -0.1765, -0.0746], [-0.6158, 0.4281, -0.1702], [ 2.0274, 2.3959, 0.5081], [ 0.1707, -0.5628, -2.4552]], [[ 0.8340, -0.4241, -0.4802], [-1.6821, -0.5301, 1.2178], [ 2.2584, -0.0460, 1.7543], [-0.9705, -0.4540, 0.6339], [ 0.1246, -0.0607, 0.9205]]]) >>> x.view(-1, 3, 5) tensor([[[ 0.3104, -1.5533, -0.4214, 0.1752, -0.1765], [-0.0746, -0.6158, 0.4281, -0.1702, 2.0274], [ 2.3959, 0.5081, 0.1707, -0.5628, -2.4552]], [[ 0.8340, -0.4241, -0.4802, -1.6821, -0.5301], [ 1.2178, 2.2584, -0.0460, 1.7543, -0.9705], [-0.4540, 0.6339, 0.1246, -0.0607, 0.9205]]]) >>> torch.transpose(x, 1, 2) tensor([[[ 0.3104, 0.1752, -0.6158, 2.0274, 0.1707], [-1.5533, -0.1765, 0.4281, 2.3959, -0.5628], [-0.4214, -0.0746, -0.1702, 0.5081, -2.4552]], [[ 0.8340, -1.6821, 2.2584, -0.9705, 0.1246], [-0.4241, -0.5301, -0.0460, -0.4540, -0.0607], [-0.4802, 1.2178, 1.7543, 0.6339, 0.9205]]]) ``` ## MaxPool1d torch.nn.MaxPool1d(kernel_size) ```python >>> x tensor([[[ 0.9807, 0.0329, -0.3041, -1.0789], [-0.1989, 0.5325, 0.9603, 1.6502], [-1.4203, 0.3572, -0.0059, -1.6910]], [[-0.5305, 0.3733, 0.4158, 0.0045], [-0.2104, 0.1885, 0.0040, 0.1256], [-0.4915, 0.2189, -1.1648, 0.0640]]]) >>> x.size(0) 2 >>> x.size(1) 3 >>> x.size(2) 4 >>> x.size(-1) # つまり2次元目を指している(列数) 4 >>> torch.nn.MaxPool1d(x.size(-1))(x) tensor([[[0.9807], [1.6502], [0.3572]], [[0.4158], [0.1885], [0.2189]]]) # 4列の中で一番大きい数字を取り出している ``` ## Flatten torch.nn.Flatten(start_dim: int = 1, end_dim: int = -1) ```python >>> x tensor([[[ 0.9807, 0.0329, -0.3041, -1.0789], [-0.1989, 0.5325, 0.9603, 1.6502], [-1.4203, 0.3572, -0.0059, -1.6910]], [[-0.5305, 0.3733, 0.4158, 0.0045], [-0.2104, 0.1885, 0.0040, 0.1256], [-0.4915, 0.2189, -1.1648, 0.0640]]]) >>> torch.nn.Flatten(1)(x) # 今回では1次元目と2次元目を一つにまとめてる tensor([[ 0.9807, 0.0329, -0.3041, -1.0789, -0.1989, 0.5325, 0.9603, 1.6502, -1.4203, 0.3572, -0.0059, -1.6910], [-0.5305, 0.3733, 0.4158, 0.0045, -0.2104, 0.1885, 0.0040, 0.1256, -0.4915, 0.2189, -1.1648, 0.0640]]) ``` ## L0?L1?L2?ノルム??? あるベクトルの大きさのこと `np.linalg.norm(input, ord:ノルム=2, axis:対象軸)` ### L0ノルム 0以外の値を持つ次元数(ざっくり) ### L1ノルム 各次元の絶対値の和(マンハッタン距離) ### L2ノルム 各次元の2乗した和の平方根(ユークリッド距離) > 例えば、ベクトルノルムの場合はノルムの計算方法は > 各要素の2乗和の平方根 > で算出しますが、ord=3 を指定すると > 各要素の3乗和の3乗根 で算出されます。 > https://teratail.com/questions/73822 ## Axis https://deepage.net/features/numpy-axis.html ## nn.BatchNorm1d torch.nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) ```python >>> input = torch.randn(10, 3) >>> m = torch.nn.BatchNorm1d(3) >>> output = m(input) >>> output tensor([[ 0.6273, -0.5331, -1.5502], [ 0.9353, -0.7351, 0.7647], [ 1.5150, -0.9468, 0.2170], [-0.5732, -1.5238, -0.3610], [-2.0045, 0.5869, 1.6986], [ 0.5672, -0.3396, 1.5211], [-0.2734, 0.6944, -0.2322], [ 0.1759, 1.6959, -0.3830], [ 0.2872, -0.3248, -0.9642], [-1.2569, 1.4260, -0.7109]], grad_fn=) ``` ## torch.matmul() 行列積を計算 matmul()とmm()/bmm()は同じ機能で、`@`演算子も使えるらしい いろいろな行列積の計算方法 https://qiita.com/tand826/items/9e1b6a4de785097fe6a5 ```python >>> matrix = torch.randn(1, 3, 3) >>> matrix tensor([[[ 0.0466, -0.9606, -0.0769], [ 1.3093, -0.5168, -0.3116], [-1.0825, 0.4925, -0.0080]]]) >>> input = torch.randn(1, 10, 3) >>> output = torch.matmul(input, matrix) >>> output tensor([[[ 0.1437, 1.2994, -0.1585], [ 2.5082, -0.0109, -0.5832], [-0.3461, -0.4641, 0.0111], [ 0.1358, -0.6681, 0.1967], [ 0.1357, 0.3903, -0.1306], [-2.7507, 1.8638, 0.1512], [ 2.5679, -0.2351, -0.1907], [ 0.2100, 0.0833, 0.2342], [-0.8640, 1.3497, 0.1551], [ 3.4258, -3.5129, -0.7188]]]) >>> output.size() torch.Size([1, 10, 3]) >>> out = input@matrix >>> out tensor([[[ 0.1437, 1.2994, -0.1585], [ 2.5082, -0.0109, -0.5832], [-0.3461, -0.4641, 0.0111], [ 0.1358, -0.6681, 0.1967], [ 0.1357, 0.3903, -0.1306], [-2.7507, 1.8638, 0.1512], [ 2.5679, -0.2351, -0.1907], [ 0.2100, 0.0833, 0.2342], [-0.8640, 1.3497, 0.1551], [ 3.4258, -3.5129, -0.7188]]]) >>> input.bmm(matrix) tensor([[[ 0.1437, 1.2994, -0.1585], [ 2.5082, -0.0109, -0.5832], [-0.3461, -0.4641, 0.0111], [ 0.1358, -0.6681, 0.1967], [ 0.1357, 0.3903, -0.1306], [-2.7507, 1.8638, 0.1512], [ 2.5679, -0.2351, -0.1907], [ 0.2100, 0.0833, 0.2342], [-0.8640, 1.3497, 0.1551], [ 3.4258, -3.5129, -0.7188]]]) ``` ## torch.cat() テンソルの結合を行う https://qiita.com/Haaamaaaaa/items/709d774698082e9d342d ```python >>> input1 = torch.randn(2, 3, 4) >>> input2 = torch.randn(3, 3, 4) >>> input3 = torch.randn(5, 3, 4) >>> inputlist = [input1, input2, input3] >>> output = torch.cat(inputlist) >>> output.size() torch.Size([10, 3, 4]) ``` ## torch.eye() 対角行列を生成 ```python >>> torch.eye(3) tensor([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> torch.eye(3).view(-1) tensor([1., 0., 0., 0., 1., 0., 0., 0., 1.]) ``` ## torch.max() 最大値を取り出す。第2引数で次元を指定 ``` >>> a = torch.randn(4, 5) >>> a tensor([[-0.9413, -0.2067, -0.9084, 0.4732, -0.6856], [ 0.7210, -1.5712, 1.8576, -0.8501, -1.6156], [ 0.0607, -0.7049, -0.3230, -0.1158, 0.9874], [ 1.5044, 0.9751, 1.3197, 2.3033, -0.7163]]) >>> torch.max(a, 1) torch.return_types.max( values=tensor([0.4732, 1.8576, 0.9874, 2.3033]), indices=tensor([3, 2, 4, 3])) >>> torch.max(a, 0) torch.return_types.max( values=tensor([1.5044, 0.9751, 1.8576, 2.3033, 0.9874]), indices=tensor([3, 3, 1, 3, 2])) >>> _, pred = torch.max(a, 1) >>> pred tensor([3, 2, 4, 3]) ``` ## ファイル読み込み ```python >>> import torch >>> import os >>> folders = [dir for dir in sorted(os.listdir("Data/five_position_class")) if os.path.isdir(f"Data/five_position_class/{dir}")] >>> folders ['0', 'l45', 'l90', 'r45', 'r90'] >>> classes = {folder:i for i, folder in enumerate(folders)} >>> classes {'0': 0, 'l45': 1, 'l90': 2, 'r45': 3, 'r90': 4} ``` ## Pytorch.scheduler https://wonderfuru.com/scheduler/ # ツール ## Visdom [参考](https://qiita.com/yasudadesu/items/1dda5f9d1708b6d4d923) `% -> visdom` でサーバを起動 ## collect_env `-> % python ~/anaconda3/envs/pytorch/lib/python3.7/site-packages/torch/utils/collect_env.py ` https://github.com/pytorch/pytorch/blob/master/torch/utils/collect_env.py # 参考 [PointNet 論文](https://arxiv.org/abs/1612.00593) [Open3D ドキュメント](http://www.open3d.org/docs/release/index.html) [PyTorch ドキュメント](https://pytorch.org/docs/stable/index.html) [Deep Learning on Point clouds: Implementing PointNet in Google Colab](https://towardsdatascience.com/deep-learning-on-point-clouds-implementing-pointnet-in-google-colab-1fd65cd3a263) [点群DNN、3D DNN入門](https://qiita.com/arutema47/items/cda262c61baa953a97e9)