Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Shreyan Chowdhury
moodwalk
Commits
48deb5bb
Commit
48deb5bb
authored
Sep 09, 2019
by
Verena Praher
Browse files
add dataloaders to resnet, make resnet experiment work
parent
abf2d01d
Changes
3
Hide whitespace changes
Inline
Side-by-side
experiments/experiment_resnets.py
View file @
48deb5bb
from
utils
import
CURR_RUN_PATH
,
USE_GPU
,
logger
from
pytorch_lightning
import
Trainer
from
pytorch_lightning.callbacks
import
EarlyStopping
from
pytorch_lightning.callbacks
import
EarlyStopping
,
ModelCheckpoint
from
test_tube
import
Experiment
from
models.resnet18
import
Network
import
os
def
run
():
...
...
@@ -13,21 +14,30 @@ def run():
# callbacks
early_stop
=
EarlyStopping
(
monitor
=
'val_loss'
,
# TODO: check if this exists
monitor
=
'val_loss'
,
patience
=
50
,
verbose
=
True
,
mode
=
'min'
# TODO: check if correct
mode
=
'min'
)
checkpoint_callback
=
ModelCheckpoint
(
filepath
=
os
.
path
.
join
(
CURR_RUN_PATH
,
'best.ckpt'
),
save_best_only
=
True
,
verbose
=
True
,
monitor
=
'val_loss'
,
mode
=
'min'
)
if
USE_GPU
:
trainer
=
Trainer
(
gpus
=
[
0
],
distributed_backend
=
'ddp'
,
experiment
=
exp
,
max_nb_epochs
=
500
,
train_percent_check
=
1.0
,
fast_dev_run
=
False
,
early_stop_callback
=
early_stop
)
fast_dev_run
=
False
,
early_stop_callback
=
early_stop
,
checkpoint_callback
=
checkpoint_callback
)
else
:
trainer
=
Trainer
(
experiment
=
exp
,
max_nb_epochs
=
1
,
train_percent_check
=
0.1
,
fast_dev_run
=
True
)
model
=
Network
()
# TODO num_tags
model
=
Network
(
56
)
# TODO num_tags
print
(
model
)
...
...
models/resnet18.py
View file @
48deb5bb
from
utils
import
*
from
datasets
import
MelSpecDataset
import
torch
import
torch.nn
as
nn
import
torch.nn.functional
as
F
from
torch.utils.data
import
DataLoader
import
pytorch_lightning
as
pl
from
models.shared_stuff
import
tng_dataloader
,
val_dataloader
,
test_dataloader
,
\
validation_end
,
training_step
,
validation_step
from
sklearn.metrics
import
roc_auc_score
# TODO pr-auc
# TODO f1-score
from
torchvision.models
import
r
es
n
et
18
from
models.resnet_arch
import
R
es
N
et
,
BasicBlock
class
Network
(
pl
.
LightningModule
):
def
__init__
(
self
,
num_tags
):
super
(
Network
,
self
).
__init__
()
self
.
num_tags
=
num_tags
self
.
model
=
resnet18
(
False
)
# TODO: need to check if optimizer recognizes these parameters
num_features
=
self
.
model
.
fc
.
in_features
self
.
model
.
fc
=
nn
.
Linear
(
num_features
,
self
.
num_tags
)
# overwriting fc layer
self
.
sig
=
nn
.
Sigmoid
(
self
.
num_tags
)
self
.
model
=
nn
.
Sequential
(
ResNet
(
BasicBlock
,
[
2
,
2
,
2
,
2
],
num_classes
=
self
.
num_tags
),
nn
.
Sigmoid
())
# TODO: need to check if optimizer recognizes these parameters
# num_features = self.model.fc.in_features
# self.model.fc = nn.Linear(num_features, self.num_tags) # overwriting fc layer
# self.sig = nn.Sigmoid()
def
forward
(
self
,
x
):
x
=
self
.
model
(
x
)
x
=
self
.
sig
(
x
)
#
x = self.sig(x)
return
x
def
my_loss
(
self
,
y_hat
,
y
):
return
F
.
binary_cross_entropy
(
y_hat
,
y
)
def
configure_optimizers
(
self
):
return
[
torch
.
optim
.
Adam
(
self
.
parameters
(),
lr
=
0.001
)]
\ No newline at end of file
return
[
torch
.
optim
.
Adam
(
self
.
parameters
(),
lr
=
0.001
)]
def
training_step
(
self
,
data_batch
,
batch_nb
):
return
training_step
(
self
,
data_batch
,
batch_nb
)
def
validation_step
(
self
,
data_batch
,
batch_nb
):
return
validation_step
(
self
,
data_batch
,
batch_nb
)
def
validation_end
(
self
,
outputs
):
return
validation_end
(
outputs
)
@
pl
.
data_loader
def
tng_dataloader
(
self
):
return
tng_dataloader
()
@
pl
.
data_loader
def
val_dataloader
(
self
):
return
val_dataloader
()
@
pl
.
data_loader
def
test_dataloader
(
self
):
return
test_dataloader
()
models/resnet_arch.py
0 → 100644
View file @
48deb5bb
import
torch.nn
as
nn
import
torch
def
conv3x3
(
in_planes
,
out_planes
,
stride
=
1
,
groups
=
1
,
dilation
=
1
):
"""3x3 convolution with padding"""
return
nn
.
Conv2d
(
in_planes
,
out_planes
,
kernel_size
=
3
,
stride
=
stride
,
padding
=
dilation
,
groups
=
groups
,
bias
=
False
,
dilation
=
dilation
)
def
conv1x1
(
in_planes
,
out_planes
,
stride
=
1
):
"""1x1 convolution"""
return
nn
.
Conv2d
(
in_planes
,
out_planes
,
kernel_size
=
1
,
stride
=
stride
,
bias
=
False
)
class
BasicBlock
(
nn
.
Module
):
expansion
=
1
__constants__
=
[
'downsample'
]
def
__init__
(
self
,
inplanes
,
planes
,
stride
=
1
,
downsample
=
None
,
groups
=
1
,
base_width
=
64
,
dilation
=
1
,
norm_layer
=
None
):
super
(
BasicBlock
,
self
).
__init__
()
if
norm_layer
is
None
:
norm_layer
=
nn
.
BatchNorm2d
if
groups
!=
1
or
base_width
!=
64
:
raise
ValueError
(
'BasicBlock only supports groups=1 and base_width=64'
)
if
dilation
>
1
:
raise
NotImplementedError
(
"Dilation > 1 not supported in BasicBlock"
)
# Both self.conv1 and self.downsample layers downsample the input when stride != 1
self
.
conv1
=
conv3x3
(
inplanes
,
planes
,
stride
)
self
.
bn1
=
norm_layer
(
planes
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
conv2
=
conv3x3
(
planes
,
planes
)
self
.
bn2
=
norm_layer
(
planes
)
self
.
downsample
=
downsample
self
.
stride
=
stride
def
forward
(
self
,
x
):
identity
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
bn1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
bn2
(
out
)
if
self
.
downsample
is
not
None
:
identity
=
self
.
downsample
(
x
)
out
+=
identity
out
=
self
.
relu
(
out
)
return
out
class
Bottleneck
(
nn
.
Module
):
expansion
=
4
def
__init__
(
self
,
inplanes
,
planes
,
stride
=
1
,
downsample
=
None
,
groups
=
1
,
base_width
=
64
,
dilation
=
1
,
norm_layer
=
None
):
super
(
Bottleneck
,
self
).
__init__
()
if
norm_layer
is
None
:
norm_layer
=
nn
.
BatchNorm2d
width
=
int
(
planes
*
(
base_width
/
64.
))
*
groups
# Both self.conv2 and self.downsample layers downsample the input when stride != 1
self
.
conv1
=
conv1x1
(
inplanes
,
width
)
self
.
bn1
=
norm_layer
(
width
)
self
.
conv2
=
conv3x3
(
width
,
width
,
stride
,
groups
,
dilation
)
self
.
bn2
=
norm_layer
(
width
)
self
.
conv3
=
conv1x1
(
width
,
planes
*
self
.
expansion
)
self
.
bn3
=
norm_layer
(
planes
*
self
.
expansion
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
downsample
=
downsample
self
.
stride
=
stride
def
forward
(
self
,
x
):
identity
=
x
out
=
self
.
conv1
(
x
)
out
=
self
.
bn1
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv2
(
out
)
out
=
self
.
bn2
(
out
)
out
=
self
.
relu
(
out
)
out
=
self
.
conv3
(
out
)
out
=
self
.
bn3
(
out
)
if
self
.
downsample
is
not
None
:
identity
=
self
.
downsample
(
x
)
out
+=
identity
out
=
self
.
relu
(
out
)
return
out
class
ResNet
(
nn
.
Module
):
def
__init__
(
self
,
block
,
layers
,
num_classes
=
1000
,
zero_init_residual
=
False
,
groups
=
1
,
width_per_group
=
64
,
replace_stride_with_dilation
=
None
,
norm_layer
=
None
):
super
(
ResNet
,
self
).
__init__
()
if
norm_layer
is
None
:
norm_layer
=
nn
.
BatchNorm2d
self
.
_norm_layer
=
norm_layer
self
.
inplanes
=
64
self
.
dilation
=
1
if
replace_stride_with_dilation
is
None
:
# each element in the tuple indicates if we should replace
# the 2x2 stride with a dilated convolution instead
replace_stride_with_dilation
=
[
False
,
False
,
False
]
if
len
(
replace_stride_with_dilation
)
!=
3
:
raise
ValueError
(
"replace_stride_with_dilation should be None "
"or a 3-element tuple, got {}"
.
format
(
replace_stride_with_dilation
))
self
.
groups
=
groups
self
.
base_width
=
width_per_group
self
.
conv1
=
nn
.
Conv2d
(
1
,
self
.
inplanes
,
kernel_size
=
7
,
stride
=
2
,
padding
=
3
,
bias
=
False
)
self
.
bn1
=
norm_layer
(
self
.
inplanes
)
self
.
relu
=
nn
.
ReLU
(
inplace
=
True
)
self
.
maxpool
=
nn
.
MaxPool2d
(
kernel_size
=
3
,
stride
=
2
,
padding
=
1
)
self
.
layer1
=
self
.
_make_layer
(
block
,
64
,
layers
[
0
])
self
.
layer2
=
self
.
_make_layer
(
block
,
128
,
layers
[
1
],
stride
=
2
,
dilate
=
replace_stride_with_dilation
[
0
])
self
.
layer3
=
self
.
_make_layer
(
block
,
256
,
layers
[
2
],
stride
=
2
,
dilate
=
replace_stride_with_dilation
[
1
])
self
.
layer4
=
self
.
_make_layer
(
block
,
512
,
layers
[
3
],
stride
=
2
,
dilate
=
replace_stride_with_dilation
[
2
])
self
.
avgpool
=
nn
.
AdaptiveAvgPool2d
((
1
,
1
))
self
.
fc
=
nn
.
Linear
(
512
*
block
.
expansion
,
num_classes
)
for
m
in
self
.
modules
():
if
isinstance
(
m
,
nn
.
Conv2d
):
nn
.
init
.
kaiming_normal_
(
m
.
weight
,
mode
=
'fan_out'
,
nonlinearity
=
'relu'
)
elif
isinstance
(
m
,
(
nn
.
BatchNorm2d
,
nn
.
GroupNorm
)):
nn
.
init
.
constant_
(
m
.
weight
,
1
)
nn
.
init
.
constant_
(
m
.
bias
,
0
)
# Zero-initialize the last BN in each residual branch,
# so that the residual branch starts with zeros, and each residual block behaves like an identity.
# This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
if
zero_init_residual
:
for
m
in
self
.
modules
():
if
isinstance
(
m
,
Bottleneck
):
nn
.
init
.
constant_
(
m
.
bn3
.
weight
,
0
)
elif
isinstance
(
m
,
BasicBlock
):
nn
.
init
.
constant_
(
m
.
bn2
.
weight
,
0
)
def
_make_layer
(
self
,
block
,
planes
,
blocks
,
stride
=
1
,
dilate
=
False
):
norm_layer
=
self
.
_norm_layer
downsample
=
None
previous_dilation
=
self
.
dilation
if
dilate
:
self
.
dilation
*=
stride
stride
=
1
if
stride
!=
1
or
self
.
inplanes
!=
planes
*
block
.
expansion
:
downsample
=
nn
.
Sequential
(
conv1x1
(
self
.
inplanes
,
planes
*
block
.
expansion
,
stride
),
norm_layer
(
planes
*
block
.
expansion
),
)
layers
=
[]
layers
.
append
(
block
(
self
.
inplanes
,
planes
,
stride
,
downsample
,
self
.
groups
,
self
.
base_width
,
previous_dilation
,
norm_layer
))
self
.
inplanes
=
planes
*
block
.
expansion
for
_
in
range
(
1
,
blocks
):
layers
.
append
(
block
(
self
.
inplanes
,
planes
,
groups
=
self
.
groups
,
base_width
=
self
.
base_width
,
dilation
=
self
.
dilation
,
norm_layer
=
norm_layer
))
return
nn
.
Sequential
(
*
layers
)
def
forward
(
self
,
x
):
x
=
self
.
conv1
(
x
)
x
=
self
.
bn1
(
x
)
x
=
self
.
relu
(
x
)
x
=
self
.
maxpool
(
x
)
x
=
self
.
layer1
(
x
)
x
=
self
.
layer2
(
x
)
x
=
self
.
layer3
(
x
)
x
=
self
.
layer4
(
x
)
x
=
self
.
avgpool
(
x
)
x
=
torch
.
flatten
(
x
,
1
)
x
=
self
.
fc
(
x
)
return
x
\ No newline at end of file
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