| 185 | |
| 186 | # Model |
| 187 | class NeRF(nn.Module): |
| 188 | def __init__(self, D=8, W=256, input_ch=3, input_ch_views=3, output_ch=4, skips=[4], use_viewdirs=False): |
| 189 | """ |
| 190 | """ |
| 191 | super(NeRF, self).__init__() |
| 192 | self.D = D |
| 193 | self.W = W |
| 194 | self.input_ch = input_ch |
| 195 | self.input_ch_views = input_ch_views |
| 196 | self.skips = skips |
| 197 | self.use_viewdirs = use_viewdirs |
| 198 | |
| 199 | self.pts_linears = nn.ModuleList( |
| 200 | [nn.Linear(input_ch, W)] + [nn.Linear(W, W) if i not in self.skips else nn.Linear(W + input_ch, W) for i in range(D-1)]) |
| 201 | |
| 202 | ### Implementation according to the official code release (https://github.com/bmild/nerf/blob/master/run_nerf_helpers.py#L104-L105) |
| 203 | self.views_linears = nn.ModuleList([nn.Linear(input_ch_views + W, W//2)]) |
| 204 | |
| 205 | ### Implementation according to the NeRF paper |
| 206 | # self.views_linears = nn.ModuleList( |
| 207 | # [nn.Linear(input_ch_views + W, W//2)] + [nn.Linear(W//2, W//2) for i in range(D//2)]) |
| 208 | |
| 209 | if use_viewdirs: |
| 210 | self.feature_linear = nn.Linear(W, W) |
| 211 | self.alpha_linear = nn.Linear(W, 1) |
| 212 | self.rgb_linear = nn.Linear(W//2, 3) |
| 213 | else: |
| 214 | self.output_linear = nn.Linear(W, output_ch) |
| 215 | |
| 216 | def forward(self, x): |
| 217 | input_pts, input_views = torch.split(x, [self.input_ch, self.input_ch_views], dim=-1) |
| 218 | h = input_pts |
| 219 | for i, l in enumerate(self.pts_linears): |
| 220 | h = self.pts_linears[i](h) |
| 221 | h = F.relu(h) |
| 222 | if i in self.skips: |
| 223 | h = torch.cat([input_pts, h], -1) |
| 224 | |
| 225 | if self.use_viewdirs: |
| 226 | alpha = self.alpha_linear(h) |
| 227 | feature = self.feature_linear(h) |
| 228 | h = torch.cat([feature, input_views], -1) |
| 229 | |
| 230 | for i, l in enumerate(self.views_linears): |
| 231 | h = self.views_linears[i](h) |
| 232 | h = F.relu(h) |
| 233 | |
| 234 | rgb = self.rgb_linear(h) |
| 235 | outputs = torch.cat([rgb, alpha], -1) |
| 236 | else: |
| 237 | outputs = self.output_linear(h) |
| 238 | |
| 239 | return outputs |
| 240 | |
| 241 | def load_weights_from_keras(self, weights): |
| 242 | assert self.use_viewdirs, "Not implemented if use_viewdirs=False" |
| 243 | |
| 244 | # Load pts_linears |
no outgoing calls
no test coverage detected