Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
DragGAN_pytorch
Commits
fba8bde8
Commit
fba8bde8
authored
Oct 29, 2024
by
bailuo
Browse files
update
parents
Pipeline
#1808
failed with stages
Changes
224
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1794 additions
and
0 deletions
+1794
-0
stylegan_human/openpose/src/model.py
stylegan_human/openpose/src/model.py
+219
-0
stylegan_human/openpose/src/util.py
stylegan_human/openpose/src/util.py
+95
-0
stylegan_human/pti/pti_configs/__init__.py
stylegan_human/pti/pti_configs/__init__.py
+0
-0
stylegan_human/pti/pti_configs/global_config.py
stylegan_human/pti/pti_configs/global_config.py
+12
-0
stylegan_human/pti/pti_configs/hyperparameters.py
stylegan_human/pti/pti_configs/hyperparameters.py
+28
-0
stylegan_human/pti/pti_configs/paths_config.py
stylegan_human/pti/pti_configs/paths_config.py
+24
-0
stylegan_human/pti/pti_models/__init__.py
stylegan_human/pti/pti_models/__init__.py
+0
-0
stylegan_human/pti/pti_models/e4e/__init__.py
stylegan_human/pti/pti_models/e4e/__init__.py
+0
-0
stylegan_human/pti/pti_models/e4e/encoders/__init__.py
stylegan_human/pti/pti_models/e4e/encoders/__init__.py
+0
-0
stylegan_human/pti/pti_models/e4e/encoders/helpers.py
stylegan_human/pti/pti_models/e4e/encoders/helpers.py
+140
-0
stylegan_human/pti/pti_models/e4e/encoders/model_irse.py
stylegan_human/pti/pti_models/e4e/encoders/model_irse.py
+84
-0
stylegan_human/pti/pti_models/e4e/encoders/psp_encoders.py
stylegan_human/pti/pti_models/e4e/encoders/psp_encoders.py
+200
-0
stylegan_human/pti/pti_models/e4e/latent_codes_pool.py
stylegan_human/pti/pti_models/e4e/latent_codes_pool.py
+55
-0
stylegan_human/pti/pti_models/e4e/psp.py
stylegan_human/pti/pti_models/e4e/psp.py
+99
-0
stylegan_human/pti/pti_models/e4e/stylegan2/__init__.py
stylegan_human/pti/pti_models/e4e/stylegan2/__init__.py
+0
-0
stylegan_human/pti/pti_models/e4e/stylegan2/model.py
stylegan_human/pti/pti_models/e4e/stylegan2/model.py
+680
-0
stylegan_human/pti/pti_models/e4e/stylegan2/op/__init__.py
stylegan_human/pti/pti_models/e4e/stylegan2/op/__init__.py
+2
-0
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_act.py
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_act.py
+34
-0
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_bias_act.cpp
..._human/pti/pti_models/e4e/stylegan2/op/fused_bias_act.cpp
+22
-0
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_bias_act_kernel.cu
.../pti/pti_models/e4e/stylegan2/op/fused_bias_act_kernel.cu
+100
-0
No files found.
stylegan_human/openpose/src/model.py
0 → 100644
View file @
fba8bde8
import
torch
from
collections
import
OrderedDict
import
torch
import
torch.nn
as
nn
def
make_layers
(
block
,
no_relu_layers
):
layers
=
[]
for
layer_name
,
v
in
block
.
items
():
if
'pool'
in
layer_name
:
layer
=
nn
.
MaxPool2d
(
kernel_size
=
v
[
0
],
stride
=
v
[
1
],
padding
=
v
[
2
])
layers
.
append
((
layer_name
,
layer
))
else
:
conv2d
=
nn
.
Conv2d
(
in_channels
=
v
[
0
],
out_channels
=
v
[
1
],
kernel_size
=
v
[
2
],
stride
=
v
[
3
],
padding
=
v
[
4
])
layers
.
append
((
layer_name
,
conv2d
))
if
layer_name
not
in
no_relu_layers
:
layers
.
append
((
'relu_'
+
layer_name
,
nn
.
ReLU
(
inplace
=
True
)))
return
nn
.
Sequential
(
OrderedDict
(
layers
))
class
bodypose_model
(
nn
.
Module
):
def
__init__
(
self
):
super
(
bodypose_model
,
self
).
__init__
()
# these layers have no relu layer
no_relu_layers
=
[
'conv5_5_CPM_L1'
,
'conv5_5_CPM_L2'
,
'Mconv7_stage2_L1'
,
\
'Mconv7_stage2_L2'
,
'Mconv7_stage3_L1'
,
'Mconv7_stage3_L2'
,
\
'Mconv7_stage4_L1'
,
'Mconv7_stage4_L2'
,
'Mconv7_stage5_L1'
,
\
'Mconv7_stage5_L2'
,
'Mconv7_stage6_L1'
,
'Mconv7_stage6_L1'
]
blocks
=
{}
block0
=
OrderedDict
([
(
'conv1_1'
,
[
3
,
64
,
3
,
1
,
1
]),
(
'conv1_2'
,
[
64
,
64
,
3
,
1
,
1
]),
(
'pool1_stage1'
,
[
2
,
2
,
0
]),
(
'conv2_1'
,
[
64
,
128
,
3
,
1
,
1
]),
(
'conv2_2'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'pool2_stage1'
,
[
2
,
2
,
0
]),
(
'conv3_1'
,
[
128
,
256
,
3
,
1
,
1
]),
(
'conv3_2'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'conv3_3'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'conv3_4'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'pool3_stage1'
,
[
2
,
2
,
0
]),
(
'conv4_1'
,
[
256
,
512
,
3
,
1
,
1
]),
(
'conv4_2'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv4_3_CPM'
,
[
512
,
256
,
3
,
1
,
1
]),
(
'conv4_4_CPM'
,
[
256
,
128
,
3
,
1
,
1
])
])
# Stage 1
block1_1
=
OrderedDict
([
(
'conv5_1_CPM_L1'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_2_CPM_L1'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_3_CPM_L1'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_4_CPM_L1'
,
[
128
,
512
,
1
,
1
,
0
]),
(
'conv5_5_CPM_L1'
,
[
512
,
38
,
1
,
1
,
0
])
])
block1_2
=
OrderedDict
([
(
'conv5_1_CPM_L2'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_2_CPM_L2'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_3_CPM_L2'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'conv5_4_CPM_L2'
,
[
128
,
512
,
1
,
1
,
0
]),
(
'conv5_5_CPM_L2'
,
[
512
,
19
,
1
,
1
,
0
])
])
blocks
[
'block1_1'
]
=
block1_1
blocks
[
'block1_2'
]
=
block1_2
self
.
model0
=
make_layers
(
block0
,
no_relu_layers
)
# Stages 2 - 6
for
i
in
range
(
2
,
7
):
blocks
[
'block%d_1'
%
i
]
=
OrderedDict
([
(
'Mconv1_stage%d_L1'
%
i
,
[
185
,
128
,
7
,
1
,
3
]),
(
'Mconv2_stage%d_L1'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv3_stage%d_L1'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv4_stage%d_L1'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv5_stage%d_L1'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv6_stage%d_L1'
%
i
,
[
128
,
128
,
1
,
1
,
0
]),
(
'Mconv7_stage%d_L1'
%
i
,
[
128
,
38
,
1
,
1
,
0
])
])
blocks
[
'block%d_2'
%
i
]
=
OrderedDict
([
(
'Mconv1_stage%d_L2'
%
i
,
[
185
,
128
,
7
,
1
,
3
]),
(
'Mconv2_stage%d_L2'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv3_stage%d_L2'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv4_stage%d_L2'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv5_stage%d_L2'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv6_stage%d_L2'
%
i
,
[
128
,
128
,
1
,
1
,
0
]),
(
'Mconv7_stage%d_L2'
%
i
,
[
128
,
19
,
1
,
1
,
0
])
])
for
k
in
blocks
.
keys
():
blocks
[
k
]
=
make_layers
(
blocks
[
k
],
no_relu_layers
)
self
.
model1_1
=
blocks
[
'block1_1'
]
self
.
model2_1
=
blocks
[
'block2_1'
]
self
.
model3_1
=
blocks
[
'block3_1'
]
self
.
model4_1
=
blocks
[
'block4_1'
]
self
.
model5_1
=
blocks
[
'block5_1'
]
self
.
model6_1
=
blocks
[
'block6_1'
]
self
.
model1_2
=
blocks
[
'block1_2'
]
self
.
model2_2
=
blocks
[
'block2_2'
]
self
.
model3_2
=
blocks
[
'block3_2'
]
self
.
model4_2
=
blocks
[
'block4_2'
]
self
.
model5_2
=
blocks
[
'block5_2'
]
self
.
model6_2
=
blocks
[
'block6_2'
]
def
forward
(
self
,
x
):
out1
=
self
.
model0
(
x
)
out1_1
=
self
.
model1_1
(
out1
)
out1_2
=
self
.
model1_2
(
out1
)
out2
=
torch
.
cat
([
out1_1
,
out1_2
,
out1
],
1
)
out2_1
=
self
.
model2_1
(
out2
)
out2_2
=
self
.
model2_2
(
out2
)
out3
=
torch
.
cat
([
out2_1
,
out2_2
,
out1
],
1
)
out3_1
=
self
.
model3_1
(
out3
)
out3_2
=
self
.
model3_2
(
out3
)
out4
=
torch
.
cat
([
out3_1
,
out3_2
,
out1
],
1
)
out4_1
=
self
.
model4_1
(
out4
)
out4_2
=
self
.
model4_2
(
out4
)
out5
=
torch
.
cat
([
out4_1
,
out4_2
,
out1
],
1
)
out5_1
=
self
.
model5_1
(
out5
)
out5_2
=
self
.
model5_2
(
out5
)
out6
=
torch
.
cat
([
out5_1
,
out5_2
,
out1
],
1
)
out6_1
=
self
.
model6_1
(
out6
)
out6_2
=
self
.
model6_2
(
out6
)
return
out6_1
,
out6_2
class
handpose_model
(
nn
.
Module
):
def
__init__
(
self
):
super
(
handpose_model
,
self
).
__init__
()
# these layers have no relu layer
no_relu_layers
=
[
'conv6_2_CPM'
,
'Mconv7_stage2'
,
'Mconv7_stage3'
,
\
'Mconv7_stage4'
,
'Mconv7_stage5'
,
'Mconv7_stage6'
]
# stage 1
block1_0
=
OrderedDict
([
(
'conv1_1'
,
[
3
,
64
,
3
,
1
,
1
]),
(
'conv1_2'
,
[
64
,
64
,
3
,
1
,
1
]),
(
'pool1_stage1'
,
[
2
,
2
,
0
]),
(
'conv2_1'
,
[
64
,
128
,
3
,
1
,
1
]),
(
'conv2_2'
,
[
128
,
128
,
3
,
1
,
1
]),
(
'pool2_stage1'
,
[
2
,
2
,
0
]),
(
'conv3_1'
,
[
128
,
256
,
3
,
1
,
1
]),
(
'conv3_2'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'conv3_3'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'conv3_4'
,
[
256
,
256
,
3
,
1
,
1
]),
(
'pool3_stage1'
,
[
2
,
2
,
0
]),
(
'conv4_1'
,
[
256
,
512
,
3
,
1
,
1
]),
(
'conv4_2'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv4_3'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv4_4'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv5_1'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv5_2'
,
[
512
,
512
,
3
,
1
,
1
]),
(
'conv5_3_CPM'
,
[
512
,
128
,
3
,
1
,
1
])
])
block1_1
=
OrderedDict
([
(
'conv6_1_CPM'
,
[
128
,
512
,
1
,
1
,
0
]),
(
'conv6_2_CPM'
,
[
512
,
22
,
1
,
1
,
0
])
])
blocks
=
{}
blocks
[
'block1_0'
]
=
block1_0
blocks
[
'block1_1'
]
=
block1_1
# stage 2-6
for
i
in
range
(
2
,
7
):
blocks
[
'block%d'
%
i
]
=
OrderedDict
([
(
'Mconv1_stage%d'
%
i
,
[
150
,
128
,
7
,
1
,
3
]),
(
'Mconv2_stage%d'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv3_stage%d'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv4_stage%d'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv5_stage%d'
%
i
,
[
128
,
128
,
7
,
1
,
3
]),
(
'Mconv6_stage%d'
%
i
,
[
128
,
128
,
1
,
1
,
0
]),
(
'Mconv7_stage%d'
%
i
,
[
128
,
22
,
1
,
1
,
0
])
])
for
k
in
blocks
.
keys
():
blocks
[
k
]
=
make_layers
(
blocks
[
k
],
no_relu_layers
)
self
.
model1_0
=
blocks
[
'block1_0'
]
self
.
model1_1
=
blocks
[
'block1_1'
]
self
.
model2
=
blocks
[
'block2'
]
self
.
model3
=
blocks
[
'block3'
]
self
.
model4
=
blocks
[
'block4'
]
self
.
model5
=
blocks
[
'block5'
]
self
.
model6
=
blocks
[
'block6'
]
def
forward
(
self
,
x
):
out1_0
=
self
.
model1_0
(
x
)
out1_1
=
self
.
model1_1
(
out1_0
)
concat_stage2
=
torch
.
cat
([
out1_1
,
out1_0
],
1
)
out_stage2
=
self
.
model2
(
concat_stage2
)
concat_stage3
=
torch
.
cat
([
out_stage2
,
out1_0
],
1
)
out_stage3
=
self
.
model3
(
concat_stage3
)
concat_stage4
=
torch
.
cat
([
out_stage3
,
out1_0
],
1
)
out_stage4
=
self
.
model4
(
concat_stage4
)
concat_stage5
=
torch
.
cat
([
out_stage4
,
out1_0
],
1
)
out_stage5
=
self
.
model5
(
concat_stage5
)
concat_stage6
=
torch
.
cat
([
out_stage5
,
out1_0
],
1
)
out_stage6
=
self
.
model6
(
concat_stage6
)
return
out_stage6
stylegan_human/openpose/src/util.py
0 → 100644
View file @
fba8bde8
import
numpy
as
np
import
math
import
cv2
import
matplotlib
from
matplotlib.backends.backend_agg
import
FigureCanvasAgg
as
FigureCanvas
from
matplotlib.figure
import
Figure
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
cv2
def
padRightDownCorner
(
img
,
stride
,
padValue
):
h
=
img
.
shape
[
0
]
w
=
img
.
shape
[
1
]
pad
=
4
*
[
None
]
pad
[
0
]
=
0
# up
pad
[
1
]
=
0
# left
pad
[
2
]
=
0
if
(
h
%
stride
==
0
)
else
stride
-
(
h
%
stride
)
# down
pad
[
3
]
=
0
if
(
w
%
stride
==
0
)
else
stride
-
(
w
%
stride
)
# right
img_padded
=
img
pad_up
=
np
.
tile
(
img_padded
[
0
:
1
,
:,
:]
*
0
+
padValue
,
(
pad
[
0
],
1
,
1
))
img_padded
=
np
.
concatenate
((
pad_up
,
img_padded
),
axis
=
0
)
pad_left
=
np
.
tile
(
img_padded
[:,
0
:
1
,
:]
*
0
+
padValue
,
(
1
,
pad
[
1
],
1
))
img_padded
=
np
.
concatenate
((
pad_left
,
img_padded
),
axis
=
1
)
pad_down
=
np
.
tile
(
img_padded
[
-
2
:
-
1
,
:,
:]
*
0
+
padValue
,
(
pad
[
2
],
1
,
1
))
img_padded
=
np
.
concatenate
((
img_padded
,
pad_down
),
axis
=
0
)
pad_right
=
np
.
tile
(
img_padded
[:,
-
2
:
-
1
,
:]
*
0
+
padValue
,
(
1
,
pad
[
3
],
1
))
img_padded
=
np
.
concatenate
((
img_padded
,
pad_right
),
axis
=
1
)
return
img_padded
,
pad
# transfer caffe model to pytorch which will match the layer name
def
transfer
(
model
,
model_weights
):
transfered_model_weights
=
{}
for
weights_name
in
model
.
state_dict
().
keys
():
transfered_model_weights
[
weights_name
]
=
model_weights
[
'.'
.
join
(
weights_name
.
split
(
'.'
)[
1
:])]
return
transfered_model_weights
# draw the body keypoint and lims
def
draw_bodypose
(
canvas
,
candidate
,
subset
,
show_number
=
False
):
stickwidth
=
4
limbSeq
=
[[
2
,
3
],
[
2
,
6
],
[
3
,
4
],
[
4
,
5
],
[
6
,
7
],
[
7
,
8
],
[
2
,
9
],
[
9
,
10
],
\
[
10
,
11
],
[
2
,
12
],
[
12
,
13
],
[
13
,
14
],
[
2
,
1
],
[
1
,
15
],
[
15
,
17
],
\
[
1
,
16
],
[
16
,
18
],
[
3
,
17
],
[
6
,
18
]]
colors
=
[[
255
,
0
,
0
],
[
255
,
85
,
0
],
[
255
,
170
,
0
],
[
255
,
255
,
0
],
[
170
,
255
,
0
],
[
85
,
255
,
0
],
[
0
,
255
,
0
],
\
[
0
,
255
,
85
],
[
0
,
255
,
170
],
[
0
,
255
,
255
],
[
0
,
170
,
255
],
[
0
,
85
,
255
],
[
0
,
0
,
255
],
[
85
,
0
,
255
],
\
[
170
,
0
,
255
],
[
255
,
0
,
255
],
[
255
,
0
,
170
],
[
255
,
0
,
85
]]
for
i
in
range
(
18
):
for
n
in
range
(
len
(
subset
)):
index
=
int
(
subset
[
n
][
i
])
if
index
==
-
1
:
continue
x
,
y
=
candidate
[
index
][
0
:
2
]
cv2
.
circle
(
canvas
,
(
int
(
x
),
int
(
y
)),
4
,
colors
[
i
],
thickness
=-
1
)
if
show_number
:
cv2
.
putText
(
canvas
,
f
'
{
index
}
'
,
(
int
(
x
),
int
(
y
)),
cv2
.
FONT_HERSHEY_SIMPLEX
,
0.6
,
(
255
,
255
,
0
),
1
,
cv2
.
LINE_AA
)
## calc and print average
for
i
in
range
(
17
):
for
n
in
range
(
len
(
subset
)):
index
=
subset
[
n
][
np
.
array
(
limbSeq
[
i
])
-
1
]
if
-
1
in
index
:
continue
cur_canvas
=
canvas
.
copy
()
Y
=
candidate
[
index
.
astype
(
int
),
0
]
X
=
candidate
[
index
.
astype
(
int
),
1
]
mX
=
np
.
mean
(
X
)
mY
=
np
.
mean
(
Y
)
length
=
((
X
[
0
]
-
X
[
1
])
**
2
+
(
Y
[
0
]
-
Y
[
1
])
**
2
)
**
0.5
angle
=
math
.
degrees
(
math
.
atan2
(
X
[
0
]
-
X
[
1
],
Y
[
0
]
-
Y
[
1
]))
polygon
=
cv2
.
ellipse2Poly
((
int
(
mY
),
int
(
mX
)),
(
int
(
length
/
2
),
stickwidth
),
int
(
angle
),
0
,
360
,
1
)
cv2
.
fillConvexPoly
(
cur_canvas
,
polygon
,
colors
[
i
])
canvas
=
cv2
.
addWeighted
(
canvas
,
0.4
,
cur_canvas
,
0.6
,
0
)
return
canvas
# get max index of 2d array
def
npmax
(
array
):
arrayindex
=
array
.
argmax
(
1
)
arrayvalue
=
array
.
max
(
1
)
i
=
arrayvalue
.
argmax
()
j
=
arrayindex
[
i
]
return
i
,
j
# get max index of 2d array
def
npmax_with_score
(
array
):
arrayindex
=
array
.
argmax
(
1
)
arrayvalue
=
array
.
max
(
1
)
i
=
arrayvalue
.
argmax
()
j
=
arrayindex
[
i
]
score
=
array
[
i
][
j
]
return
i
,
j
,
score
stylegan_human/pti/pti_configs/__init__.py
0 → 100644
View file @
fba8bde8
stylegan_human/pti/pti_configs/global_config.py
0 → 100644
View file @
fba8bde8
## Device
cuda_visible_devices
=
'0'
device
=
'cuda:0'
## Logs
training_step
=
1
image_rec_result_log_snapshot
=
100
pivotal_training_steps
=
0
model_snapshot_interval
=
400
## Run name to be updated during PTI
run_name
=
'exp'
stylegan_human/pti/pti_configs/hyperparameters.py
0 → 100644
View file @
fba8bde8
## Architechture
lpips_type
=
'alex'
first_inv_type
=
'w+'
#'w+'
optim_type
=
'adam'
## Locality regularization
latent_ball_num_of_samples
=
1
locality_regularization_interval
=
1
use_locality_regularization
=
False
regulizer_l2_lambda
=
0.1
regulizer_lpips_lambda
=
0.1
regulizer_alpha
=
30
## Loss
pt_l2_lambda
=
1
pt_lpips_lambda
=
1
## Steps
LPIPS_value_threshold
=
0.04
max_pti_steps
=
350
first_inv_steps
=
450
max_images_to_invert
=
30
## Optimization
pti_learning_rate
=
5e-4
first_inv_lr
=
8e-3
train_batch_size
=
1
use_last_w_pivots
=
False
stylegan_human/pti/pti_configs/paths_config.py
0 → 100644
View file @
fba8bde8
import
os
## Pretrained models paths
e4e
=
'./pti/e4e_w+.pt'
stylegan2_ada_shhq
=
'./pretrained_models/stylegan_human_v2_1024.pkl'
ir_se50
=
''
#'./model_ir_se50.pth'
## Dirs for output files
checkpoints_dir
=
'./outputs/pti/checkpoints/'
embedding_base_dir
=
'./outputs/pti/embeddings'
experiments_output_dir
=
'./outputs/pti/'
## Input info
### Input dir, where the images reside
input_data_path
=
'aligned_image/'
### Inversion identifier, used to keeping track of the inversion results. Both the latent code and the generator
input_data_id
=
'test'
## Keywords
pti_results_keyword
=
'PTI'
e4e_results_keyword
=
'e4e'
sg2_results_keyword
=
'SG2'
sg2_plus_results_keyword
=
'SG2_Plus'
multi_id_model_type
=
'multi_id'
stylegan_human/pti/pti_models/__init__.py
0 → 100644
View file @
fba8bde8
stylegan_human/pti/pti_models/e4e/__init__.py
0 → 100644
View file @
fba8bde8
stylegan_human/pti/pti_models/e4e/encoders/__init__.py
0 → 100644
View file @
fba8bde8
stylegan_human/pti/pti_models/e4e/encoders/helpers.py
0 → 100644
View file @
fba8bde8
from
collections
import
namedtuple
import
torch
import
torch.nn.functional
as
F
from
torch.nn
import
Conv2d
,
BatchNorm2d
,
PReLU
,
ReLU
,
Sigmoid
,
MaxPool2d
,
AdaptiveAvgPool2d
,
Sequential
,
Module
"""
ArcFace implementation from [TreB1eN](https://github.com/TreB1eN/InsightFace_Pytorch)
"""
class
Flatten
(
Module
):
def
forward
(
self
,
input
):
return
input
.
view
(
input
.
size
(
0
),
-
1
)
def
l2_norm
(
input
,
axis
=
1
):
norm
=
torch
.
norm
(
input
,
2
,
axis
,
True
)
output
=
torch
.
div
(
input
,
norm
)
return
output
class
Bottleneck
(
namedtuple
(
'Block'
,
[
'in_channel'
,
'depth'
,
'stride'
])):
""" A named tuple describing a ResNet block. """
def
get_block
(
in_channel
,
depth
,
num_units
,
stride
=
2
):
return
[
Bottleneck
(
in_channel
,
depth
,
stride
)]
+
[
Bottleneck
(
depth
,
depth
,
1
)
for
i
in
range
(
num_units
-
1
)]
def
get_blocks
(
num_layers
):
if
num_layers
==
50
:
blocks
=
[
get_block
(
in_channel
=
64
,
depth
=
64
,
num_units
=
3
),
get_block
(
in_channel
=
64
,
depth
=
128
,
num_units
=
4
),
get_block
(
in_channel
=
128
,
depth
=
256
,
num_units
=
14
),
get_block
(
in_channel
=
256
,
depth
=
512
,
num_units
=
3
)
]
elif
num_layers
==
100
:
blocks
=
[
get_block
(
in_channel
=
64
,
depth
=
64
,
num_units
=
3
),
get_block
(
in_channel
=
64
,
depth
=
128
,
num_units
=
13
),
get_block
(
in_channel
=
128
,
depth
=
256
,
num_units
=
30
),
get_block
(
in_channel
=
256
,
depth
=
512
,
num_units
=
3
)
]
elif
num_layers
==
152
:
blocks
=
[
get_block
(
in_channel
=
64
,
depth
=
64
,
num_units
=
3
),
get_block
(
in_channel
=
64
,
depth
=
128
,
num_units
=
8
),
get_block
(
in_channel
=
128
,
depth
=
256
,
num_units
=
36
),
get_block
(
in_channel
=
256
,
depth
=
512
,
num_units
=
3
)
]
else
:
raise
ValueError
(
"Invalid number of layers: {}. Must be one of [50, 100, 152]"
.
format
(
num_layers
))
return
blocks
class
SEModule
(
Module
):
def
__init__
(
self
,
channels
,
reduction
):
super
(
SEModule
,
self
).
__init__
()
self
.
avg_pool
=
AdaptiveAvgPool2d
(
1
)
self
.
fc1
=
Conv2d
(
channels
,
channels
//
reduction
,
kernel_size
=
1
,
padding
=
0
,
bias
=
False
)
self
.
relu
=
ReLU
(
inplace
=
True
)
self
.
fc2
=
Conv2d
(
channels
//
reduction
,
channels
,
kernel_size
=
1
,
padding
=
0
,
bias
=
False
)
self
.
sigmoid
=
Sigmoid
()
def
forward
(
self
,
x
):
module_input
=
x
x
=
self
.
avg_pool
(
x
)
x
=
self
.
fc1
(
x
)
x
=
self
.
relu
(
x
)
x
=
self
.
fc2
(
x
)
x
=
self
.
sigmoid
(
x
)
return
module_input
*
x
class
bottleneck_IR
(
Module
):
def
__init__
(
self
,
in_channel
,
depth
,
stride
):
super
(
bottleneck_IR
,
self
).
__init__
()
if
in_channel
==
depth
:
self
.
shortcut_layer
=
MaxPool2d
(
1
,
stride
)
else
:
self
.
shortcut_layer
=
Sequential
(
Conv2d
(
in_channel
,
depth
,
(
1
,
1
),
stride
,
bias
=
False
),
BatchNorm2d
(
depth
)
)
self
.
res_layer
=
Sequential
(
BatchNorm2d
(
in_channel
),
Conv2d
(
in_channel
,
depth
,
(
3
,
3
),
(
1
,
1
),
1
,
bias
=
False
),
PReLU
(
depth
),
Conv2d
(
depth
,
depth
,
(
3
,
3
),
stride
,
1
,
bias
=
False
),
BatchNorm2d
(
depth
)
)
def
forward
(
self
,
x
):
shortcut
=
self
.
shortcut_layer
(
x
)
res
=
self
.
res_layer
(
x
)
return
res
+
shortcut
class
bottleneck_IR_SE
(
Module
):
def
__init__
(
self
,
in_channel
,
depth
,
stride
):
super
(
bottleneck_IR_SE
,
self
).
__init__
()
if
in_channel
==
depth
:
self
.
shortcut_layer
=
MaxPool2d
(
1
,
stride
)
else
:
self
.
shortcut_layer
=
Sequential
(
Conv2d
(
in_channel
,
depth
,
(
1
,
1
),
stride
,
bias
=
False
),
BatchNorm2d
(
depth
)
)
self
.
res_layer
=
Sequential
(
BatchNorm2d
(
in_channel
),
Conv2d
(
in_channel
,
depth
,
(
3
,
3
),
(
1
,
1
),
1
,
bias
=
False
),
PReLU
(
depth
),
Conv2d
(
depth
,
depth
,
(
3
,
3
),
stride
,
1
,
bias
=
False
),
BatchNorm2d
(
depth
),
SEModule
(
depth
,
16
)
)
def
forward
(
self
,
x
):
shortcut
=
self
.
shortcut_layer
(
x
)
res
=
self
.
res_layer
(
x
)
return
res
+
shortcut
def
_upsample_add
(
x
,
y
):
"""Upsample and add two feature maps.
Args:
x: (Variable) top feature map to be upsampled.
y: (Variable) lateral feature map.
Returns:
(Variable) added feature map.
Note in PyTorch, when input size is odd, the upsampled feature map
with `F.upsample(..., scale_factor=2, mode='nearest')`
maybe not equal to the lateral feature map size.
e.g.
original input size: [N,_,15,15] ->
conv2d feature map size: [N,_,8,8] ->
upsampled feature map size: [N,_,16,16]
So we choose bilinear upsample which supports arbitrary output sizes.
"""
_
,
_
,
H
,
W
=
y
.
size
()
return
F
.
interpolate
(
x
,
size
=
(
H
,
W
),
mode
=
'bilinear'
,
align_corners
=
True
)
+
y
stylegan_human/pti/pti_models/e4e/encoders/model_irse.py
0 → 100644
View file @
fba8bde8
from
torch.nn
import
Linear
,
Conv2d
,
BatchNorm1d
,
BatchNorm2d
,
PReLU
,
Dropout
,
Sequential
,
Module
from
encoder4editing.models.encoders.helpers
import
get_blocks
,
Flatten
,
bottleneck_IR
,
bottleneck_IR_SE
,
l2_norm
"""
Modified Backbone implementation from [TreB1eN](https://github.com/TreB1eN/InsightFace_Pytorch)
"""
class
Backbone
(
Module
):
def
__init__
(
self
,
input_size
,
num_layers
,
mode
=
'ir'
,
drop_ratio
=
0.4
,
affine
=
True
):
super
(
Backbone
,
self
).
__init__
()
assert
input_size
in
[
112
,
224
],
"input_size should be 112 or 224"
assert
num_layers
in
[
50
,
100
,
152
],
"num_layers should be 50, 100 or 152"
assert
mode
in
[
'ir'
,
'ir_se'
],
"mode should be ir or ir_se"
blocks
=
get_blocks
(
num_layers
)
if
mode
==
'ir'
:
unit_module
=
bottleneck_IR
elif
mode
==
'ir_se'
:
unit_module
=
bottleneck_IR_SE
self
.
input_layer
=
Sequential
(
Conv2d
(
3
,
64
,
(
3
,
3
),
1
,
1
,
bias
=
False
),
BatchNorm2d
(
64
),
PReLU
(
64
))
if
input_size
==
112
:
self
.
output_layer
=
Sequential
(
BatchNorm2d
(
512
),
Dropout
(
drop_ratio
),
Flatten
(),
Linear
(
512
*
7
*
7
,
512
),
BatchNorm1d
(
512
,
affine
=
affine
))
else
:
self
.
output_layer
=
Sequential
(
BatchNorm2d
(
512
),
Dropout
(
drop_ratio
),
Flatten
(),
Linear
(
512
*
14
*
14
,
512
),
BatchNorm1d
(
512
,
affine
=
affine
))
modules
=
[]
for
block
in
blocks
:
for
bottleneck
in
block
:
modules
.
append
(
unit_module
(
bottleneck
.
in_channel
,
bottleneck
.
depth
,
bottleneck
.
stride
))
self
.
body
=
Sequential
(
*
modules
)
def
forward
(
self
,
x
):
x
=
self
.
input_layer
(
x
)
x
=
self
.
body
(
x
)
x
=
self
.
output_layer
(
x
)
return
l2_norm
(
x
)
def
IR_50
(
input_size
):
"""Constructs a ir-50 model."""
model
=
Backbone
(
input_size
,
num_layers
=
50
,
mode
=
'ir'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
def
IR_101
(
input_size
):
"""Constructs a ir-101 model."""
model
=
Backbone
(
input_size
,
num_layers
=
100
,
mode
=
'ir'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
def
IR_152
(
input_size
):
"""Constructs a ir-152 model."""
model
=
Backbone
(
input_size
,
num_layers
=
152
,
mode
=
'ir'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
def
IR_SE_50
(
input_size
):
"""Constructs a ir_se-50 model."""
model
=
Backbone
(
input_size
,
num_layers
=
50
,
mode
=
'ir_se'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
def
IR_SE_101
(
input_size
):
"""Constructs a ir_se-101 model."""
model
=
Backbone
(
input_size
,
num_layers
=
100
,
mode
=
'ir_se'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
def
IR_SE_152
(
input_size
):
"""Constructs a ir_se-152 model."""
model
=
Backbone
(
input_size
,
num_layers
=
152
,
mode
=
'ir_se'
,
drop_ratio
=
0.4
,
affine
=
False
)
return
model
stylegan_human/pti/pti_models/e4e/encoders/psp_encoders.py
0 → 100644
View file @
fba8bde8
from
enum
import
Enum
import
math
import
numpy
as
np
import
torch
from
torch
import
nn
from
torch.nn
import
Conv2d
,
BatchNorm2d
,
PReLU
,
Sequential
,
Module
from
pti.pti_models.e4e.encoders.helpers
import
get_blocks
,
bottleneck_IR
,
bottleneck_IR_SE
,
_upsample_add
from
pti.pti_models.e4e.stylegan2.model
import
EqualLinear
class
ProgressiveStage
(
Enum
):
WTraining
=
0
Delta1Training
=
1
Delta2Training
=
2
Delta3Training
=
3
Delta4Training
=
4
Delta5Training
=
5
Delta6Training
=
6
Delta7Training
=
7
Delta8Training
=
8
Delta9Training
=
9
Delta10Training
=
10
Delta11Training
=
11
Delta12Training
=
12
Delta13Training
=
13
Delta14Training
=
14
Delta15Training
=
15
Delta16Training
=
16
Delta17Training
=
17
Inference
=
18
class
GradualStyleBlock
(
Module
):
def
__init__
(
self
,
in_c
,
out_c
,
spatial
):
super
(
GradualStyleBlock
,
self
).
__init__
()
self
.
out_c
=
out_c
self
.
spatial
=
spatial
num_pools
=
int
(
np
.
log2
(
spatial
))
modules
=
[]
modules
+=
[
Conv2d
(
in_c
,
out_c
,
kernel_size
=
3
,
stride
=
2
,
padding
=
1
),
nn
.
LeakyReLU
()]
for
i
in
range
(
num_pools
-
1
):
modules
+=
[
Conv2d
(
out_c
,
out_c
,
kernel_size
=
3
,
stride
=
2
,
padding
=
1
),
nn
.
LeakyReLU
()
]
self
.
convs
=
nn
.
Sequential
(
*
modules
)
self
.
linear
=
EqualLinear
(
out_c
,
out_c
,
lr_mul
=
1
)
def
forward
(
self
,
x
):
x
=
self
.
convs
(
x
)
x
=
x
.
view
(
-
1
,
self
.
out_c
)
x
=
self
.
linear
(
x
)
return
x
class
GradualStyleEncoder
(
Module
):
def
__init__
(
self
,
num_layers
,
mode
=
'ir'
,
opts
=
None
):
super
(
GradualStyleEncoder
,
self
).
__init__
()
assert
num_layers
in
[
50
,
100
,
152
],
'num_layers should be 50,100, or 152'
assert
mode
in
[
'ir'
,
'ir_se'
],
'mode should be ir or ir_se'
blocks
=
get_blocks
(
num_layers
)
if
mode
==
'ir'
:
unit_module
=
bottleneck_IR
elif
mode
==
'ir_se'
:
unit_module
=
bottleneck_IR_SE
self
.
input_layer
=
Sequential
(
Conv2d
(
3
,
64
,
(
3
,
3
),
1
,
1
,
bias
=
False
),
BatchNorm2d
(
64
),
PReLU
(
64
))
modules
=
[]
for
block
in
blocks
:
for
bottleneck
in
block
:
modules
.
append
(
unit_module
(
bottleneck
.
in_channel
,
bottleneck
.
depth
,
bottleneck
.
stride
))
self
.
body
=
Sequential
(
*
modules
)
self
.
styles
=
nn
.
ModuleList
()
log_size
=
int
(
math
.
log
(
opts
.
stylegan_size
,
2
))
self
.
style_count
=
2
*
log_size
-
2
self
.
coarse_ind
=
3
self
.
middle_ind
=
7
for
i
in
range
(
self
.
style_count
):
if
i
<
self
.
coarse_ind
:
style
=
GradualStyleBlock
(
512
,
512
,
16
)
elif
i
<
self
.
middle_ind
:
style
=
GradualStyleBlock
(
512
,
512
,
32
)
else
:
style
=
GradualStyleBlock
(
512
,
512
,
64
)
self
.
styles
.
append
(
style
)
self
.
latlayer1
=
nn
.
Conv2d
(
256
,
512
,
kernel_size
=
1
,
stride
=
1
,
padding
=
0
)
self
.
latlayer2
=
nn
.
Conv2d
(
128
,
512
,
kernel_size
=
1
,
stride
=
1
,
padding
=
0
)
def
forward
(
self
,
x
):
x
=
self
.
input_layer
(
x
)
latents
=
[]
modulelist
=
list
(
self
.
body
.
_modules
.
values
())
for
i
,
l
in
enumerate
(
modulelist
):
x
=
l
(
x
)
if
i
==
6
:
c1
=
x
elif
i
==
20
:
c2
=
x
elif
i
==
23
:
c3
=
x
for
j
in
range
(
self
.
coarse_ind
):
latents
.
append
(
self
.
styles
[
j
](
c3
))
p2
=
_upsample_add
(
c3
,
self
.
latlayer1
(
c2
))
for
j
in
range
(
self
.
coarse_ind
,
self
.
middle_ind
):
latents
.
append
(
self
.
styles
[
j
](
p2
))
p1
=
_upsample_add
(
p2
,
self
.
latlayer2
(
c1
))
for
j
in
range
(
self
.
middle_ind
,
self
.
style_count
):
latents
.
append
(
self
.
styles
[
j
](
p1
))
out
=
torch
.
stack
(
latents
,
dim
=
1
)
return
out
class
Encoder4Editing
(
Module
):
def
__init__
(
self
,
num_layers
,
mode
=
'ir'
,
opts
=
None
):
super
(
Encoder4Editing
,
self
).
__init__
()
assert
num_layers
in
[
50
,
100
,
152
],
'num_layers should be 50,100, or 152'
assert
mode
in
[
'ir'
,
'ir_se'
],
'mode should be ir or ir_se'
blocks
=
get_blocks
(
num_layers
)
if
mode
==
'ir'
:
unit_module
=
bottleneck_IR
elif
mode
==
'ir_se'
:
unit_module
=
bottleneck_IR_SE
self
.
input_layer
=
Sequential
(
Conv2d
(
3
,
64
,
(
3
,
3
),
1
,
1
,
bias
=
False
),
BatchNorm2d
(
64
),
PReLU
(
64
))
modules
=
[]
for
block
in
blocks
:
for
bottleneck
in
block
:
modules
.
append
(
unit_module
(
bottleneck
.
in_channel
,
bottleneck
.
depth
,
bottleneck
.
stride
))
self
.
body
=
Sequential
(
*
modules
)
self
.
styles
=
nn
.
ModuleList
()
log_size
=
int
(
math
.
log
(
opts
.
stylegan_size
,
2
))
self
.
style_count
=
2
*
log_size
-
2
self
.
coarse_ind
=
3
self
.
middle_ind
=
7
for
i
in
range
(
self
.
style_count
):
if
i
<
self
.
coarse_ind
:
style
=
GradualStyleBlock
(
512
,
512
,
16
)
elif
i
<
self
.
middle_ind
:
style
=
GradualStyleBlock
(
512
,
512
,
32
)
else
:
style
=
GradualStyleBlock
(
512
,
512
,
64
)
self
.
styles
.
append
(
style
)
self
.
latlayer1
=
nn
.
Conv2d
(
256
,
512
,
kernel_size
=
1
,
stride
=
1
,
padding
=
0
)
self
.
latlayer2
=
nn
.
Conv2d
(
128
,
512
,
kernel_size
=
1
,
stride
=
1
,
padding
=
0
)
self
.
progressive_stage
=
ProgressiveStage
.
Inference
def
get_deltas_starting_dimensions
(
self
):
''' Get a list of the initial dimension of every delta from which it is applied '''
return
list
(
range
(
self
.
style_count
))
# Each dimension has a delta applied to it
def
set_progressive_stage
(
self
,
new_stage
:
ProgressiveStage
):
self
.
progressive_stage
=
new_stage
print
(
'Changed progressive stage to: '
,
new_stage
)
def
forward
(
self
,
x
):
x
=
self
.
input_layer
(
x
)
modulelist
=
list
(
self
.
body
.
_modules
.
values
())
for
i
,
l
in
enumerate
(
modulelist
):
x
=
l
(
x
)
if
i
==
6
:
c1
=
x
elif
i
==
20
:
c2
=
x
elif
i
==
23
:
c3
=
x
# Infer main W and duplicate it
w0
=
self
.
styles
[
0
](
c3
)
w
=
w0
.
repeat
(
self
.
style_count
,
1
,
1
).
permute
(
1
,
0
,
2
)
stage
=
self
.
progressive_stage
.
value
features
=
c3
for
i
in
range
(
1
,
min
(
stage
+
1
,
self
.
style_count
)):
# Infer additional deltas
if
i
==
self
.
coarse_ind
:
p2
=
_upsample_add
(
c3
,
self
.
latlayer1
(
c2
))
# FPN's middle features
features
=
p2
elif
i
==
self
.
middle_ind
:
p1
=
_upsample_add
(
p2
,
self
.
latlayer2
(
c1
))
# FPN's fine features
features
=
p1
delta_i
=
self
.
styles
[
i
](
features
)
w
[:,
i
]
+=
delta_i
return
w
stylegan_human/pti/pti_models/e4e/latent_codes_pool.py
0 → 100644
View file @
fba8bde8
import
random
import
torch
class
LatentCodesPool
:
"""This class implements latent codes buffer that stores previously generated w latent codes.
This buffer enables us to update discriminators using a history of generated w's
rather than the ones produced by the latest encoder.
"""
def
__init__
(
self
,
pool_size
):
"""Initialize the ImagePool class
Parameters:
pool_size (int) -- the size of image buffer, if pool_size=0, no buffer will be created
"""
self
.
pool_size
=
pool_size
if
self
.
pool_size
>
0
:
# create an empty pool
self
.
num_ws
=
0
self
.
ws
=
[]
def
query
(
self
,
ws
):
"""Return w's from the pool.
Parameters:
ws: the latest generated w's from the generator
Returns w's from the buffer.
By 50/100, the buffer will return input w's.
By 50/100, the buffer will return w's previously stored in the buffer,
and insert the current w's to the buffer.
"""
if
self
.
pool_size
==
0
:
# if the buffer size is 0, do nothing
return
ws
return_ws
=
[]
for
w
in
ws
:
# ws.shape: (batch, 512) or (batch, n_latent, 512)
# w = torch.unsqueeze(image.data, 0)
if
w
.
ndim
==
2
:
i
=
random
.
randint
(
0
,
len
(
w
)
-
1
)
# apply a random latent index as a candidate
w
=
w
[
i
]
self
.
handle_w
(
w
,
return_ws
)
return_ws
=
torch
.
stack
(
return_ws
,
0
)
# collect all the images and return
return
return_ws
def
handle_w
(
self
,
w
,
return_ws
):
if
self
.
num_ws
<
self
.
pool_size
:
# if the buffer is not full; keep inserting current codes to the buffer
self
.
num_ws
=
self
.
num_ws
+
1
self
.
ws
.
append
(
w
)
return_ws
.
append
(
w
)
else
:
p
=
random
.
uniform
(
0
,
1
)
if
p
>
0.5
:
# by 50% chance, the buffer will return a previously stored latent code, and insert the current code into the buffer
random_id
=
random
.
randint
(
0
,
self
.
pool_size
-
1
)
# randint is inclusive
tmp
=
self
.
ws
[
random_id
].
clone
()
self
.
ws
[
random_id
]
=
w
return_ws
.
append
(
tmp
)
else
:
# by another 50% chance, the buffer will return the current image
return_ws
.
append
(
w
)
stylegan_human/pti/pti_models/e4e/psp.py
0 → 100644
View file @
fba8bde8
import
matplotlib
from
pti.pti_configs
import
paths_config
matplotlib
.
use
(
'Agg'
)
import
torch
from
torch
import
nn
from
pti.pti_models.e4e.encoders
import
psp_encoders
from
pti.pti_models.e4e.stylegan2.model
import
Generator
def
get_keys
(
d
,
name
):
if
'state_dict'
in
d
:
d
=
d
[
'state_dict'
]
d_filt
=
{
k
[
len
(
name
)
+
1
:]:
v
for
k
,
v
in
d
.
items
()
if
k
[:
len
(
name
)]
==
name
}
return
d_filt
class
pSp
(
nn
.
Module
):
def
__init__
(
self
,
opts
):
super
(
pSp
,
self
).
__init__
()
self
.
opts
=
opts
# Define architecture
self
.
encoder
=
self
.
set_encoder
()
self
.
decoder
=
Generator
(
opts
.
stylegan_size
,
512
,
8
,
channel_multiplier
=
2
)
self
.
face_pool
=
torch
.
nn
.
AdaptiveAvgPool2d
((
256
,
256
//
2
))
# Load weights if needed
self
.
load_weights
()
def
set_encoder
(
self
):
if
self
.
opts
.
encoder_type
==
'GradualStyleEncoder'
:
encoder
=
psp_encoders
.
GradualStyleEncoder
(
50
,
'ir_se'
,
self
.
opts
)
elif
self
.
opts
.
encoder_type
==
'Encoder4Editing'
:
encoder
=
psp_encoders
.
Encoder4Editing
(
50
,
'ir_se'
,
self
.
opts
)
elif
self
.
opts
.
encoder_type
==
'SingleStyleCodeEncoder'
:
encoder
=
psp_encoders
.
BackboneEncoderUsingLastLayerIntoW
(
50
,
'ir_se'
,
self
.
opts
)
else
:
raise
Exception
(
'{} is not a valid encoders'
.
format
(
self
.
opts
.
encoder_type
))
return
encoder
def
load_weights
(
self
):
if
self
.
opts
.
checkpoint_path
is
not
None
:
print
(
'Loading e4e over the pSp framework from checkpoint: {}'
.
format
(
self
.
opts
.
checkpoint_path
))
ckpt
=
torch
.
load
(
self
.
opts
.
checkpoint_path
,
map_location
=
'cpu'
)
self
.
encoder
.
load_state_dict
(
get_keys
(
ckpt
,
'encoder'
),
strict
=
True
)
self
.
decoder
.
load_state_dict
(
get_keys
(
ckpt
,
'decoder'
),
strict
=
True
)
self
.
__load_latent_avg
(
ckpt
)
else
:
print
(
'Loading encoders weights from irse50!'
)
encoder_ckpt
=
torch
.
load
(
model_paths
[
'ir_se50'
])
self
.
encoder
.
load_state_dict
(
encoder_ckpt
,
strict
=
False
)
print
(
'Loading decoder weights from pretrained!'
)
ckpt
=
torch
.
load
(
self
.
opts
.
stylegan_weights
)
self
.
decoder
.
load_state_dict
(
ckpt
[
'g_ema'
],
strict
=
False
)
self
.
__load_latent_avg
(
ckpt
,
repeat
=
self
.
encoder
.
style_count
)
def
forward
(
self
,
x
,
resize
=
True
,
latent_mask
=
None
,
input_code
=
False
,
randomize_noise
=
True
,
inject_latent
=
None
,
return_latents
=
False
,
alpha
=
None
):
if
input_code
:
codes
=
x
else
:
codes
=
self
.
encoder
(
x
)
# normalize with respect to the center of an average face
if
self
.
opts
.
start_from_latent_avg
:
if
codes
.
ndim
==
2
:
codes
=
codes
+
self
.
latent_avg
.
repeat
(
codes
.
shape
[
0
],
1
,
1
)[:,
0
,
:]
else
:
codes
=
codes
+
self
.
latent_avg
.
repeat
(
codes
.
shape
[
0
],
1
,
1
)
if
latent_mask
is
not
None
:
for
i
in
latent_mask
:
if
inject_latent
is
not
None
:
if
alpha
is
not
None
:
codes
[:,
i
]
=
alpha
*
inject_latent
[:,
i
]
+
(
1
-
alpha
)
*
codes
[:,
i
]
else
:
codes
[:,
i
]
=
inject_latent
[:,
i
]
else
:
codes
[:,
i
]
=
0
input_is_latent
=
not
input_code
images
,
result_latent
=
self
.
decoder
([
codes
],
input_is_latent
=
input_is_latent
,
randomize_noise
=
randomize_noise
,
return_latents
=
return_latents
)
if
resize
:
images
=
self
.
face_pool
(
images
)
if
return_latents
:
return
images
,
result_latent
else
:
return
images
def
__load_latent_avg
(
self
,
ckpt
,
repeat
=
None
):
if
'latent_avg'
in
ckpt
:
self
.
latent_avg
=
ckpt
[
'latent_avg'
].
to
(
self
.
opts
.
device
)
if
repeat
is
not
None
:
self
.
latent_avg
=
self
.
latent_avg
.
repeat
(
repeat
,
1
)
else
:
self
.
latent_avg
=
None
stylegan_human/pti/pti_models/e4e/stylegan2/__init__.py
0 → 100644
View file @
fba8bde8
stylegan_human/pti/pti_models/e4e/stylegan2/model.py
0 → 100644
View file @
fba8bde8
import
math
import
random
import
torch
from
torch
import
nn
from
torch.nn
import
functional
as
F
from
.op.fused_act
import
FusedLeakyReLU
,
fused_leaky_relu
from
.op.upfirdn2d
import
upfirdn2d
class
PixelNorm
(
nn
.
Module
):
def
__init__
(
self
):
super
().
__init__
()
def
forward
(
self
,
input
):
return
input
*
torch
.
rsqrt
(
torch
.
mean
(
input
**
2
,
dim
=
1
,
keepdim
=
True
)
+
1e-8
)
def
make_kernel
(
k
):
k
=
torch
.
tensor
(
k
,
dtype
=
torch
.
float32
)
if
k
.
ndim
==
1
:
k
=
k
[
None
,
:]
*
k
[:,
None
]
k
/=
k
.
sum
()
return
k
class
Upsample
(
nn
.
Module
):
def
__init__
(
self
,
kernel
,
factor
=
2
):
super
().
__init__
()
self
.
factor
=
factor
kernel
=
make_kernel
(
kernel
)
*
(
factor
**
2
)
self
.
register_buffer
(
'kernel'
,
kernel
)
p
=
kernel
.
shape
[
0
]
-
factor
pad0
=
(
p
+
1
)
//
2
+
factor
-
1
pad1
=
p
//
2
self
.
pad
=
(
pad0
,
pad1
)
def
forward
(
self
,
input
):
out
=
upfirdn2d
(
input
,
self
.
kernel
,
up
=
self
.
factor
,
down
=
1
,
pad
=
self
.
pad
)
return
out
class
Downsample
(
nn
.
Module
):
def
__init__
(
self
,
kernel
,
factor
=
2
):
super
().
__init__
()
self
.
factor
=
factor
kernel
=
make_kernel
(
kernel
)
self
.
register_buffer
(
'kernel'
,
kernel
)
p
=
kernel
.
shape
[
0
]
-
factor
pad0
=
(
p
+
1
)
//
2
pad1
=
p
//
2
self
.
pad
=
(
pad0
,
pad1
)
def
forward
(
self
,
input
):
out
=
upfirdn2d
(
input
,
self
.
kernel
,
up
=
1
,
down
=
self
.
factor
,
pad
=
self
.
pad
)
return
out
class
Blur
(
nn
.
Module
):
def
__init__
(
self
,
kernel
,
pad
,
upsample_factor
=
1
):
super
().
__init__
()
kernel
=
make_kernel
(
kernel
)
if
upsample_factor
>
1
:
kernel
=
kernel
*
(
upsample_factor
**
2
)
self
.
register_buffer
(
'kernel'
,
kernel
)
self
.
pad
=
pad
def
forward
(
self
,
input
):
out
=
upfirdn2d
(
input
,
self
.
kernel
,
pad
=
self
.
pad
)
return
out
class
EqualConv2d
(
nn
.
Module
):
def
__init__
(
self
,
in_channel
,
out_channel
,
kernel_size
,
stride
=
1
,
padding
=
0
,
bias
=
True
):
super
().
__init__
()
self
.
weight
=
nn
.
Parameter
(
torch
.
randn
(
out_channel
,
in_channel
,
kernel_size
,
kernel_size
)
)
self
.
scale
=
1
/
math
.
sqrt
(
in_channel
*
kernel_size
**
2
)
self
.
stride
=
stride
self
.
padding
=
padding
if
bias
:
self
.
bias
=
nn
.
Parameter
(
torch
.
zeros
(
out_channel
))
else
:
self
.
bias
=
None
def
forward
(
self
,
input
):
out
=
F
.
conv2d
(
input
,
self
.
weight
*
self
.
scale
,
bias
=
self
.
bias
,
stride
=
self
.
stride
,
padding
=
self
.
padding
,
)
return
out
def
__repr__
(
self
):
return
(
f
'
{
self
.
__class__
.
__name__
}
(
{
self
.
weight
.
shape
[
1
]
}
,
{
self
.
weight
.
shape
[
0
]
}
,'
f
'
{
self
.
weight
.
shape
[
2
]
}
, stride=
{
self
.
stride
}
, padding=
{
self
.
padding
}
)'
)
class
EqualLinear
(
nn
.
Module
):
def
__init__
(
self
,
in_dim
,
out_dim
,
bias
=
True
,
bias_init
=
0
,
lr_mul
=
1
,
activation
=
None
):
super
().
__init__
()
self
.
weight
=
nn
.
Parameter
(
torch
.
randn
(
out_dim
,
in_dim
).
div_
(
lr_mul
))
if
bias
:
self
.
bias
=
nn
.
Parameter
(
torch
.
zeros
(
out_dim
).
fill_
(
bias_init
))
else
:
self
.
bias
=
None
self
.
activation
=
activation
self
.
scale
=
(
1
/
math
.
sqrt
(
in_dim
))
*
lr_mul
self
.
lr_mul
=
lr_mul
def
forward
(
self
,
input
):
if
self
.
activation
:
out
=
F
.
linear
(
input
,
self
.
weight
*
self
.
scale
)
out
=
fused_leaky_relu
(
out
,
self
.
bias
*
self
.
lr_mul
)
else
:
out
=
F
.
linear
(
input
,
self
.
weight
*
self
.
scale
,
bias
=
self
.
bias
*
self
.
lr_mul
)
return
out
def
__repr__
(
self
):
return
(
f
'
{
self
.
__class__
.
__name__
}
(
{
self
.
weight
.
shape
[
1
]
}
,
{
self
.
weight
.
shape
[
0
]
}
)'
)
class
ScaledLeakyReLU
(
nn
.
Module
):
def
__init__
(
self
,
negative_slope
=
0.2
):
super
().
__init__
()
self
.
negative_slope
=
negative_slope
def
forward
(
self
,
input
):
out
=
F
.
leaky_relu
(
input
,
negative_slope
=
self
.
negative_slope
)
return
out
*
math
.
sqrt
(
2
)
class
ModulatedConv2d
(
nn
.
Module
):
def
__init__
(
self
,
in_channel
,
out_channel
,
kernel_size
,
style_dim
,
demodulate
=
True
,
upsample
=
False
,
downsample
=
False
,
blur_kernel
=
[
1
,
3
,
3
,
1
],
):
super
().
__init__
()
self
.
eps
=
1e-8
self
.
kernel_size
=
kernel_size
self
.
in_channel
=
in_channel
self
.
out_channel
=
out_channel
self
.
upsample
=
upsample
self
.
downsample
=
downsample
if
upsample
:
factor
=
2
p
=
(
len
(
blur_kernel
)
-
factor
)
-
(
kernel_size
-
1
)
pad0
=
(
p
+
1
)
//
2
+
factor
-
1
pad1
=
p
//
2
+
1
self
.
blur
=
Blur
(
blur_kernel
,
pad
=
(
pad0
,
pad1
),
upsample_factor
=
factor
)
if
downsample
:
factor
=
2
p
=
(
len
(
blur_kernel
)
-
factor
)
+
(
kernel_size
-
1
)
pad0
=
(
p
+
1
)
//
2
pad1
=
p
//
2
self
.
blur
=
Blur
(
blur_kernel
,
pad
=
(
pad0
,
pad1
))
fan_in
=
in_channel
*
kernel_size
**
2
self
.
scale
=
1
/
math
.
sqrt
(
fan_in
)
self
.
padding
=
kernel_size
//
2
self
.
weight
=
nn
.
Parameter
(
torch
.
randn
(
1
,
out_channel
,
in_channel
,
kernel_size
,
kernel_size
)
)
self
.
modulation
=
EqualLinear
(
style_dim
,
in_channel
,
bias_init
=
1
)
self
.
demodulate
=
demodulate
def
__repr__
(
self
):
return
(
f
'
{
self
.
__class__
.
__name__
}
(
{
self
.
in_channel
}
,
{
self
.
out_channel
}
,
{
self
.
kernel_size
}
, '
f
'upsample=
{
self
.
upsample
}
, downsample=
{
self
.
downsample
}
)'
)
def
forward
(
self
,
input
,
style
):
batch
,
in_channel
,
height
,
width
=
input
.
shape
style
=
self
.
modulation
(
style
).
view
(
batch
,
1
,
in_channel
,
1
,
1
)
weight
=
self
.
scale
*
self
.
weight
*
style
if
self
.
demodulate
:
demod
=
torch
.
rsqrt
(
weight
.
pow
(
2
).
sum
([
2
,
3
,
4
])
+
1e-8
)
weight
=
weight
*
demod
.
view
(
batch
,
self
.
out_channel
,
1
,
1
,
1
)
weight
=
weight
.
view
(
batch
*
self
.
out_channel
,
in_channel
,
self
.
kernel_size
,
self
.
kernel_size
)
if
self
.
upsample
:
input
=
input
.
view
(
1
,
batch
*
in_channel
,
height
,
width
)
weight
=
weight
.
view
(
batch
,
self
.
out_channel
,
in_channel
,
self
.
kernel_size
,
self
.
kernel_size
)
weight
=
weight
.
transpose
(
1
,
2
).
reshape
(
batch
*
in_channel
,
self
.
out_channel
,
self
.
kernel_size
,
self
.
kernel_size
)
out
=
F
.
conv_transpose2d
(
input
,
weight
,
padding
=
0
,
stride
=
2
,
groups
=
batch
)
_
,
_
,
height
,
width
=
out
.
shape
out
=
out
.
view
(
batch
,
self
.
out_channel
,
height
,
width
)
out
=
self
.
blur
(
out
)
elif
self
.
downsample
:
input
=
self
.
blur
(
input
)
_
,
_
,
height
,
width
=
input
.
shape
input
=
input
.
view
(
1
,
batch
*
in_channel
,
height
,
width
)
out
=
F
.
conv2d
(
input
,
weight
,
padding
=
0
,
stride
=
2
,
groups
=
batch
)
_
,
_
,
height
,
width
=
out
.
shape
out
=
out
.
view
(
batch
,
self
.
out_channel
,
height
,
width
)
else
:
input
=
input
.
view
(
1
,
batch
*
in_channel
,
height
,
width
)
out
=
F
.
conv2d
(
input
,
weight
,
padding
=
self
.
padding
,
groups
=
batch
)
_
,
_
,
height
,
width
=
out
.
shape
out
=
out
.
view
(
batch
,
self
.
out_channel
,
height
,
width
)
return
out
class
NoiseInjection
(
nn
.
Module
):
def
__init__
(
self
):
super
().
__init__
()
self
.
weight
=
nn
.
Parameter
(
torch
.
zeros
(
1
))
def
forward
(
self
,
image
,
noise
=
None
):
if
noise
is
None
:
batch
,
_
,
height
,
width
=
image
.
shape
noise
=
image
.
new_empty
(
batch
,
1
,
height
,
width
).
normal_
()
return
image
+
self
.
weight
*
noise
class
ConstantInput
(
nn
.
Module
):
def
__init__
(
self
,
channel
,
size
=
4
):
super
().
__init__
()
self
.
input
=
nn
.
Parameter
(
torch
.
randn
(
1
,
channel
,
size
,
size
//
2
))
def
forward
(
self
,
input
):
batch
=
input
.
shape
[
0
]
out
=
self
.
input
.
repeat
(
batch
,
1
,
1
,
1
)
return
out
class
StyledConv
(
nn
.
Module
):
def
__init__
(
self
,
in_channel
,
out_channel
,
kernel_size
,
style_dim
,
upsample
=
False
,
blur_kernel
=
[
1
,
3
,
3
,
1
],
demodulate
=
True
,
):
super
().
__init__
()
self
.
conv
=
ModulatedConv2d
(
in_channel
,
out_channel
,
kernel_size
,
style_dim
,
upsample
=
upsample
,
blur_kernel
=
blur_kernel
,
demodulate
=
demodulate
,
)
self
.
noise
=
NoiseInjection
()
# self.bias = nn.Parameter(torch.zeros(1, out_channel, 1, 1))
# self.activate = ScaledLeakyReLU(0.2)
self
.
activate
=
FusedLeakyReLU
(
out_channel
)
def
forward
(
self
,
input
,
style
,
noise
=
None
):
out
=
self
.
conv
(
input
,
style
)
out
=
self
.
noise
(
out
,
noise
=
noise
)
# out = out + self.bias
out
=
self
.
activate
(
out
)
return
out
class
ToRGB
(
nn
.
Module
):
def
__init__
(
self
,
in_channel
,
style_dim
,
upsample
=
True
,
blur_kernel
=
[
1
,
3
,
3
,
1
]):
super
().
__init__
()
if
upsample
:
self
.
upsample
=
Upsample
(
blur_kernel
)
self
.
conv
=
ModulatedConv2d
(
in_channel
,
3
,
1
,
style_dim
,
demodulate
=
False
)
self
.
bias
=
nn
.
Parameter
(
torch
.
zeros
(
1
,
3
,
1
,
1
))
def
forward
(
self
,
input
,
style
,
skip
=
None
):
out
=
self
.
conv
(
input
,
style
)
out
=
out
+
self
.
bias
if
skip
is
not
None
:
skip
=
self
.
upsample
(
skip
)
out
=
out
+
skip
return
out
class
Generator
(
nn
.
Module
):
def
__init__
(
self
,
size
,
style_dim
,
n_mlp
,
channel_multiplier
=
2
,
blur_kernel
=
[
1
,
3
,
3
,
1
],
lr_mlp
=
0.01
,
):
super
().
__init__
()
self
.
size
=
size
self
.
style_dim
=
style_dim
layers
=
[
PixelNorm
()]
for
i
in
range
(
n_mlp
):
layers
.
append
(
EqualLinear
(
style_dim
,
style_dim
,
lr_mul
=
lr_mlp
,
activation
=
'fused_lrelu'
)
)
self
.
style
=
nn
.
Sequential
(
*
layers
)
self
.
channels
=
{
4
:
512
,
8
:
512
,
16
:
512
,
32
:
512
,
64
:
256
*
channel_multiplier
,
128
:
128
*
channel_multiplier
,
256
:
64
*
channel_multiplier
,
512
:
32
*
channel_multiplier
,
1024
:
16
*
channel_multiplier
,
}
self
.
input
=
ConstantInput
(
self
.
channels
[
4
])
self
.
conv1
=
StyledConv
(
self
.
channels
[
4
],
self
.
channels
[
4
],
3
,
style_dim
,
blur_kernel
=
blur_kernel
)
self
.
to_rgb1
=
ToRGB
(
self
.
channels
[
4
],
style_dim
,
upsample
=
False
)
self
.
log_size
=
int
(
math
.
log
(
size
,
2
))
self
.
num_layers
=
(
self
.
log_size
-
2
)
*
2
+
1
self
.
convs
=
nn
.
ModuleList
()
self
.
upsamples
=
nn
.
ModuleList
()
self
.
to_rgbs
=
nn
.
ModuleList
()
self
.
noises
=
nn
.
Module
()
in_channel
=
self
.
channels
[
4
]
for
layer_idx
in
range
(
self
.
num_layers
):
res
=
(
layer_idx
+
5
)
//
2
shape
=
[
1
,
1
,
2
**
res
,
2
**
res
//
2
]
self
.
noises
.
register_buffer
(
"noise_{}"
.
format
(
layer_idx
),
torch
.
randn
(
*
shape
)
)
for
i
in
range
(
3
,
self
.
log_size
+
1
):
out_channel
=
self
.
channels
[
2
**
i
]
self
.
convs
.
append
(
StyledConv
(
in_channel
,
out_channel
,
3
,
style_dim
,
upsample
=
True
,
blur_kernel
=
blur_kernel
,
)
)
self
.
convs
.
append
(
StyledConv
(
out_channel
,
out_channel
,
3
,
style_dim
,
blur_kernel
=
blur_kernel
)
)
self
.
to_rgbs
.
append
(
ToRGB
(
out_channel
,
style_dim
))
in_channel
=
out_channel
self
.
n_latent
=
self
.
log_size
*
2
-
2
def
make_noise
(
self
):
device
=
self
.
input
.
input
.
device
noises
=
[
torch
.
randn
(
1
,
1
,
2
**
2
,
2
**
2
//
2
,
device
=
device
)]
for
i
in
range
(
3
,
self
.
log_size
+
1
):
for
_
in
range
(
2
):
noises
.
append
(
torch
.
randn
(
1
,
1
,
2
**
i
,
2
**
i
//
2
,
device
=
device
))
return
noises
def
mean_latent
(
self
,
n_latent
):
latent_in
=
torch
.
randn
(
n_latent
,
self
.
style_dim
,
device
=
self
.
input
.
input
.
device
)
latent
=
self
.
style
(
latent_in
).
mean
(
0
,
keepdim
=
True
)
return
latent
def
get_latent
(
self
,
input
):
return
self
.
style
(
input
)
def
forward
(
self
,
styles
,
return_latents
=
False
,
return_features
=
False
,
inject_index
=
None
,
truncation
=
1
,
truncation_latent
=
None
,
input_is_latent
=
False
,
noise
=
None
,
randomize_noise
=
True
,
):
if
not
input_is_latent
:
styles
=
[
self
.
style
(
s
)
for
s
in
styles
]
if
noise
is
None
:
if
randomize_noise
:
noise
=
[
None
]
*
self
.
num_layers
else
:
noise
=
[
getattr
(
self
.
noises
,
f
'noise_
{
i
}
'
)
for
i
in
range
(
self
.
num_layers
)
]
if
truncation
<
1
:
style_t
=
[]
for
style
in
styles
:
style_t
.
append
(
truncation_latent
+
truncation
*
(
style
-
truncation_latent
)
)
styles
=
style_t
if
len
(
styles
)
<
2
:
inject_index
=
self
.
n_latent
if
styles
[
0
].
ndim
<
3
:
latent
=
styles
[
0
].
unsqueeze
(
1
).
repeat
(
1
,
inject_index
,
1
)
else
:
latent
=
styles
[
0
]
else
:
if
inject_index
is
None
:
inject_index
=
random
.
randint
(
1
,
self
.
n_latent
-
1
)
# latent = styles[0].unsqueeze(0)
# if latent.shape[1] == 1:
# latent = latent.repeat(1, inject_index, 1)
# else:
# latent = latent[:, :inject_index, :]
latent
=
styles
[
0
].
unsqueeze
(
1
).
repeat
(
1
,
inject_index
,
1
)
latent2
=
styles
[
1
].
unsqueeze
(
1
).
repeat
(
1
,
self
.
n_latent
-
inject_index
,
1
)
# latent = styles[0][:, :inject_index, :]
# latent2 = styles[1][:, inject_index:, :]
latent
=
torch
.
cat
([
latent
,
latent2
],
1
)
out
=
self
.
input
(
latent
)
out
=
self
.
conv1
(
out
,
latent
[:,
0
],
noise
=
noise
[
0
])
skip
=
self
.
to_rgb1
(
out
,
latent
[:,
1
])
i
=
1
for
conv1
,
conv2
,
noise1
,
noise2
,
to_rgb
in
zip
(
self
.
convs
[::
2
],
self
.
convs
[
1
::
2
],
noise
[
1
::
2
],
noise
[
2
::
2
],
self
.
to_rgbs
):
out
=
conv1
(
out
,
latent
[:,
i
],
noise
=
noise1
)
out
=
conv2
(
out
,
latent
[:,
i
+
1
],
noise
=
noise2
)
skip
=
to_rgb
(
out
,
latent
[:,
i
+
2
],
skip
)
i
+=
2
image
=
skip
if
return_latents
:
return
image
,
latent
elif
return_features
:
return
image
,
out
else
:
return
image
,
None
class
ConvLayer
(
nn
.
Sequential
):
def
__init__
(
self
,
in_channel
,
out_channel
,
kernel_size
,
downsample
=
False
,
blur_kernel
=
[
1
,
3
,
3
,
1
],
bias
=
True
,
activate
=
True
,
):
layers
=
[]
if
downsample
:
factor
=
2
p
=
(
len
(
blur_kernel
)
-
factor
)
+
(
kernel_size
-
1
)
pad0
=
(
p
+
1
)
//
2
pad1
=
p
//
2
layers
.
append
(
Blur
(
blur_kernel
,
pad
=
(
pad0
,
pad1
)))
stride
=
2
self
.
padding
=
0
else
:
stride
=
1
self
.
padding
=
kernel_size
//
2
layers
.
append
(
EqualConv2d
(
in_channel
,
out_channel
,
kernel_size
,
padding
=
self
.
padding
,
stride
=
stride
,
bias
=
bias
and
not
activate
,
)
)
if
activate
:
if
bias
:
layers
.
append
(
FusedLeakyReLU
(
out_channel
))
else
:
layers
.
append
(
ScaledLeakyReLU
(
0.2
))
super
().
__init__
(
*
layers
)
class
ResBlock
(
nn
.
Module
):
def
__init__
(
self
,
in_channel
,
out_channel
,
blur_kernel
=
[
1
,
3
,
3
,
1
]):
super
().
__init__
()
self
.
conv1
=
ConvLayer
(
in_channel
,
in_channel
,
3
)
self
.
conv2
=
ConvLayer
(
in_channel
,
out_channel
,
3
,
downsample
=
True
)
self
.
skip
=
ConvLayer
(
in_channel
,
out_channel
,
1
,
downsample
=
True
,
activate
=
False
,
bias
=
False
)
def
forward
(
self
,
input
):
out
=
self
.
conv1
(
input
)
out
=
self
.
conv2
(
out
)
skip
=
self
.
skip
(
input
)
out
=
(
out
+
skip
)
/
math
.
sqrt
(
2
)
return
out
class
Discriminator
(
nn
.
Module
):
def
__init__
(
self
,
size
,
channel_multiplier
=
2
,
blur_kernel
=
[
1
,
3
,
3
,
1
]):
super
().
__init__
()
channels
=
{
4
:
512
,
8
:
512
,
16
:
512
,
32
:
512
,
64
:
256
*
channel_multiplier
,
128
:
128
*
channel_multiplier
,
256
:
64
*
channel_multiplier
,
512
:
32
*
channel_multiplier
,
1024
:
16
*
channel_multiplier
,
}
convs
=
[
ConvLayer
(
3
,
channels
[
size
],
1
)]
log_size
=
int
(
math
.
log
(
size
,
2
))
in_channel
=
channels
[
size
]
for
i
in
range
(
log_size
,
2
,
-
1
):
out_channel
=
channels
[
2
**
(
i
-
1
)]
convs
.
append
(
ResBlock
(
in_channel
,
out_channel
,
blur_kernel
))
in_channel
=
out_channel
self
.
convs
=
nn
.
Sequential
(
*
convs
)
self
.
stddev_group
=
4
self
.
stddev_feat
=
1
self
.
final_conv
=
ConvLayer
(
in_channel
+
1
,
channels
[
4
],
3
)
self
.
final_linear
=
nn
.
Sequential
(
EqualLinear
(
channels
[
4
]
*
4
*
4
//
2
,
channels
[
4
],
activation
=
'fused_lrelu'
),
EqualLinear
(
channels
[
4
],
1
),
)
def
forward
(
self
,
input
):
out
=
self
.
convs
(
input
)
batch
,
channel
,
height
,
width
=
out
.
shape
group
=
min
(
batch
,
self
.
stddev_group
)
stddev
=
out
.
view
(
group
,
-
1
,
self
.
stddev_feat
,
channel
//
self
.
stddev_feat
,
height
,
width
)
stddev
=
torch
.
sqrt
(
stddev
.
var
(
0
,
unbiased
=
False
)
+
1e-8
)
stddev
=
stddev
.
mean
([
2
,
3
,
4
],
keepdims
=
True
).
squeeze
(
2
)
stddev
=
stddev
.
repeat
(
group
,
1
,
height
,
width
)
out
=
torch
.
cat
([
out
,
stddev
],
1
)
out
=
self
.
final_conv
(
out
)
out
=
out
.
view
(
batch
,
-
1
)
out
=
self
.
final_linear
(
out
)
return
out
stylegan_human/pti/pti_models/e4e/stylegan2/op/__init__.py
0 → 100644
View file @
fba8bde8
from
.fused_act
import
FusedLeakyReLU
,
fused_leaky_relu
from
.upfirdn2d
import
upfirdn2d
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_act.py
0 → 100644
View file @
fba8bde8
import
os
import
torch
from
torch
import
nn
from
torch.nn
import
functional
as
F
from
torch.autograd
import
Function
module_path
=
os
.
path
.
dirname
(
__file__
)
class
FusedLeakyReLU
(
nn
.
Module
):
def
__init__
(
self
,
channel
,
negative_slope
=
0.2
,
scale
=
2
**
0.5
):
super
().
__init__
()
self
.
bias
=
nn
.
Parameter
(
torch
.
zeros
(
channel
))
self
.
negative_slope
=
negative_slope
self
.
scale
=
scale
def
forward
(
self
,
input
):
return
fused_leaky_relu
(
input
,
self
.
bias
,
self
.
negative_slope
,
self
.
scale
)
def
fused_leaky_relu
(
input
,
bias
,
negative_slope
=
0.2
,
scale
=
2
**
0.5
):
rest_dim
=
[
1
]
*
(
input
.
ndim
-
bias
.
ndim
-
1
)
input
=
input
.
cuda
()
return
(
F
.
leaky_relu
(
input
+
bias
.
view
(
1
,
bias
.
shape
[
0
],
*
rest_dim
),
negative_slope
=
negative_slope
)
*
scale
)
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_bias_act.cpp
0 → 100644
View file @
fba8bde8
#include <torch/extension.h>
torch
::
Tensor
fused_bias_act_op
(
const
torch
::
Tensor
&
input
,
const
torch
::
Tensor
&
bias
,
const
torch
::
Tensor
&
refer
,
int
act
,
int
grad
,
float
alpha
,
float
scale
);
#define CHECK_CUDA(x) TORCH_CHECK(x.type().is_cuda(), #x " must be a CUDA tensor")
#define CHECK_CONTIGUOUS(x) TORCH_CHECK(x.is_contiguous(), #x " must be contiguous")
#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x)
torch
::
Tensor
fused_bias_act
(
const
torch
::
Tensor
&
input
,
const
torch
::
Tensor
&
bias
,
const
torch
::
Tensor
&
refer
,
int
act
,
int
grad
,
float
alpha
,
float
scale
)
{
CHECK_CUDA
(
input
);
CHECK_CUDA
(
bias
);
return
fused_bias_act_op
(
input
,
bias
,
refer
,
act
,
grad
,
alpha
,
scale
);
}
PYBIND11_MODULE
(
TORCH_EXTENSION_NAME
,
m
)
{
m
.
def
(
"fused_bias_act"
,
&
fused_bias_act
,
"fused bias act (CUDA)"
);
}
\ No newline at end of file
stylegan_human/pti/pti_models/e4e/stylegan2/op/fused_bias_act_kernel.cu
0 → 100644
View file @
fba8bde8
// Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
//
// This work is made available under the Nvidia Source Code License-NC.
// To view a copy of this license, visit
// https://nvlabs.github.io/stylegan2/license.html
#include <torch/types.h>
#include <ATen/ATen.h>
#include <ATen/AccumulateType.h>
#include <ATen/cuda/CUDAContext.h>
#include <ATen/cuda/CUDAApplyUtils.cuh>
#include <cuda.h>
#include <cuda_runtime.h>
template
<
typename
scalar_t
>
static
__global__
void
fused_bias_act_kernel
(
scalar_t
*
out
,
const
scalar_t
*
p_x
,
const
scalar_t
*
p_b
,
const
scalar_t
*
p_ref
,
int
act
,
int
grad
,
scalar_t
alpha
,
scalar_t
scale
,
int
loop_x
,
int
size_x
,
int
step_b
,
int
size_b
,
int
use_bias
,
int
use_ref
)
{
int
xi
=
blockIdx
.
x
*
loop_x
*
blockDim
.
x
+
threadIdx
.
x
;
scalar_t
zero
=
0.0
;
for
(
int
loop_idx
=
0
;
loop_idx
<
loop_x
&&
xi
<
size_x
;
loop_idx
++
,
xi
+=
blockDim
.
x
)
{
scalar_t
x
=
p_x
[
xi
];
if
(
use_bias
)
{
x
+=
p_b
[(
xi
/
step_b
)
%
size_b
];
}
scalar_t
ref
=
use_ref
?
p_ref
[
xi
]
:
zero
;
scalar_t
y
;
switch
(
act
*
10
+
grad
)
{
default:
case
10
:
y
=
x
;
break
;
case
11
:
y
=
x
;
break
;
case
12
:
y
=
0.0
;
break
;
case
30
:
y
=
(
x
>
0.0
)
?
x
:
x
*
alpha
;
break
;
case
31
:
y
=
(
ref
>
0.0
)
?
x
:
x
*
alpha
;
break
;
case
32
:
y
=
0.0
;
break
;
}
out
[
xi
]
=
y
*
scale
;
}
}
torch
::
Tensor
fused_bias_act_op
(
const
torch
::
Tensor
&
input
,
const
torch
::
Tensor
&
bias
,
const
torch
::
Tensor
&
refer
,
int
act
,
int
grad
,
float
alpha
,
float
scale
)
{
int
curDevice
=
-
1
;
cudaGetDevice
(
&
curDevice
);
cudaStream_t
stream
=
at
::
cuda
::
getCurrentCUDAStream
(
curDevice
);
auto
x
=
input
.
contiguous
();
auto
b
=
bias
.
contiguous
();
auto
ref
=
refer
.
contiguous
();
int
use_bias
=
b
.
numel
()
?
1
:
0
;
int
use_ref
=
ref
.
numel
()
?
1
:
0
;
int
size_x
=
x
.
numel
();
int
size_b
=
b
.
numel
();
int
step_b
=
1
;
for
(
int
i
=
1
+
1
;
i
<
x
.
dim
();
i
++
)
{
step_b
*=
x
.
size
(
i
);
}
int
loop_x
=
4
;
int
block_size
=
4
*
32
;
int
grid_size
=
(
size_x
-
1
)
/
(
loop_x
*
block_size
)
+
1
;
auto
y
=
torch
::
empty_like
(
x
);
AT_DISPATCH_FLOATING_TYPES_AND_HALF
(
x
.
scalar_type
(),
"fused_bias_act_kernel"
,
[
&
]
{
fused_bias_act_kernel
<
scalar_t
><<<
grid_size
,
block_size
,
0
,
stream
>>>
(
y
.
data_ptr
<
scalar_t
>
(),
x
.
data_ptr
<
scalar_t
>
(),
b
.
data_ptr
<
scalar_t
>
(),
ref
.
data_ptr
<
scalar_t
>
(),
act
,
grad
,
alpha
,
scale
,
loop_x
,
size_x
,
step_b
,
size_b
,
use_bias
,
use_ref
);
});
return
y
;
}
\ No newline at end of file
Prev
1
2
3
4
5
6
7
8
9
…
12
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment