From c5df737b202da9feb2c368f299cd343d206af78b Mon Sep 17 00:00:00 2001 From: Danish Syed Date: Wed, 22 Apr 2020 20:24:01 -0400 Subject: [PATCH] a lot has happened --- .gitignore | 2 + Eval.ipynb | 410 ++++++++ Untitled.ipynb | 395 -------- config/train_p2m.yml | 12 +- config/train_p2m_gan.yml | 10 +- ...n_p2m_vaegan.yml => train_p2m_randgan.yml} | 12 +- sicgan/config.py | 3 + sicgan/models/generator.py | 10 +- sicgan/models/heads/mesh_head.py | 2 +- sicgan/models/heads/mesh_loss.py | 6 +- splits.ipynb | 926 ++++++++++++++++++ ...1587601309.lh0033.arc-ts.umich.edu.21914.0 | Bin 0 -> 40 bytes ...1587600678.lh0033.arc-ts.umich.edu.19326.0 | Bin 0 -> 40 bytes ...1587600859.lh0033.arc-ts.umich.edu.19923.0 | Bin 0 -> 668 bytes ...1587601355.lh0036.arc-ts.umich.edu.14887.0 | Bin 0 -> 40 bytes ...1587600694.lh0033.arc-ts.umich.edu.19418.0 | Bin 0 -> 40 bytes ...1587600964.lh0033.arc-ts.umich.edu.20455.0 | Bin 0 -> 668 bytes ...1587601104.lh0033.arc-ts.umich.edu.21070.0 | Bin 0 -> 668 bytes ....1587526621.lh0033.arc-ts.umich.edu.9194.0 | Bin 40 -> 0 bytes ...1587526785.lh0033.arc-ts.umich.edu.13352.0 | Bin 40 -> 0 bytes ...1587526838.lh0033.arc-ts.umich.edu.13904.0 | Bin 40 -> 0 bytes ...1587526976.lh0033.arc-ts.umich.edu.15093.0 | Bin 40 -> 0 bytes ...1587527128.lh0033.arc-ts.umich.edu.16627.0 | Bin 40 -> 0 bytes ...1587527166.lh0033.arc-ts.umich.edu.16999.0 | Bin 40 -> 0 bytes ...1587527949.lh0033.arc-ts.umich.edu.22614.0 | Bin 40 -> 0 bytes ...1587528041.lh0033.arc-ts.umich.edu.24245.0 | Bin 40 -> 0 bytes ...1587528149.lh0033.arc-ts.umich.edu.24999.0 | Bin 40 -> 0 bytes ...1587528553.lh0033.arc-ts.umich.edu.28138.0 | Bin 40 -> 0 bytes ...1587528858.lh0033.arc-ts.umich.edu.31498.0 | Bin 40 -> 0 bytes ...1587537693.lh0033.arc-ts.umich.edu.30301.0 | Bin 244 -> 0 bytes ...1587601305.lh0033.arc-ts.umich.edu.21834.0 | Bin 0 -> 40 bytes ...1587598840.lh0033.arc-ts.umich.edu.11981.0 | Bin 0 -> 40 bytes ...1587600127.lh0033.arc-ts.umich.edu.16075.0 | Bin 0 -> 40 bytes ...1587600246.lh0033.arc-ts.umich.edu.17102.0 | Bin 0 -> 40 bytes ...1587600470.lh0033.arc-ts.umich.edu.18514.0 | Bin 0 -> 378 bytes train_p2m.py | 19 +- train_p2m_gan.py | 25 +- train_p2m_randgan.py | 26 +- 38 files changed, 1415 insertions(+), 443 deletions(-) create mode 100644 Eval.ipynb delete mode 100644 Untitled.ipynb rename config/{train_p2m_vaegan.yml => train_p2m_randgan.yml} (83%) create mode 100644 splits.ipynb create mode 100644 tensorboard/p2m_gan/events.out.tfevents.1587601309.lh0033.arc-ts.umich.edu.21914.0 create mode 100644 tensorboard/p2m_gan_of/events.out.tfevents.1587600678.lh0033.arc-ts.umich.edu.19326.0 create mode 100644 tensorboard/p2m_gan_of/events.out.tfevents.1587600859.lh0033.arc-ts.umich.edu.19923.0 create mode 100644 tensorboard/p2m_randgan/events.out.tfevents.1587601355.lh0036.arc-ts.umich.edu.14887.0 create mode 100644 tensorboard/p2m_randgan_of/events.out.tfevents.1587600694.lh0033.arc-ts.umich.edu.19418.0 create mode 100644 tensorboard/p2m_randgan_of/events.out.tfevents.1587600964.lh0033.arc-ts.umich.edu.20455.0 create mode 100644 tensorboard/p2m_randgan_of/events.out.tfevents.1587601104.lh0033.arc-ts.umich.edu.21070.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587526621.lh0033.arc-ts.umich.edu.9194.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587526785.lh0033.arc-ts.umich.edu.13352.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587526838.lh0033.arc-ts.umich.edu.13904.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587526976.lh0033.arc-ts.umich.edu.15093.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587527128.lh0033.arc-ts.umich.edu.16627.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587527166.lh0033.arc-ts.umich.edu.16999.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587527949.lh0033.arc-ts.umich.edu.22614.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587528041.lh0033.arc-ts.umich.edu.24245.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587528149.lh0033.arc-ts.umich.edu.24999.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587528553.lh0033.arc-ts.umich.edu.28138.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587528858.lh0033.arc-ts.umich.edu.31498.0 delete mode 100644 tensorboard/p2m_vaegan_of/events.out.tfevents.1587537693.lh0033.arc-ts.umich.edu.30301.0 create mode 100644 tensorboard/pixel2mesh_baseline/events.out.tfevents.1587601305.lh0033.arc-ts.umich.edu.21834.0 create mode 100644 tensorboard/pixel2mesh_of/events.out.tfevents.1587598840.lh0033.arc-ts.umich.edu.11981.0 create mode 100644 tensorboard/pixel2mesh_of/events.out.tfevents.1587600127.lh0033.arc-ts.umich.edu.16075.0 create mode 100644 tensorboard/pixel2mesh_of/events.out.tfevents.1587600246.lh0033.arc-ts.umich.edu.17102.0 create mode 100644 tensorboard/pixel2mesh_of/events.out.tfevents.1587600470.lh0033.arc-ts.umich.edu.18514.0 diff --git a/.gitignore b/.gitignore index 8937b78..174e541 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ docs/_build # virtualenv venv/ ENV/ +*.obj +*.pth diff --git a/Eval.ipynb b/Eval.ipynb new file mode 100644 index 0000000..89a8041 --- /dev/null +++ b/Eval.ipynb @@ -0,0 +1,410 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!nvidia-smi" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "%reload_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import logging\n", + "import numpy as np\n", + "import torch, os\n", + "from sicgan.utils.metrics import compare_meshes\n", + "from tqdm import tqdm\n", + "\n", + "from IPython.core.display import display, HTML\n", + "from sicgan.config import Config\n", + "from sicgan.models import Pixel2MeshHead\n", + "from sicgan.models import GraphConvClf\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "from sicgan.models import MeshLoss\n", + "from pytorch3d.io import load_obj, save_obj\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib as mpl\n", + "import matplotlib.animation #import FuncAnimation\n", + "from matplotlib.animation import FuncAnimation\n", + "\n", + "\n", + "from sicgan.data.build_data_loader import build_data_loader\n", + "display(HTML(\"\"))\n", + "device = torch.device(\"cuda:0\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from PyGEL3D import gel\n", + "from PyGEL3D import js\n", + "def plot_mesh(mesh):\n", + " save_obj('mesh.obj', mesh.verts_packed(), mesh.faces_packed())\n", + " js.set_export_mode()\n", + " m = gel.obj_load('mesh.obj')\n", + " js.display(m, smooth=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "_C = Config('config/train_p2m.yml',[])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1500" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data_loader = build_data_loader(_C, \"MeshVox\", split_name='test', multigpu=False)\n", + "len(data_loader)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "cp = torch.load('pixel2mesh_R50.pth')[\"best_states\"][\"model\"]\n", + "from collections import OrderedDict\n", + "new_cp = OrderedDict()\n", + "for k, v in cp.items():\n", + " name = k[7:] # remove `module.`\n", + " if name != 'K':\n", + " new_cp[name] = v" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = Pixel2MeshHead(_C).cuda()\n", + "model.load_state_dict(new_cp)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " 0%| | 0/1500 [00:01,\n", + " ,\n", + " ]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "plot_mesh(meshes_gt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plot_mesh(meshes_pred[-1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Evaluation - Change this" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pytorch3d.ops import sample_points_from_meshes\n", + "from pytorch3d.loss import (\n", + " chamfer_distance, \n", + " mesh_edge_loss, \n", + " mesh_laplacian_smoothing, \n", + " mesh_normal_consistency,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "device = torch.device(\"cuda:0\")\n", + "class_names = {\n", + " \"03001627\": \"chair\",\n", + " \"04379243\": \"table\",\n", + "}\n", + "\n", + "num_instances = {i: 0 for i in class_names}\n", + "chamfer = {i: 0 for i in class_names}\n", + "# normal = {i: 0 for i in class_names}\n", + "f1_1e_4 = {i: 0 for i in class_names}\n", + "f1_2e_4 = {i: 0 for i in class_names}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "loss_fn_kwargs = {\n", + " \"chamfer_weight\": 1,\n", + " \"normal_weight\": 0,\n", + " \"edge_weight\": 0,\n", + " \"gt_num_samples\": 5000,\n", + " \"pred_num_samples\": 5000,\n", + "}\n", + "\n", + "mesh_loss = MeshLoss(**loss_fn_kwargs).cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sample_trg = sample_points_from_meshes(meshes_gt, 5000)\n", + "sample_src = sample_points_from_meshes(meshes_pred[-1], 5000)\n", + "chamfer_distance(sample_trg, sample_src)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "num_batch_evaluated = 0\n", + "cd_chair = []\n", + "cd_table = []\n", + "for batch in tqdm(data_loader):\n", + " batch = data_loader.postprocess(batch, device)\n", + " imgs, meshes_gt, _, _, id_strs = batch\n", + "# sids = [id_str.split(\"-\")[0] for id_str in id_strs]\n", + " sid = id_strs[0].split(\"-\")[0]\n", + "# for sid in sids:\n", + "# num_instances[sid] += 1\n", + "\n", + " # with inference_context(model):\n", + " \n", + " # Change this\n", + " _,meshes_pred = model(imgs) #Removed Voxels\n", + " \n", + " loss, _ = mesh_loss(meshes_gt, meshes_pred[-1])\n", + " if sid == '03001627':\n", + " cd_chair.append(loss.item())\n", + " elif sid == '04379243':\n", + " cd_table.append(loss.item())\n", + "\n", + "\n", + "# cur_metrics = compare_meshes(\n", + "# meshes_pred[-1], meshes_gt, scale=0.57, thresholds=[0.01, 0.014142], reduce=False\n", + "# )\n", + "# cur_metrics[\"verts_per_mesh\"] = meshes_pred[-1].num_verts_per_mesh().cpu()\n", + "# cur_metrics[\"faces_per_mesh\"] = meshes_pred[-1].num_faces_per_mesh().cpu()\n", + "\n", + "# for i, sid in enumerate(sids):\n", + "# chamfer[sid] += cur_metrics[\"Chamfer-L2\"][i].item()\n", + "# # normal[sid] += cur_metrics[\"AbsNormalConsistency\"][i].item()\n", + "# f1_1e_4[sid] += cur_metrics[\"F1@%f\" % 0.01][i].item()\n", + "# f1_2e_4[sid] += cur_metrics[\"F1@%f\" % 0.014142][i].item()\n", + "\n", + "# num_batch_evaluated += 1\n", + "# print(\"Evaluated %d / %d batches\" % (num_batch_evaluated, len(data_loader)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "{\"chamfer\": chamfer, \"f1_1e_4\": f1_1e_4, \"f1_2e_4\": f1_2e_4}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "np.mean(cd_chair), np.mean(cd_table)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dasyed", + "language": "python", + "name": "dasyed" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Untitled.ipynb b/Untitled.ipynb deleted file mode 100644 index 479a491..0000000 --- a/Untitled.ipynb +++ /dev/null @@ -1,395 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from IPython.core.display import display, HTML\n", - "display(HTML(\"\"))\n", - "%load_ext autoreload\n", - "%autoreload 2 " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from sicgan.models import MeshLoss" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from PyGEL3D import gel\n", - "from PyGEL3D import js\n", - "import re\n", - "from pytorch3d.io import load_obj, save_obj" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from sicgan.models import Pixel2MeshHead\n", - "from sicgan.config import Config\n", - "\n", - "\n", - "_C = Config('./config/sicgan_train.yml', [])\n", - "G = Pixel2MeshHead(_C).cuda()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "from sicgan.data.build_data_loader import build_data_loader\n", - "train = build_data_loader(_C, \"MeshVox\", split_name='train')" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "from tqdm import tqdm" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - " 0%| | 0/20634 [00:01" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "meshes" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plt.imshow(imgs[2].permute(1,2,0).numpy())" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "def plot_mesh(mesh):\n", - " save_obj('mesh.obj', mesh.verts_packed(), mesh.faces_packed())\n", - " js.set_export_mode()\n", - " m = gel.obj_load('mesh.obj')\n", - " js.display(m, smooth=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# plot_mesh(i[1][1])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "m = G(imgs.cuda())" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'Meshes' object has no attribute 'detach'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdetach\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m: 'Meshes' object has no attribute 'detach'" - ] - } - ], - "source": [ - "m.detach()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "from sicgan.models import GraphConvClf" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "D = GraphConvClf(_C).cuda()" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "tensor([[0.5000],\n", - " [0.5000],\n", - " [0.5000],\n", - " [0.5000]], device='cuda:0', grad_fn=)" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "D(m.cuda())" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - " loss_fn_kwargs = {\n", - " \"chamfer_weight\": _C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT,\n", - " \"normal_weight\": _C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT,\n", - " \"edge_weight\": _C.G.MESH_HEAD.EDGE_LOSS_WEIGHT,\n", - " \"gt_num_samples\": _C.G.MESH_HEAD.GT_NUM_SAMPLES,\n", - " \"pred_num_samples\": _C.G.MESH_HEAD.PRED_NUM_SAMPLES,\n", - " }" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "mesh_loss = MeshLoss(**loss_fn_kwargs).cuda()" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(tensor(3.7315, device='cuda:0', grad_fn=),\n", - " {'chamfer_0': tensor(2.4276, device='cuda:0', grad_fn=),\n", - " 'normal_0': tensor(0.9636, device='cuda:0', grad_fn=),\n", - " 'edge_0': tensor(0.3403, device='cuda:0', grad_fn=)})" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mesh_loss(m.cuda(), meshes.cuda())" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/config/train_p2m.yml b/config/train_p2m.yml index 2dbd193..d015bee 100644 --- a/config/train_p2m.yml +++ b/config/train_p2m.yml @@ -1,16 +1,17 @@ RANDOM_SEED: 0 PHASE: "training" -EXPERIMENT_NAME: "pixel2mesh_baseline_run2" +EXPERIMENT_NAME: "pixel2mesh_baseline" RESULTS_DIR: "results" OVERFIT: False +Z: False SOLVER: LR_SCHEDULER_NAME: "constant" # {'constant', 'cosine'} BATCH_SIZE: 32 - BATCH_SIZE_EVAL: 1 - NUM_EPOCHS: 25 + BATCH_SIZE_EVAL: 32 + NUM_EPOCHS: 100 BASE_LR: 0.0001 OPTIMIZER: "adam" # {'sgd', 'adam'} MOMENTUM: 0.9 @@ -33,7 +34,8 @@ G: GT_NUM_SAMPLES: 5000 PRED_NUM_SAMPLES: 5000 CHAMFER_LOSS_WEIGHT: 1.0 - NORMAL_LOSS_WEIGHT: 0.0 - EDGE_LOSS_WEIGHT: 0.2 + NORMAL_LOSS_WEIGHT: 0.00016 + EDGE_LOSS_WEIGHT: 0.1 + LAPLACIAN_LOSS_WEIGHT: 0.3 ICO_SPHERE_LEVEL: 2 diff --git a/config/train_p2m_gan.yml b/config/train_p2m_gan.yml index 83145f6..574dfad 100644 --- a/config/train_p2m_gan.yml +++ b/config/train_p2m_gan.yml @@ -1,9 +1,10 @@ RANDOM_SEED: 0 PHASE: "training" -EXPERIMENT_NAME: "p2m_gan_run" +EXPERIMENT_NAME: "p2m_gan" RESULTS_DIR: "results" OVERFIT: False +Z: False SHAPENET_DATA: PATH: "/scratch/jiadeng_root/jiadeng/shared_data/datasets/ShapeNetCore.v1/" @@ -35,9 +36,10 @@ G: GT_NUM_SAMPLES: 5000 PRED_NUM_SAMPLES: 5000 CHAMFER_LOSS_WEIGHT: 1.0 - NORMAL_LOSS_WEIGHT: 0.0 - EDGE_LOSS_WEIGHT: 0.2 - ICO_SPHERE_LEVEL: 2.0 + NORMAL_LOSS_WEIGHT: 0.00016 + EDGE_LOSS_WEIGHT: 0.1 + LAPLACIAN_LOSS_WEIGHT: 0.3 + ICO_SPHERE_LEVEL: 2 D: INPUT_MESH_FEATS: 3 HIDDEN_DIMS: [16, 32, 64] diff --git a/config/train_p2m_vaegan.yml b/config/train_p2m_randgan.yml similarity index 83% rename from config/train_p2m_vaegan.yml rename to config/train_p2m_randgan.yml index d8d60ef..99efe15 100644 --- a/config/train_p2m_vaegan.yml +++ b/config/train_p2m_randgan.yml @@ -1,9 +1,10 @@ RANDOM_SEED: 0 PHASE: "training" -EXPERIMENT_NAME: "p2m_vaegan_of" +EXPERIMENT_NAME: "p2m_randgan" RESULTS_DIR: "results" -OVERFIT: True +OVERFIT: False +Z: True SHAPENET_DATA: PATH: "/scratch/jiadeng_root/jiadeng/shared_data/datasets/ShapeNetCore.v1/" @@ -35,9 +36,10 @@ G: GT_NUM_SAMPLES: 5000 PRED_NUM_SAMPLES: 5000 CHAMFER_LOSS_WEIGHT: 1.0 - NORMAL_LOSS_WEIGHT: 0.0 - EDGE_LOSS_WEIGHT: 0.2 - ICO_SPHERE_LEVEL: 2.0 + NORMAL_LOSS_WEIGHT: 0.00016 + EDGE_LOSS_WEIGHT: 0.1 + LAPLACIAN_LOSS_WEIGHT: 0.3 + ICO_SPHERE_LEVEL: 2 D: INPUT_MESH_FEATS: 3 HIDDEN_DIMS: [16, 32, 64] diff --git a/sicgan/config.py b/sicgan/config.py index e6fb699..5ef9159 100755 --- a/sicgan/config.py +++ b/sicgan/config.py @@ -49,6 +49,7 @@ def __init__(self, config_yaml: str, config_override: List[Any] = []): self._C.EXPERIMENT_NAME = "default" self._C.RESULTS_DIR = "results" self._C.OVERFIT= False + self._C.Z= False self._C.SHAPENET_DATA = CN() self._C.SHAPENET_DATA.PATH = '/scratch/jiadeng_root/jiadeng/shared_data/datasets/ShapeNetCore.v1/' @@ -86,8 +87,10 @@ def __init__(self, config_yaml: str, config_override: List[Any] = []): self._C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT = 1.0 self._C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT = 1.0 self._C.G.MESH_HEAD.EDGE_LOSS_WEIGHT = 1.0 + self._C.G.MESH_HEAD.LAPLACIAN_LOSS_WEIGHT = 1.0 self._C.G.MESH_HEAD.ICO_SPHERE_LEVEL = -1 + self._C.D = CN() self._C.D.INPUT_MESH_FEATS = 3 diff --git a/sicgan/models/generator.py b/sicgan/models/generator.py index 2c063c5..744e1fd 100644 --- a/sicgan/models/generator.py +++ b/sicgan/models/generator.py @@ -20,13 +20,17 @@ def __init__(self, cfg): # backbone self.backbone, feat_dims = build_backbone(backbone) # mesh head - cfg.G.MESH_HEAD.COMPUTED_INPUT_CHANNELS = sum(feat_dims) + if cfg.Z == True: + cfg.G.MESH_HEAD.COMPUTED_INPUT_CHANNELS = sum(feat_dims) + 200 + else: + cfg.G.MESH_HEAD.COMPUTED_INPUT_CHANNELS = sum(feat_dims) + self.mesh_head = MeshRefinementHead(cfg) def _get_projection_matrix(self, N, device): return self.K[None].repeat(N, 1, 1).to(device).detach() - def forward(self, imgs, z): # z is the latent vector sampled from P(z|x) + def forward(self, imgs, z=None): # z is the latent vector sampled from P(z|x) N = imgs.shape[0] device = imgs.device @@ -36,5 +40,5 @@ def forward(self, imgs, z): # z is the latent vector sampled from P(z|x) # print(P) init_meshes = ico_sphere(self.ico_sphere_level, device).extend(N) - refined_meshes = self.mesh_head(img_feats, init_meshes, P, subdivide=True) + refined_meshes = self.mesh_head(img_feats,z, init_meshes, P, subdivide=True) return None, refined_meshes diff --git a/sicgan/models/heads/mesh_head.py b/sicgan/models/heads/mesh_head.py index 3522f40..4d43873 100644 --- a/sicgan/models/heads/mesh_head.py +++ b/sicgan/models/heads/mesh_head.py @@ -63,7 +63,7 @@ def __init__(self, img_feat_dim, vert_feat_dim, hidden_dim, stage_depth, gconv_i """ super(MeshRefinementStage, self).__init__() - self.bottleneck = nn.Linear(img_feat_dim+200, hidden_dim) + self.bottleneck = nn.Linear(img_feat_dim, hidden_dim) self.vert_offset = nn.Linear(hidden_dim + 3, 3) diff --git a/sicgan/models/heads/mesh_loss.py b/sicgan/models/heads/mesh_loss.py index 8c22b58..d622751 100644 --- a/sicgan/models/heads/mesh_loss.py +++ b/sicgan/models/heads/mesh_loss.py @@ -2,7 +2,7 @@ import torch import torch.nn as nn import torch.nn.functional as F -from pytorch3d.loss import chamfer_distance, mesh_edge_loss +from pytorch3d.loss import chamfer_distance, mesh_edge_loss, mesh_laplacian_smoothing from pytorch3d.ops import sample_points_from_meshes from pytorch3d.structures import Meshes @@ -13,8 +13,9 @@ class MeshLoss(nn.Module): def __init__( self, chamfer_weight=1.0, - normal_weight=0.0, + normal_weight=1.6e-4, edge_weight=0.1, + lap_weight=0.3, gt_num_samples=5000, pred_num_samples=5000, ): @@ -23,6 +24,7 @@ def __init__( self.chamfer_weight = chamfer_weight self.normal_weight = normal_weight self.edge_weight = edge_weight + self.lap_weight = lap_weight self.gt_num_samples = gt_num_samples self.pred_num_samples = pred_num_samples diff --git a/splits.ipynb b/splits.ipynb new file mode 100644 index 0000000..04c44cf --- /dev/null +++ b/splits.ipynb @@ -0,0 +1,926 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "import os, json\n", + "from tqdm import tqdm" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "path = '/scratch/jiadeng_root/jiadeng/shared_data/datasets/SICGAN_data/'\n", + "labels = {'04379243':'table','03211117':'monitor','04401088':'cellphone','04530566': 'watercraft', '03001627' : 'chair','03636649' : 'lamp', '03691459': 'speaker' , '02828884':'bench',\n", + "'02691156': 'plane', '02808440': 'bathtub', '02871439': 'bookcase',\n", + "'02773838': 'bag', '02801938': 'basket', '02828884' : 'bench','02880940': 'bowl' ,\n", + "'02924116': 'bus', '02933112': 'cabinet', '02942699': 'camera', '02958343': 'car', '03207941': 'dishwasher',\n", + "'03337140': 'file', '03624134': 'knife', '03642806': 'laptop', '03710193': 'mailbox',\n", + "'03761084': 'microwave', '03928116': 'piano', '03938244':'pillow', '03948459': 'pistol', '04004475': 'printer',\n", + "'04099429': 'rocket', '04256520': 'sofa', '04554684': 'washer', '04090263': 'rifle'}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "summary = defaultdict(dict)\n", + "for sid in ['03001627', '04379243']:\n", + " sid_pth = os.path.join(path, sid)\n", + " for mid in tqdm(os.listdir(sid_pth)):\n", + " mid_pth = os.path.join(sid_pth, mid)\n", + " image_list = os.listdir(os.path.join(mid_pth, 'images'))\n", + " summary[sid][mid] = len(image_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for sid in summary:\n", + " print(sid,labels[sid]+' : '+str(len(set(summary[sid]))))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open(path+'summary.json', \"w\") as f:\n", + " json.dump(summary, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open(path+'summary.json', \"r\") as f:\n", + " summary = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "split_file = defaultdict(dict)\n", + "trn_ratio = 3500\n", + "val_ratio = 4500\n", + "tst_ratio = 5500\n", + "for sid in summary:\n", + " sid_pth = os.path.join(path, sid)\n", + " sid_len = len(os.listdir(sid_pth))\n", + " for i,mid in enumerate(tqdm(os.listdir(sid_pth))):\n", + " if i < trn_ratio:\n", + " split_type = 'train'\n", + " elif i < val_ratio:\n", + " split_type = 'val'\n", + " elif i < tst_ratio:\n", + " split_type = 'test'\n", + " else:\n", + " split_type = 'leftover'\n", + " mid_pth = os.path.join(sid_pth, mid)\n", + " num_image = len(os.listdir(os.path.join(mid_pth, 'images')))\n", + " try:\n", + " split_file[split_type][sid].update({mid : [i for i in range(num_image)]})\n", + " except:\n", + " split_file[split_type][sid] = {}\n", + " split_file[split_type][sid].update({mid : [i for i in range(num_image)]})" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train\n", + "\tchair : 3500\n", + "\ttable : 3500\n", + "val\n", + "\tchair : 1000\n", + "\ttable : 1000\n", + "test\n", + "\tchair : 1000\n", + "\ttable : 1000\n", + "leftover\n", + "\tchair : 11\n", + "\ttable : 2177\n" + ] + } + ], + "source": [ + "for data in split_file:\n", + " print(data)\n", + " for sid in split_file[data]:\n", + " print('\\t'+labels[sid]+' : '+str(len(set(split_file[data][sid]))))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open(path+'p2m_splits.json', \"w\") as f:\n", + " json.dump(split_file, f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open('p2m_splits.json', \"w\") as f:\n", + " json.dump(split_file, f)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "with open(path+'p2m_splits.json', \"r\") as f:\n", + " split_file = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import argparse\n", + "import logging\n", + "import os,sys\n", + "from typing import Type\n", + "import random \n", + "from tqdm import tqdm\n", + "\n", + "import torch\n", + "import numpy as np\n", + "from torch import nn, optim\n", + "\n", + "from sicgan.config import Config\n", + "from sicgan.models import Pixel2MeshHead\n", + "from sicgan.models import GraphConvClf\n", + "from sicgan.data.build_data_loader import build_data_loader\n", + "from sicgan.models import MeshLoss\n", + "from sicgan.utils.torch_utils import save_checkpoint\n", + "from torch.utils.tensorboard import SummaryWriter\n", + "\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "_C = Config('config/train_p2m.yml', [])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trn_dataloader = build_data_loader(_C, \"MeshVox\", split_name='train')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(trn_dataloader)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "splits_file = _C.DATASETS.SPLITS_FILE\n", + "split_name = 'test'\n", + "with open(splits_file, \"r\") as f:\n", + " splits = json.load(f)\n", + "if split_name is not None:\n", + " if split_name in [\"train\", \"train_eval\"]:\n", + " split = splits[\"train\"]\n", + " else:\n", + " split = splits[split_name]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(split)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n", + "import json\n", + "import logging\n", + "import os\n", + "import torch\n", + "from pytorch3d.ops import sample_points_from_meshes\n", + "from pytorch3d.structures import Meshes\n", + "from torch.utils.data import Dataset\n", + "\n", + "import torchvision.transforms as T\n", + "from PIL import Image\n", + "from sicgan.data.utils import imagenet_preprocess, project_verts\n", + "# from shapenet.utils.coords import SHAPENET_MAX_ZMAX, SHAPENET_MIN_ZMIN, project_verts\n", + "\n", + "logger = logging.getLogger('mesh')\n", + "\n", + "\n", + "class MeshVoxDataset(Dataset):\n", + " def __init__(\n", + " self,\n", + " data_dir,\n", + " normalize_images=True,\n", + " split=None,\n", + " return_mesh=False,\n", + " voxel_size=32, # Not required\n", + " num_samples=5000,\n", + " sample_online=False,\n", + " in_memory=False,\n", + " return_id_str=False,\n", + " ):\n", + "\n", + " super(MeshVoxDataset, self).__init__()\n", + " if not return_mesh and sample_online:\n", + " raise ValueError(\"Cannot sample online without returning mesh\")\n", + " self.data_dir = data_dir\n", + " self.return_mesh = return_mesh\n", + " # self.voxel_size = voxel_size\n", + " self.num_samples = num_samples\n", + " self.sample_online = sample_online\n", + " self.return_id_str = return_id_str\n", + " \n", + " self.synset_ids = []\n", + " self.model_ids = []\n", + " self.image_ids = []\n", + " self.mid_to_samples = {}\n", + "\n", + " transform = [T.Resize((192,256))]\n", + " transform.append(T.ToTensor())\n", + " if normalize_images:\n", + " transform.append(imagenet_preprocess()) # Change this to r2n2 params\n", + " self.transform = T.Compose(transform)\n", + "\n", + " summary_json = os.path.join(data_dir, \"summary.json\")\n", + " print(data_dir)\n", + " with open(summary_json, \"r\") as f:\n", + " summary = json.load(f)\n", + " for sid in summary:\n", + " print(\"Starting synset %s\" % sid)\n", + " allowed_mids = None\n", + " if split is not None:\n", + " if sid not in split:\n", + " print(\"Skipping synset %s\" % sid)\n", + " continue\n", + " elif isinstance(split[sid], list):\n", + " print('list')\n", + " allowed_mids = set(split[sid])\n", + " elif isinstance(split, dict):\n", + " print('dict')\n", + " allowed_mids = set(split[sid].keys())\n", + " print(len(allowed_mids))\n", + "# print(allowed_mids)\n", + " a = []\n", + " b = 0\n", + " for mid, num_imgs in summary[sid].items():\n", + " a.append(mid not in allowed_mids)\n", + " if allowed_mids is not None and mid not in allowed_mids:\n", + "# print('skipping over : ', mid)\n", + "# print(mid not in allowed_mids)\n", + " continue\n", + " allowed_iids = None\n", + " if split is not None and isinstance(split[sid], dict):\n", + " allowed_iids = set(split[sid][mid])\n", + " if not sample_online and in_memory:\n", + " samples_path = os.path.join(data_dir, sid, mid, \"samples.pt\")\n", + " samples = torch.load(samples_path)\n", + " self.mid_to_samples[mid] = samples\n", + " for iid in range(num_imgs):\n", + " if allowed_iids is None or iid in allowed_iids:\n", + " b +=1\n", + " self.synset_ids.append(sid)\n", + " self.model_ids.append(mid)\n", + " self.image_ids.append(iid)\n", + "# else:\n", + "# print(iid in allowed_iids, iid, allowed_iids)\n", + "# break\n", + " print(np.sum(a),b)\n", + "\n", + " def __len__(self):\n", + " return len(self.synset_ids)\n", + "\n", + " def __getitem__(self, idx):\n", + " sid = self.synset_ids[idx]\n", + " mid = self.model_ids[idx]\n", + " iid = self.image_ids[idx]\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/scratch/jiadeng_root/jiadeng/shared_data/datasets/SICGAN_data/\n", + "Starting synset 03001627\n", + "dict\n", + "1000\n", + "4511 24000\n", + "Starting synset 04379243\n", + "dict\n", + "1000\n", + "6677 24000\n" + ] + } + ], + "source": [ + "dset = MeshVoxDataset(\n", + " _C.DATASETS.DATA_DIR,\n", + " split=split,\n", + " num_samples=_C.G.MESH_HEAD.GT_NUM_SAMPLES,\n", + " return_mesh=True,\n", + " sample_online=False,\n", + " return_id_str=False,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1500.0" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(dset)/32" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "synset_ids = []\n", + "model_ids = []\n", + "image_ids = []\n", + "mid_to_samples = {}" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/scratch/jiadeng_root/jiadeng/shared_data/datasets/SICGAN_data/\n", + "Starting synset 03001627\n", + "dict\n", + "1000\n", + "1000 24000\n", + "Starting synset 04379243\n", + "dict\n", + "1000\n", + "1000 24000\n" + ] + } + ], + "source": [ + "data_dir = _C.DATASETS.DATA_DIR\n", + "summary_json = os.path.join(data_dir, \"summary.json\")\n", + "print(data_dir)\n", + "with open(summary_json, \"r\") as f:\n", + " summary = json.load(f)\n", + " for sid in summary:\n", + " print(\"Starting synset %s\" % sid)\n", + " allowed_mids = None\n", + " if split is not None:\n", + " if sid not in split:\n", + " print(\"Skipping synset %s\" % sid)\n", + " continue\n", + " elif isinstance(split[sid], list):\n", + " print('list')\n", + " allowed_mids = set(split[sid])\n", + " elif isinstance(split, dict):\n", + " print('dict')\n", + " allowed_mids = set(split[sid].keys())\n", + " print(len(allowed_mids))\n", + " a = []\n", + " b = 0\n", + " for mid, num_imgs in summary[sid].items():\n", + " if allowed_mids is not None and mid not in allowed_mids:\n", + " # print('skipping over : ', mid)\n", + " # print(mid not in allowed_mids)\n", + " continue\n", + " else:\n", + " a.append(mid)\n", + " allowed_iids = None\n", + " if split is not None and isinstance(split[sid], dict):\n", + " allowed_iids = set(split[sid][mid])\n", + " for iid in range(num_imgs):\n", + " if allowed_iids is None or iid in allowed_iids:\n", + " b +=1\n", + " synset_ids.append(sid)\n", + " model_ids.append(mid)\n", + " image_ids.append(iid)\n", + " # else:\n", + " # print(iid in allowed_iids, iid, allowed_iids)\n", + " # break\n", + " print(len(a),b)\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "b = 0 \n", + "a = 0\n", + "m =[]\n", + "for mid, num_imgs in summary[sid].items():\n", + " a+=1\n", + " if allowed_mids is not None and mid not in allowed_mids:\n", + " b+=1\n", + " else:\n", + " m.append(mid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b, len(m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for mid, num_imgs in summary[sid].items():\n", + " print(mid, num_imgs)\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mid" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "allowed_mids = set(split[sid].keys())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mid in allowed_mids" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.core.display import display, HTML\n", + "display(HTML(\"\"))\n", + "%load_ext autoreload\n", + "%autoreload 2 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sicgan.models import MeshLoss" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from PyGEL3D import gel\n", + "from PyGEL3D import js\n", + "import re\n", + "from pytorch3d.io import load_obj, save_obj" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sicgan.models import Pixel2MeshHead\n", + "from sicgan.config import Config\n", + "\n", + "\n", + "_C = Config('./config/sicgan_train.yml', [])\n", + "G = Pixel2MeshHead(_C).cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sicgan.data.build_data_loader import build_data_loader\n", + "train = build_data_loader(_C, \"MeshVox\", split_name='train')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tqdm import tqdm" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for data in tqdm(train):\n", + " imgs = data[0]\n", + " meshes = data[1]\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "meshes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "plt.imshow(imgs[2].permute(1,2,0).numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_mesh(mesh):\n", + " save_obj('mesh.obj', mesh.verts_packed(), mesh.faces_packed())\n", + " js.set_export_mode()\n", + " m = gel.obj_load('mesh.obj')\n", + " js.display(m, smooth=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# plot_mesh(i[1][1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m = G(imgs.cuda())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m.detach()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sicgan.models import GraphConvClf" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "D = GraphConvClf(_C).cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "D(m.cuda())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + " loss_fn_kwargs = {\n", + " \"chamfer_weight\": _C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT,\n", + " \"normal_weight\": _C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT,\n", + " \"edge_weight\": _C.G.MESH_HEAD.EDGE_LOSS_WEIGHT,\n", + " \"gt_num_samples\": _C.G.MESH_HEAD.GT_NUM_SAMPLES,\n", + " \"pred_num_samples\": _C.G.MESH_HEAD.PRED_NUM_SAMPLES,\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mesh_loss = MeshLoss(**loss_fn_kwargs).cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mesh_loss(m.cuda(), meshes.cuda())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/tensorboard/p2m_gan/events.out.tfevents.1587601309.lh0033.arc-ts.umich.edu.21914.0 b/tensorboard/p2m_gan/events.out.tfevents.1587601309.lh0033.arc-ts.umich.edu.21914.0 new file mode 100644 index 0000000000000000000000000000000000000000..3d0eba16da35bb632f6123a91f14bb9da9db9168 GIT binary patch literal 40 rcmb1OfPlsI-b$QH)qS6vuek0g#hX-=n3<>NT9%quVr3MNop=oZ&ASX~ literal 0 HcmV?d00001 diff --git a/tensorboard/p2m_gan_of/events.out.tfevents.1587600678.lh0033.arc-ts.umich.edu.19326.0 b/tensorboard/p2m_gan_of/events.out.tfevents.1587600678.lh0033.arc-ts.umich.edu.19326.0 new file mode 100644 index 0000000000000000000000000000000000000000..96fea0b39d2494c8da22816f513c1c079fe979cd GIT binary patch literal 40 rcmb1OfPlsI-b$RWm{)t6uek0g#hX-=n3<>NT9%quVr8^j`1lt9%|;C2 literal 0 HcmV?d00001 diff --git a/tensorboard/p2m_gan_of/events.out.tfevents.1587600859.lh0033.arc-ts.umich.edu.19923.0 b/tensorboard/p2m_gan_of/events.out.tfevents.1587600859.lh0033.arc-ts.umich.edu.19923.0 new file mode 100644 index 0000000000000000000000000000000000000000..14c84d95a38d5d30436074293841f1a30fa1c2a9 GIT binary patch literal 668 zcmb1OfPlsI-b$Rka}Jl8uek0g#hX-=n3<>NT9%quVr8VW{F|ISR9&FAiv(wa$mVj8 zIxP_{AujHe#F9jPpZwzDcz02KeQO6T=I4`9ly4NnP@V%)?jria!_c1n4dYogsOiQ2 zj~O`sibIu4b4hXuflUtqIVUqOJszY_l&gf-VROQ-Ga67`{|m&tIE^Hsx@5VexkSLa z!V+^bfsD-jym*lFL~E1;9IT)C>MKI^F;>6%#wmDUX$8nH0*sixN!@AckUdLk2a1NM zLs&FG{iBg@VE;9#wj0G|iw?sz;PO$uB&WmiAGKGspe|e2JMk;$t{7?D-At literal 0 HcmV?d00001 diff --git a/tensorboard/p2m_randgan_of/events.out.tfevents.1587600694.lh0033.arc-ts.umich.edu.19418.0 b/tensorboard/p2m_randgan_of/events.out.tfevents.1587600694.lh0033.arc-ts.umich.edu.19418.0 new file mode 100644 index 0000000000000000000000000000000000000000..f1f53033857f97dd30e7e973f137b17cab2d522f GIT binary patch literal 40 rcmb1OfPlsI-b$R?|4#QcUvb@0iZ`h!F*8rkwJbHS#L7t0^x|&--L4HO literal 0 HcmV?d00001 diff --git a/tensorboard/p2m_randgan_of/events.out.tfevents.1587600964.lh0033.arc-ts.umich.edu.20455.0 b/tensorboard/p2m_randgan_of/events.out.tfevents.1587600964.lh0033.arc-ts.umich.edu.20455.0 new file mode 100644 index 0000000000000000000000000000000000000000..67ecf8c5e1fcad374ce9009865d1ad3e51237046 GIT binary patch literal 668 zcmb1OfPlsI-b$Py2CNg!S6p|L;!P?_%*@ksElbTSu`+so!@5%*sxHvmMS{~{!#A)x zEfFpuF7A}Xl0^NS{NmzxchRVY_70hSdt_0Rmu|wY+(q>7OhbE?6{l{fK}|3Af6TzS zbu(1CG?yfo5ZLq(kaIHg(&Itah$`s{I2=B!!>s|;^}j&Oi}U&xs4iJ9X)Y14uCT|elI3#@1$wSegKMj`# z7tz>41N*7bj?+OcF6 z;>5O&ZIi)%V#4%OkD$4O?)qH~C>joS;nLtDIy+w9K1$JS8;YO)cEdH`^3%l*PKN_A X(rzezQtE~4!|kW2dJc!E_u*3jPdU+E literal 0 HcmV?d00001 diff --git a/tensorboard/p2m_randgan_of/events.out.tfevents.1587601104.lh0033.arc-ts.umich.edu.21070.0 b/tensorboard/p2m_randgan_of/events.out.tfevents.1587601104.lh0033.arc-ts.umich.edu.21070.0 new file mode 100644 index 0000000000000000000000000000000000000000..e123e2139643643193f0ad27e2e17c81954c900f GIT binary patch literal 668 zcmb1OfPlsI-b$Q*C&+FwUvb@0iZ`h!F*8rkwJbHS#LCF+^HFd~RAm+u{wG^sLmP?vT1gtA8 zF((tq$jr}+_W|kiif3`SSMeiD5vq@|`pq}af+p^5AioGOV*2KY*cAI@?FD;LG^}gE zrNKosw$Q-dW&vM4ipxH>!ZqOX5nmgpLzIqntrpZ}>v|`C<&%;A*H$S-@*ko@# zLUE$S^J@@4F=6_tQ)H4oyR^|)6b%(GacOW7ofEHbKbw<(7mA;Dzk+MP<)^LfoDLn_ Ytg})4^!PPgA8tQwsN-k88ibTYlY9iZ`h!F*8rkwJbHS#L6g($7vb>@UIO+ diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526785.lh0033.arc-ts.umich.edu.13352.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526785.lh0033.arc-ts.umich.edu.13352.0 deleted file mode 100644 index a3fc39741eae00202f01c66946016b6a7ed56031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$Q%8Zs5$FTd_6#hX-=n3<>NT9%quVr68UXlM!m*d+_? diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526838.lh0033.arc-ts.umich.edu.13904.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526838.lh0033.arc-ts.umich.edu.13904.0 deleted file mode 100644 index a934c53ea8f819b5978f00db5335136183ee7f22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$S5T2pl2FTd_6#hX-=n3<>NT9%quVrArHC$I(p%jFBa diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526976.lh0033.arc-ts.umich.edu.15093.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587526976.lh0033.arc-ts.umich.edu.15093.0 deleted file mode 100644 index 97441581dc4571d5f8f985529f366221454d5788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$R?j+zI&Uw++DiZ`h!F*8rkwJbHS#LDQs-mdEa;w}x| diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527128.lh0033.arc-ts.umich.edu.16627.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527128.lh0033.arc-ts.umich.edu.16627.0 deleted file mode 100644 index 84705ec426256ee253b0ccec6f65203b217a5e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$S5)i!1CmtS|3;!P?_%*@ksElbTSu`-IuVcY`%(?bkL diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527166.lh0033.arc-ts.umich.edu.16999.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527166.lh0033.arc-ts.umich.edu.16999.0 deleted file mode 100644 index 0b067cae6a76c0420f2a42430271edbe8363b50c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$Q*w3_PQFTd_6#hX-=n3<>NT9%quVrBIG-i_k`=jjf~ diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527949.lh0033.arc-ts.umich.edu.22614.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587527949.lh0033.arc-ts.umich.edu.22614.0 deleted file mode 100644 index 7d5c5a4ef9886ae9931e2ed55f8e69021186c2b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$Q&fzHk!mS1<2;!P?_%*@ksElbTSu`*&cUUdur!0!vZ diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528041.lh0033.arc-ts.umich.edu.24245.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528041.lh0033.arc-ts.umich.edu.24245.0 deleted file mode 100644 index 4cc625faee6b7979ca4fe5c215b881d1af310b0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$SOnWa%5mS1<2;!P?_%*@ksElbTSu`=r3uxKR!&E^dJ diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528149.lh0033.arc-ts.umich.edu.24999.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528149.lh0033.arc-ts.umich.edu.24999.0 deleted file mode 100644 index f37a95b22b880b8af4a5ed5f782113737170f7c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$R8f7h0NSbp76iZ`h!F*8rkwJbHS#L6hn^hYcJ^6?GV diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528553.lh0033.arc-ts.umich.edu.28138.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528553.lh0033.arc-ts.umich.edu.28138.0 deleted file mode 100644 index 3d4caaa3b01376dd5818c94a6684206484b16a1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$Ru96fG*Sbp76iZ`h!F*8rkwJbHS#LCDZHLV-~;l~Wh diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528858.lh0033.arc-ts.umich.edu.31498.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587528858.lh0033.arc-ts.umich.edu.31498.0 deleted file mode 100644 index c163d06df0e1f9f5f5462b1a20a74dec8ed35f66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmb1OfPlsI-b$RmwzQ~yTz=hAiZ`h!F*8rkwJbHS#LDQ;xnOnx>)8#g diff --git a/tensorboard/p2m_vaegan_of/events.out.tfevents.1587537693.lh0033.arc-ts.umich.edu.30301.0 b/tensorboard/p2m_vaegan_of/events.out.tfevents.1587537693.lh0033.arc-ts.umich.edu.30301.0 deleted file mode 100644 index b9dc322e044ba33ab9cc549d2c67d8d6c644a1da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmb1OfPlsI-b$Q5r+6Lzx%|4L6mL>dVrHJ6YguYuiIvgfn^O+RL)8U(yGU^MUcXoU z3#d*@giDBvJ0-CsQ9mcYxH#Tj^z*wt_DNULj-x1_dkedA7tw7`l^jpI>K<2vnqKVx zn1S=pZK!f-E=evSu<0Qn=Va!k$Ahd9RoT79-qUgaVhyOS{{>=RoTu+Wb;)u`bBTa; ag(c=>0vVb4dGS6VeI9RC*{jcX?g9YMepQwL diff --git a/tensorboard/pixel2mesh_baseline/events.out.tfevents.1587601305.lh0033.arc-ts.umich.edu.21834.0 b/tensorboard/pixel2mesh_baseline/events.out.tfevents.1587601305.lh0033.arc-ts.umich.edu.21834.0 new file mode 100644 index 0000000000000000000000000000000000000000..56541f47eea03522aaf757dd00ec974935a21a0d GIT binary patch literal 40 rcmb1OfPlsI-b$RCiz1$xuek0g#hX-=n3<>NT9%quVr5jdNZbqn*XImF literal 0 HcmV?d00001 diff --git a/tensorboard/pixel2mesh_of/events.out.tfevents.1587598840.lh0033.arc-ts.umich.edu.11981.0 b/tensorboard/pixel2mesh_of/events.out.tfevents.1587598840.lh0033.arc-ts.umich.edu.11981.0 new file mode 100644 index 0000000000000000000000000000000000000000..87003eed31bc8c1def1db5c58a1cb8a8c3d48ccd GIT binary patch literal 40 rcmb1OfPlsI-b$QL3T5g{S6p|L;!P?_%*@ksElbTSu`>D?^yfPO(4`HU literal 0 HcmV?d00001 diff --git a/tensorboard/pixel2mesh_of/events.out.tfevents.1587600127.lh0033.arc-ts.umich.edu.16075.0 b/tensorboard/pixel2mesh_of/events.out.tfevents.1587600127.lh0033.arc-ts.umich.edu.16075.0 new file mode 100644 index 0000000000000000000000000000000000000000..746833664ba3da7566dc4bfcc3c40d5a07eb964c GIT binary patch literal 40 rcmb1OfPlsI-b$P+?jPN6w&J>@6mL>dVrHJ6YguYuiItJt{rX4%>5vV6 literal 0 HcmV?d00001 diff --git a/tensorboard/pixel2mesh_of/events.out.tfevents.1587600246.lh0033.arc-ts.umich.edu.17102.0 b/tensorboard/pixel2mesh_of/events.out.tfevents.1587600246.lh0033.arc-ts.umich.edu.17102.0 new file mode 100644 index 0000000000000000000000000000000000000000..7168164c52c6747e1e9d1a032a2154c9566c9d9b GIT binary patch literal 40 rcmb1OfPlsI-b$Pkc22x&w&J>@6mL>dVrHJ6YguYuiIvgv%|(j<;uj5@ literal 0 HcmV?d00001 diff --git a/tensorboard/pixel2mesh_of/events.out.tfevents.1587600470.lh0033.arc-ts.umich.edu.18514.0 b/tensorboard/pixel2mesh_of/events.out.tfevents.1587600470.lh0033.arc-ts.umich.edu.18514.0 new file mode 100644 index 0000000000000000000000000000000000000000..8224fb2a59a16e133086ba9ea24bf89368bbdb1b GIT binary patch literal 378 zcmb1OfPlsI-b$R27R{pOE3P|A@g@}|X6EU+mZj#ESQ#mMX^N;p)fM|cX5gIUoFE2L zrzOoL$t9GMSdyq80@9F~mmZ&!UtBDDuY}d%rT@WP4XCdF1!7*DGd-cYWVxidM8LYj z5_2+vjLiJJcps3y&2PCK;`T^JqUbwuH%J_0n*bwD`&6fLI^w+sK5|#sVEShwJgTr=!@&dJ?V=w~hZBxgA#SoOA#H D3)FOh literal 0 HcmV?d00001 diff --git a/train_p2m.py b/train_p2m.py index 5cbae32..c0008b9 100644 --- a/train_p2m.py +++ b/train_p2m.py @@ -91,6 +91,7 @@ "chamfer_weight": _C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT, "normal_weight": _C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT, "edge_weight": _C.G.MESH_HEAD.EDGE_LOSS_WEIGHT, + "lap_weight": _C.G.MESH_HEAD.LAPLACIAN_LOSS_WEIGHT, "gt_num_samples": _C.G.MESH_HEAD.GT_NUM_SAMPLES, "pred_num_samples": _C.G.MESH_HEAD.PRED_NUM_SAMPLES, } @@ -98,7 +99,7 @@ mesh_loss = MeshLoss(**loss_fn_kwargs).cuda() ## Optimizers - G_optimizer = torch.optim.Adam(G.parameters(), lr= 0.001, betas=(0.5, 0.999)) + G_optimizer = torch.optim.Adam(G.parameters(), lr= 1e-5) ## Tensorboard tb = SummaryWriter(os.path.join('tensorboard/', _C.CKP.full_experiment_name)) @@ -128,7 +129,7 @@ ## Update G network G_optimizer.zero_grad() - meshes_G = G(imgs) + _, meshes_G = G(imgs) loss_G, _ = mesh_loss(meshes_G, meshes) loss_G.backward() G_optimizer.step() @@ -137,7 +138,7 @@ if _C.OVERFIT: - if step%10==0: + if step%2==0: break # ---------------------------------------------------------------------------------------- @@ -150,11 +151,12 @@ meshes = data[1].cuda() with torch.no_grad(): - meshes_G = G(imgs) + _, meshes_G = G(imgs) val_loss, _ = mesh_loss(meshes_G, meshes) val_losses.append(val_loss.item()) if _C.OVERFIT: - break + if step%2==0: + break print("===> Epoch[{}]: Loss_G: {:.4f}".format(epoch, np.mean(trn_losses))) tb.add_scalar('data/Training_loss', np.mean(trn_losses), epoch) @@ -163,8 +165,10 @@ if (np.mean(val_losses) <= best_val_loss): best_val_loss = np.mean(val_losses) - torch.save(G.state_dict(), os.path.join(_C.CKP.experiment_path,'p2m.pth')) + torch.save(G.state_dict(), os.path.join(_C.CKP.experiment_path,'G.pth')) print('Best Loss: ', best_val_loss) + if _C.OVERFIT and epoch==2: + break # args = save_checkpoint(G = G, # D = D, @@ -175,7 +179,8 @@ # curr_step = step, # args = args, # filename = ('model@epoch%d.pkl' %(epoch))) - + + print('---------------------------------------------------------------------------------------\n') print('Finished Training') tb.close() \ No newline at end of file diff --git a/train_p2m_gan.py b/train_p2m_gan.py index d3bbf8f..b0909cd 100644 --- a/train_p2m_gan.py +++ b/train_p2m_gan.py @@ -100,6 +100,7 @@ "chamfer_weight": _C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT, "normal_weight": _C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT, "edge_weight": _C.G.MESH_HEAD.EDGE_LOSS_WEIGHT, + "lap_weight": _C.G.MESH_HEAD.LAPLACIAN_LOSS_WEIGHT, "gt_num_samples": _C.G.MESH_HEAD.GT_NUM_SAMPLES, "pred_num_samples": _C.G.MESH_HEAD.PRED_NUM_SAMPLES, } @@ -108,8 +109,8 @@ clf_loss = nn.BCELoss().cuda() ## Optimizers - G_optimizer = torch.optim.Adam(G.parameters(), lr= 0.001, betas=(0.5, 0.999)) - D_optimizer = torch.optim.Adam(D.parameters(), lr= 0.01, betas=(0.5, 0.999)) + G_optimizer = torch.optim.Adam(G.parameters(), lr= 1e-5) + D_optimizer = torch.optim.Adam(D.parameters(), lr= 0.001) ## Tensorboard tb = SummaryWriter(os.path.join('tensorboard/', _C.CKP.full_experiment_name)) @@ -140,12 +141,12 @@ imgs = data[0].cuda() meshes = data[1].cuda() - meshes_G = G(imgs, z=None) + _, meshes_G = G(imgs, z=None) ## Update D network D_optimizer.zero_grad() with torch.no_grad(): - D_neg = D(meshes_G) + D_neg = D(meshes_G[-1]) D_pos = D(meshes) @@ -158,9 +159,9 @@ G_optimizer.zero_grad() recon_loss, _ = mesh_loss(meshes_G, meshes) - D_neg = D(meshes_G) + D_neg = D(meshes_G[-1]) - loss_G = recon_loss + clf_loss(D_neg, Variable(torch.ones(D_neg.size()).cuda())) + loss_G = 0.1*recon_loss + clf_loss(D_neg, Variable(torch.ones(D_neg.size()).cuda())) loss_G.backward() G_optimizer.step() @@ -168,9 +169,8 @@ D_losses.append(loss_D.item()) G_losses.append(loss_G.item()) - if _C.OVERFIT: - if step%3==0: + if step%2==0: break # ---------------------------------------------------------------------------------------- @@ -185,11 +185,11 @@ with torch.no_grad(): - meshes_G = G(imgs, z=None) + _,meshes_G = G(imgs, z=None) val_loss, _ = mesh_loss(meshes_G, meshes) val_losses.append(val_loss.item()) if _C.OVERFIT: - if step%3==0: + if step%2==0: break # Print Summary and update tensorboard @@ -206,9 +206,8 @@ torch.save(D.state_dict(), os.path.join(_C.CKP.experiment_path,'D.pth')) print('Best Loss: ', best_val_loss) - if _C.OVERFIT: - if epoch == 2: - break + if _C.OVERFIT and epoch==2: + break print('---------------------------------------------------------------------------------------\n') diff --git a/train_p2m_randgan.py b/train_p2m_randgan.py index e3413e1..361776b 100644 --- a/train_p2m_randgan.py +++ b/train_p2m_randgan.py @@ -95,17 +95,19 @@ "chamfer_weight": _C.G.MESH_HEAD.CHAMFER_LOSS_WEIGHT, "normal_weight": _C.G.MESH_HEAD.NORMAL_LOSS_WEIGHT, "edge_weight": _C.G.MESH_HEAD.EDGE_LOSS_WEIGHT, + "lap_weight": _C.G.MESH_HEAD.LAPLACIAN_LOSS_WEIGHT, "gt_num_samples": _C.G.MESH_HEAD.GT_NUM_SAMPLES, "pred_num_samples": _C.G.MESH_HEAD.PRED_NUM_SAMPLES, } + mesh_loss = MeshLoss(**loss_fn_kwargs).cuda() clf_loss = nn.BCELoss().cuda() ## Optimizers # E_optimizer = torch.optim.Adam(E.parameters(), lr= 0.02, betas=(0.5, 0.999)) - G_optimizer = torch.optim.Adam(G.parameters(), lr= 0.002, betas=(0.5, 0.999)) - D_optimizer = torch.optim.Adam(D.parameters(), lr= 0.02, betas=(0.5, 0.999)) + G_optimizer = torch.optim.Adam(G.parameters(), lr= 1e-5) + D_optimizer = torch.optim.Adam(D.parameters(), lr= 0.001) ## Tensorboard tb = SummaryWriter(os.path.join('tensorboard/', _C.CKP.full_experiment_name)) @@ -143,13 +145,13 @@ # z, means, sigmas = E(imgs) # print(z) z = torch.randn((imgs.shape[0],200)).cuda() - meshes_G = G(imgs,z) + _, meshes_G = G(imgs,z) D_optimizer.zero_grad() ## Update D network with torch.no_grad(): - D_neg = D(meshes_G) + D_neg = D(meshes_G[-1]) D_pos = D(meshes) # print('Device',D_neg.device) @@ -160,13 +162,15 @@ loss_D.backward(retain_graph=True) D_optimizer.step() - #Update E&G Network + #Update G Network # E_optimizer.zero_grad() G_optimizer.zero_grad() + + D_neg = D(meshes_G[-1]) # loss_kl_E = torch.mean(0.5 * torch.sum(torch.exp(sigmas) + means**2 - 1. - sigmas, 1)) recon_loss, _ = mesh_loss(meshes_G, meshes) - loss_G = recon_loss + clf_loss(D_neg, torch.ones(D_neg.size()).cuda()) + loss_G = 0.1*recon_loss + clf_loss(D_neg, torch.ones(D_neg.size()).cuda()) # loss_EG = loss_kl_E + loss_G loss_G.backward() # E_optimizer.step() @@ -181,7 +185,7 @@ if _C.OVERFIT: - if step%10==0: + if step%2==0: break # ---------------------------------------------------------------------------------------- @@ -199,10 +203,14 @@ with torch.no_grad(): # z_v,_,_ = E(imgs) z_v = torch.randn((imgs.shape[0],200)).cuda() - meshes_G = G(imgs,z_v) # -----Check which z you have to consider here!------- + _, meshes_G = G(imgs,z_v) # -----Check which z you have to consider here!------- val_loss, _ = mesh_loss(meshes_G, meshes) val_losses.append(val_loss.item()) + if _C.OVERFIT: + if step%2==0: + break + @@ -218,6 +226,8 @@ torch.save(D.state_dict(), os.path.join(_C.CKP.experiment_path,'D.pth')) torch.save(G.state_dict(), os.path.join(_C.CKP.experiment_path,'G.pth')) # torch.save(E.state_dict(), os.path.join(_C.CKP.experiment_path,'E.pth')) + if _C.OVERFIT and epoch==2: + break print('---------------------------------------------------------------------------------------\n') print('Finished Training')