forked from nyukat/BIRADS_classifier
-
Notifications
You must be signed in to change notification settings - Fork 0
/
layers_torch.py
110 lines (86 loc) · 3.29 KB
/
layers_torch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import torch
import torch.nn as nn
import torch.nn.functional as F
class AllViewsGaussianNoise(nn.Module):
"""Add gaussian noise across all 4 views"""
def __init__(self, gaussian_noise_std, device):
super(AllViewsGaussianNoise, self).__init__()
self.gaussian_noise_std = gaussian_noise_std
self.device = device
def forward(self, x):
if not self.gaussian_noise_std:
return x
return {
"L-CC": self._add_gaussian_noise(x["L-CC"]),
"L-MLO": self._add_gaussian_noise(x["L-MLO"]),
"R-CC": self._add_gaussian_noise(x["R-CC"]),
"R-MLO": self._add_gaussian_noise(x["R-MLO"]),
}
def _add_gaussian_noise(self, single_view):
return single_view + torch.Tensor(*single_view.shape).normal_(std=self.gaussian_noise_std).to(self.device)
class AllViewsConvLayer(nn.Module):
"""Convolutional layers across all 4 views"""
def __init__(self, in_channels, number_of_filters=32, filter_size=(3, 3), stride=(1, 1)):
super(AllViewsConvLayer, self).__init__()
self.cc = nn.Conv2d(
in_channels=in_channels,
out_channels=number_of_filters,
kernel_size=filter_size,
stride=stride,
)
self.mlo = nn.Conv2d(
in_channels=in_channels,
out_channels=number_of_filters,
kernel_size=filter_size,
stride=stride,
)
def forward(self, x):
return {
"L-CC": F.relu(self.cc(x["L-CC"])),
"L-MLO": F.relu(self.mlo(x["L-MLO"])),
"R-CC": F.relu(self.cc(x["R-CC"])),
"R-MLO": F.relu(self.mlo(x["R-MLO"])),
}
@property
def ops(self):
return {
"CC": self.cc,
"MLO": self.mlo,
}
class AllViewsMaxPool(nn.Module):
"""Max-pool across all 4 views"""
def __init__(self):
super(AllViewsMaxPool, self).__init__()
def forward(self, x, stride=(2, 2), padding=(0, 0)):
return {
"L-CC": F.max_pool2d(x["L-CC"], kernel_size=stride, stride=stride, padding=padding),
"L-MLO": F.max_pool2d(x["L-MLO"], kernel_size=stride, stride=stride, padding=padding),
"R-CC": F.max_pool2d(x["R-CC"], kernel_size=stride, stride=stride, padding=padding),
"R-MLO": F.max_pool2d(x["R-MLO"], kernel_size=stride, stride=stride, padding=padding),
}
class AllViewsAvgPool(nn.Module):
"""Average-pool across all 4 views"""
def __init__(self):
super(AllViewsAvgPool, self).__init__()
def forward(self, x):
return {
"L-CC": self._avg_pool(x["L-CC"]),
"L-MLO": self._avg_pool(x["L-MLO"]),
"R-CC": self._avg_pool(x["R-CC"]),
"R-MLO": self._avg_pool(x["R-MLO"]),
}
@staticmethod
def _avg_pool(single_view):
n, c, h, w = single_view.size()
return single_view.view(n, c, -1).mean(-1)
class AllViewsPad(nn.Module):
"""Pad tensor across all 4 views"""
def __init__(self):
super(AllViewsPad, self).__init__()
def forward(self, x, pad):
return {
"L-CC": F.pad(x["L-CC"], pad),
"L-MLO": F.pad(x["L-MLO"], pad),
"R-CC": F.pad(x["R-CC"], pad),
"R-MLO": F.pad(x["R-MLO"], pad),
}