From 245f811d47fae241404ad6a12685fe3fb27a0a75 Mon Sep 17 00:00:00 2001 From: Hunor Laczko Date: Tue, 14 Jun 2022 10:16:55 +0000 Subject: [PATCH] train on template only with mask applied --- .gitignore | 8 ++- dataset.py | 4 +- inference_custom.py | 8 +-- load_models.py | 3 +- losses.py | 2 +- models/.gitignore | 5 -- reconstruct.py | 90 +++++++++++++++++++++++------- stylegan2/generator.py | 1 + stylegan2/layers/mapping_block.py | 10 ++-- temp.jpg | Bin 64583 -> 17360 bytes train.py | 41 +++++++------- 11 files changed, 112 insertions(+), 60 deletions(-) delete mode 100644 models/.gitignore diff --git a/.gitignore b/.gitignore index 4d09f44..469e186 100644 --- a/.gitignore +++ b/.gitignore @@ -135,5 +135,9 @@ dmypy.json .vscode/ wandb/ -output/ -output.zip \ No newline at end of file +output/* +*.zip +*.out +models/ +models_archive/ +temp.jpg diff --git a/dataset.py b/dataset.py index 58ac10b..55a635e 100644 --- a/dataset.py +++ b/dataset.py @@ -27,12 +27,12 @@ class DatasetSimple(tf.data.Dataset): uv_mask = np.load(os.path.join(folder, 'uv_mask', id + '.npz')); uv_mask=uv_mask['uv_mask']; uv_mask = uv_mask.astype(np.float32) # uv_posed, (pose, shape, uv_static), mesh_static, mesh_body_posed, mask - yield uv_posed, (pose_shape[:72], pose_shape[72:], uv_static), mesh_static, mesh_body_posed, mesh_mask, uv_mask + yield uv_posed, (pose_shape[:72], pose_shape[72:], uv_static, uv_mask), mesh_static, mesh_body_posed, mesh_mask def __new__(cls, folder, res=256): return tf.data.Dataset.from_generator( cls._generator, - output_signature = (tf.TensorSpec(shape = (3, res * 2, res,), dtype = tf.float32), (tf.TensorSpec(shape = (72), dtype = tf.float32), tf.TensorSpec(shape = (11), dtype = tf.float32), tf.TensorSpec(shape = (3, res * 2, res,), dtype = tf.float32) ), tf.TensorSpec(shape = (14475, 3,), dtype = tf.float32), tf.TensorSpec(shape = (14475, 3,), dtype = tf.float32), tf.TensorSpec(shape = (14475,), dtype = tf.float32), tf.TensorSpec(shape = (res * 2, res,), dtype = tf.float32) ), + output_signature = (tf.TensorSpec(shape = (3, res * 2, res,), dtype = tf.float32), (tf.TensorSpec(shape = (72), dtype = tf.float32), tf.TensorSpec(shape = (11), dtype = tf.float32), tf.TensorSpec(shape = (3, res * 2, res,), dtype = tf.float32), tf.TensorSpec(shape = (res * 2, res,), dtype = tf.float32) ), tf.TensorSpec(shape = (14475, 3,), dtype = tf.float32), tf.TensorSpec(shape = (14475, 3,), dtype = tf.float32), tf.TensorSpec(shape = (14475,), dtype = tf.float32) ), args=(folder, ) ) diff --git a/inference_custom.py b/inference_custom.py index ccfa0f0..b5203a7 100644 --- a/inference_custom.py +++ b/inference_custom.py @@ -43,7 +43,7 @@ def uv_to_mesh(uv): def inference(ckpt_dir, use_custom_cuda, res, folder, data_folder, samples=50): # create generator resolutions = [4, 8, 16, 32, 64, 128, 256, 512, 1024] - featuremaps = [512, 512, 512, 512, 512, 256, 128, 64, 32] + featuremaps = [256, 256, 256, 256, 256, 128, 64, 32, 16] filter_index = resolutions.index(res) g_params = { 'z_dim': 256, @@ -66,7 +66,7 @@ def inference(ckpt_dir, use_custom_cuda, res, folder, data_folder, samples=50): batch[1]], training=False, truncation_psi=0.5) - np.savez_compressed(os.path.join(folder, str(i) + '.npz'), uv=tf.squeeze(fake_images), template=tf.squeeze(batch[1][2]), body=tf.squeeze(batch[3]), mask=tf.squeeze(batch[4])) + np.savez_compressed(os.path.join(folder, str(i) + '.npz'), uv=tf.squeeze(fake_images), template=tf.squeeze(batch[1][2]), body=tf.squeeze(batch[3]), mask=tf.squeeze(batch[4]), gt=tf.squeeze(batch[0])) img = np.transpose(np.round((fake_images + 1) * 128)[0], [1,2,0]) cv2.imwrite(os.path.join(folder, str(i) + '.jpg'), img) i += 1 @@ -83,9 +83,9 @@ def main(): checkpoints = [ { 'res': 512, - 'ckpt_dir': 'models/stylegan2-test-8-512x512', + 'ckpt_dir': 'models/stylegan2-test-12-512x512', 'use_custom_cuda': True, - 'folder': 'output/test-8-196000', + 'folder': 'output/test-12-140000', 'data_folder': '/home/workspace/data/dataset/stylegan_new/train' }, ] diff --git a/load_models.py b/load_models.py index 6537c29..e55b0dd 100644 --- a/load_models.py +++ b/load_models.py @@ -18,7 +18,8 @@ def load_generator(g_params=None, is_g_clone=False, ckpt_dir=None, custom_cuda=T } test_latent = tf.ones((1, g_params['z_dim']), dtype=tf.float32) - test_conditions = (tf.ones((1, 72), dtype=tf.float32), tf.ones((1, 11), dtype=tf.float32), tf.ones((1, 3, 512, 256), dtype=tf.float32)) + test_conditions = (tf.ones((1, 72), dtype=tf.float32), tf.ones((1, 11), dtype=tf.float32), tf.ones((1, 3, 512, 256), dtype=tf.float32), tf.ones((1, 512, 256), dtype=tf.float32)) + # test_conditions = (tf.ones((1, 72), dtype=tf.float32), tf.ones((1, 11), dtype=tf.float32), tf.ones((1, 3, 512, 256), dtype=tf.float32)) # build generator model generator = Generator(g_params) diff --git a/losses.py b/losses.py index ee5bb63..d9245eb 100644 --- a/losses.py +++ b/losses.py @@ -70,7 +70,7 @@ def g_logistic_ns_pathreg(real_images, generator, discriminator, z_dim, pl_minibatch = tf.maximum(1, tf.math.floordiv(batch_size, pl_minibatch_shrink)) pl_z = tf.random.normal(shape=[pl_minibatch, z_dim], dtype=tf.float32) - pl_conditions = (conditions[0][:pl_minibatch], conditions[1][:pl_minibatch], conditions[2][:pl_minibatch]) + pl_conditions = (conditions[0][:pl_minibatch], conditions[1][:pl_minibatch], conditions[2][:pl_minibatch], conditions[3][:pl_minibatch]) # forward pass fake_images = generator([z, conditions], ret_w_broadcasted=False, training=True) diff --git a/models/.gitignore b/models/.gitignore deleted file mode 100644 index cfeac87..0000000 --- a/models/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# ignore all -* - -# except this file -!.gitignore \ No newline at end of file diff --git a/reconstruct.py b/reconstruct.py index 15811c3..14d2606 100644 --- a/reconstruct.py +++ b/reconstruct.py @@ -22,10 +22,10 @@ def m2uv_array(m2uv): def uv_to_mesh(uv): uv_res = 256 # m2uv = np.load('/workspace/Code/featurelines/MeshUtils/m2uv.npy', allow_pickle=True).item() - m2uv = np.load(r'D:\Work\Code\featurelines\MeshUtils\m2uv.npy', allow_pickle=True).item() + m2uv = np.load('custom_utils\m2uv.npy', allow_pickle=True).item() m2uv = m2uv_array(m2uv) # uv_map = np.load('/workspace/Code/featurelines/Meshutils/stretched_uv_map_3.npy') - uv_map = np.load(r'D:\Work\Code\featurelines\MeshUtils\stretched_uv_map_3.npy') + uv_map = np.load('custom_utils\stretched_uv_map_3.npy') uv_map_discreet = np.floor(uv_map * uv_res).astype(np.int32) mesh = np.zeros((14475, 3)) @@ -36,36 +36,84 @@ def uv_to_mesh(uv): return mesh -def plot(uv, mesh): - fig = plt.figure(figsize=(15, 15)) - ax = fig.add_subplot(111, projection='3d') - ax.set_xlim3d(-1, 1) - ax.set_ylim3d(-1, 1) - ax.set_zlim3d(-1, 1) - ax.set_xlabel("X") - ax.set_ylabel("Y") - ax.set_zlabel("Z") - ax.scatter(mesh[:, 0], mesh[:, 1], mesh[:, 2], s=5) - # plt.show() +def _maskFaces(V, F, mask): + V_mask = mask + F_mask = np.take(V_mask, F.reshape(-1), axis=0) + F_mask = F_mask.reshape((-1, 3)).sum(axis=1) == 3 + + V_ind = np.zeros(V_mask.shape) + V_ind[V_mask] = np.arange(V_mask.sum()) + F_new = np.take(V_ind, F[F_mask, :].reshape(-1), axis=0).reshape((-1, 3)) + V_new = V[V_mask, :] + + return V_new, F_new + +def maskFacesBatch(V, F, mask): + Vs = [] + Fs = [] + for i in range(mask.shape[0]): + v, f = _maskFaces(V[i], F, mask[i]) + Vs.append(v) + Fs.append(f) + return Vs, Fs + +def plot(uv, mesh, faces, body, F, template, uv_gt, mesh_gt): + # fig = plt.figure(figsize=(15, 15)) + # ax = fig.add_subplot(111, projection='3d') + # ax.set_xlim3d(-1, 1) + # ax.set_ylim3d(-1, 1) + # ax.set_zlim3d(-1, 1) + # ax.set_xlabel("X") + # ax.set_ylabel("Y") + # ax.set_zlabel("Z") + # ax.scatter(mesh[:, 0], mesh[:, 1], mesh[:, 2], s=5) + # # plt.show() fig = plt.figure(figsize=(15, 15)) - ax = fig.add_subplot(111) - ax.imshow(np.round( (uv - uv.min()) / (uv.max() - uv.min()) * 255).astype(np.int32)) + ax = fig.add_subplot(131) + ax.imshow(np.round((uv + 1) * 128).astype(np.int32)) + ax = fig.add_subplot(132) + ax.imshow(np.round((template + 1) * 128).astype(np.int32)) + ax = fig.add_subplot(133) + ax.imshow(np.round((uv_gt + 1) * 128).astype(np.int32)) plt.show() - F = np.load(r'D:\Work\Code\featurelines\FeatureLines\superSMPL\smpl_faces.npy') - tm.Trimesh(mesh, F).show() + collision = np.concatenate((body, mesh), axis=0) + collision_faces = np.concatenate((F, faces + 14475), axis=0) + collision_color = np.concatenate((np.ones_like(body, dtype=np.int32)*100, np.ones_like(mesh, dtype=np.int32)*230), axis=0) + + + tm.Trimesh(mesh, faces).show() + tm.Trimesh(mesh_gt, faces).show() + # tm.Trimesh(collision, collision_faces, vertex_colors=collision_color).show() if __name__ == '__main__': file = sys.argv[1] - uv = np.load(file) - uv = np.transpose(uv['uv'][0], [1,2,0]) - mesh = uv_to_mesh(uv) + for i in range(50): + file = r'Z:\Work\Huni\Barcelona\Output\stylegan\test-12-15000\\' + str(i) + '.npz' - plot(uv, mesh) + F = np.load('custom_utils\smpl_faces.npy') + data = np.load(file) + uv = np.transpose(data['uv'], [1,2,0]) + uv_gt = np.transpose(data['gt'], [1,2,0]) + mask = data['mask'].astype(bool) + template = np.transpose(data['template'], [1,2,0]) + + + mesh = uv_to_mesh(uv) + mesh_gt = uv_to_mesh(uv_gt) + + template_mesh = uv_to_mesh(template) + filter = np.abs(np.sum(mesh, axis=-1)) < 1e-2 + overlap = np.sum((((np.sum(template_mesh, axis=-1) * mask) * (np.sum(mesh, axis=-1) * filter * mask))) > 0) + + mesh, faces = _maskFaces(mesh, F, mask) + plot(uv, mesh, faces, data['body'], F, template, uv_gt, mesh_gt[mask, :]) + + pass pass diff --git a/stylegan2/generator.py b/stylegan2/generator.py index bd28579..efa4c5b 100644 --- a/stylegan2/generator.py +++ b/stylegan2/generator.py @@ -102,6 +102,7 @@ class Generator(tf.keras.Model): w_broadcasted = self.truncation_trick(w_broadcasted, truncation_psi, truncation_cutoff) image_out = self.synthesis(w_broadcasted) + image_out = image_out * conditions[3][:,tf.newaxis,:,:] if ret_w_broadcasted: return image_out, w_broadcasted diff --git a/stylegan2/layers/mapping_block.py b/stylegan2/layers/mapping_block.py index 75eddc0..a86311e 100644 --- a/stylegan2/layers/mapping_block.py +++ b/stylegan2/layers/mapping_block.py @@ -14,8 +14,9 @@ class Mapping(tf.keras.layers.Layer): self.gain = 1.0 self.lrmul = 0.01 - self.pose_shape_embedding = PoseShapeEmbedding() - self.garment_embedding = GarmentEmbedding((self.w_dim * 2) - (216 + 11)) + # self.pose_shape_embedding = PoseShapeEmbedding() + # self.garment_embedding = GarmentEmbedding((self.w_dim * 2) - (216 + 11)) + self.garment_embedding = GarmentEmbedding(self.w_dim) self.normalize = tf.keras.layers.Lambda(lambda x: x * tf.math.rsqrt(tf.reduce_mean(tf.square(x), axis=1, keepdims=True) + 1e-8)) @@ -30,9 +31,10 @@ class Mapping(tf.keras.layers.Layer): x = latents # embed label if any - pose_shape_latent = self.pose_shape_embedding([conditions[0], conditions[1]]) + # pose_shape_latent = self.pose_shape_embedding([conditions[0], conditions[1]]) garment_latent = self.garment_embedding(conditions[2]) - x = tf.concat([x, pose_shape_latent, garment_latent], axis=1) + # x = tf.concat([x, pose_shape_latent, garment_latent], axis=1) + x = tf.concat([x, garment_latent], axis=1) # normalize inputs x = self.normalize(x) diff --git a/temp.jpg b/temp.jpg index f8c45156af7645d1ecec33adbf2a7002dbbd79b0..25487f1fd65667eb251d7673d53fbefc19b15608 100644 GIT binary patch literal 17360 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 W5d(k3z#lR2M-2RZW5Dm{?Ee9(PCeNG diff --git a/train.py b/train.py index 76ccefb..296b8bb 100644 --- a/train.py +++ b/train.py @@ -17,12 +17,13 @@ from losses import d_logistic, d_logistic_r1_reg, g_logistic_non_saturating, g_l from losses import collision_loss as collision_penalty -os.environ["CUDA_VISIBLE_DEVICES"] = "2" -run = wandb.init(config=tf.compat.v1.flags.FLAGS, sync_tensorboard=True, project='stylegan', name='test_conditioned_7(test-10)') -artifact = wandb.Artifact('code', type='code') -artifact.add_file('train.py') -artifact.add_file('losses.py') -run.log_artifact(artifact) +os.environ["CUDA_VISIBLE_DEVICES"] = "1" +# run = wandb.init(config=tf.compat.v1.flags.FLAGS, sync_tensorboard=True, project='stylegan', name='test_conditioned_10(test-13)') +# artifact = wandb.Artifact('code', type='code') +# artifact.add_file('train.py') +# artifact.add_file('losses.py') +# artifact.add_file('stylegan2/layers/mapping_block.py') +# run.log_artifact(artifact) def initiate_models(g_params, d_params, use_custom_cuda): discriminator = load_discriminator(d_params, ckpt_dir=None, custom_cuda=use_custom_cuda) @@ -124,13 +125,12 @@ class Trainer(object): return params_copy def d_train_step(self, dist_inputs): - real_images, conditions, _, _, _, _ = dist_inputs[0] + real_images, conditions, _, _, _ = dist_inputs[0] with tf.GradientTape() as d_tape: # compute losses d_loss = d_logistic(real_images, self.generator, self.discriminator, self.g_params['z_dim'], conditions=conditions) - # scale loss d_loss = tf.reduce_sum(d_loss) * self.global_batch_scaler @@ -141,7 +141,7 @@ class Trainer(object): return d_loss def d_train_step_reg(self, dist_inputs): - real_images, conditions, _, _, _, _ = dist_inputs[0] + real_images, conditions, _, _, _ = dist_inputs[0] with tf.GradientTape() as d_tape: # compute losses @@ -162,7 +162,7 @@ class Trainer(object): def g_train_step(self, dist_inputs): - real_images, conditions, _, _, _, _ = dist_inputs[0] + real_images, conditions, _, _, _ = dist_inputs[0] with tf.GradientTape() as g_tape: # compute losses @@ -176,7 +176,7 @@ class Trainer(object): return g_loss def g_train_step_reg(self, dist_inputs): - real_images, conditions, _, _, _, _ = dist_inputs[0] + real_images, conditions, _, _, _ = dist_inputs[0] with tf.GradientTape() as g_tape: # compute losses @@ -198,16 +198,16 @@ class Trainer(object): def g_train_step_extra(self, dist_inputs): - real_images, conditions, mesh_static, mesh_body_posed, mesh_mask, uv_mask = dist_inputs[0] + real_images, conditions, mesh_static, mesh_body_posed, mesh_mask = dist_inputs[0] with tf.GradientTape() as g_tape: # compute losses fake_images, g_loss = g_logistic_non_saturating(real_images, self.generator, self.discriminator, self.g_params['z_dim'], conditions=conditions) mesh_pred = uv2mesh(fake_images) - e_loss = 0.1 * edge_loss(mesh_pred, mesh_static, mesh_mask) - c_loss = 0.0 # collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) - m_loss = uv_mask_loss(fake_images, uv_mask) + e_loss = edge_loss(mesh_pred, mesh_static, mesh_mask) + c_loss = collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) + m_loss = 0.0 # uv_mask_loss(fake_images, uv_mask) # scale loss g_loss = tf.reduce_sum(g_loss) * self.global_batch_scaler @@ -222,7 +222,8 @@ class Trainer(object): return g_loss, e_loss, c_loss, m_loss def g_train_step_reg_extra(self, dist_inputs): - real_images, conditions, mesh_static, mesh_body_posed, mesh_mask, uv_mask = dist_inputs[0] + # real_images, conditions, mesh_static, mesh_body_posed, mesh_mask, uv_mask = dist_inputs[0] + real_images, conditions, mesh_static, mesh_body_posed, mesh_mask = dist_inputs[0] with tf.GradientTape() as g_tape: # compute losses @@ -233,9 +234,9 @@ class Trainer(object): mesh_pred = uv2mesh(fake_images) - e_loss = 0.1 * edge_loss(mesh_pred, mesh_static, mesh_mask) - c_loss = 0.0 # collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) - m_loss = uv_mask_loss(fake_images, uv_mask) + e_loss = edge_loss(mesh_pred, mesh_static, mesh_mask) + c_loss = collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) + m_loss = 0.0 # uv_mask_loss(fake_images, uv_mask) # scale loss pl_penalty = tf.reduce_sum(pl_penalty) * self.global_batch_scaler @@ -570,7 +571,7 @@ def main(): 'train_res': args['train_res'], } - trainer = Trainer(training_parameters, name=f'stylegan2-test-10-{args["train_res"]}x{args["train_res"]}') + trainer = Trainer(training_parameters, name=f'stylegan2-test-13-{args["train_res"]}x{args["train_res"]}') trainer.train(dist_dataset, strategy) return