187 lines
6.1 KiB
Python
187 lines
6.1 KiB
Python
import torch
|
|
from SplitOnOffLayer import SplitOnOffLayer
|
|
from append_nnmf_block import append_nnmf_block
|
|
|
|
|
|
def make_network(
|
|
use_nnmf: bool,
|
|
cnn_top: bool,
|
|
input_dim_x: int,
|
|
input_dim_y: int,
|
|
input_number_of_channel: int,
|
|
iterations: int,
|
|
epsilon: bool | None = None,
|
|
positive_function_type: int = 0,
|
|
beta: float | None = None,
|
|
# Conv:
|
|
number_of_output_channels: list[int] = [32, 64, 96, 10],
|
|
kernel_size_conv: list[tuple[int, int]] = [
|
|
(5, 5),
|
|
(5, 5),
|
|
(-1, -1), # Take the whole input image x and y size
|
|
(1, 1),
|
|
],
|
|
stride_conv: list[tuple[int, int]] = [
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
],
|
|
padding_conv: list[tuple[int, int]] = [
|
|
(0, 0),
|
|
(0, 0),
|
|
(0, 0),
|
|
(0, 0),
|
|
],
|
|
dilation_conv: list[tuple[int, int]] = [
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
],
|
|
# Pool:
|
|
kernel_size_pool: list[tuple[int, int]] = [
|
|
(2, 2),
|
|
(2, 2),
|
|
(-1, -1), # No pooling layer
|
|
(-1, -1), # No pooling layer
|
|
],
|
|
stride_pool: list[tuple[int, int]] = [
|
|
(2, 2),
|
|
(2, 2),
|
|
(-1, -1),
|
|
(-1, -1),
|
|
],
|
|
padding_pool: list[tuple[int, int]] = [
|
|
(0, 0),
|
|
(0, 0),
|
|
(0, 0),
|
|
(0, 0),
|
|
],
|
|
dilation_pool: list[tuple[int, int]] = [
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
(1, 1),
|
|
],
|
|
local_learning: list[bool] = [False, False, False, False],
|
|
skip_connection: list[bool] = [False, False, False, False],
|
|
local_learning_kl: bool = True,
|
|
use_reconstruction: bool = False,
|
|
max_pool: bool = True,
|
|
enable_onoff: bool = False,
|
|
) -> tuple[torch.nn.Sequential, list[int], list[int]]:
|
|
|
|
assert len(number_of_output_channels) == len(kernel_size_conv)
|
|
assert len(number_of_output_channels) == len(stride_conv)
|
|
assert len(number_of_output_channels) == len(padding_conv)
|
|
assert len(number_of_output_channels) == len(dilation_conv)
|
|
assert len(number_of_output_channels) == len(kernel_size_pool)
|
|
assert len(number_of_output_channels) == len(stride_pool)
|
|
assert len(number_of_output_channels) == len(padding_pool)
|
|
assert len(number_of_output_channels) == len(dilation_pool)
|
|
assert len(number_of_output_channels) == len(local_learning)
|
|
assert len(number_of_output_channels) == len(skip_connection)
|
|
|
|
if enable_onoff:
|
|
input_number_of_channel *= 2
|
|
|
|
list_cnn_top_id: list[int] = []
|
|
list_other_id: list[int] = []
|
|
|
|
test_image = torch.ones((1, input_number_of_channel, input_dim_x, input_dim_y))
|
|
|
|
network = torch.nn.Sequential()
|
|
|
|
if enable_onoff:
|
|
network.append(SplitOnOffLayer())
|
|
test_image = network[-1](test_image)
|
|
|
|
for block_id in range(0, len(number_of_output_channels)):
|
|
if use_nnmf:
|
|
test_image = append_nnmf_block(
|
|
network=network,
|
|
out_channels=number_of_output_channels[block_id],
|
|
test_image=test_image,
|
|
list_other_id=list_other_id,
|
|
dilation=dilation_conv[block_id],
|
|
padding=padding_conv[block_id],
|
|
stride=stride_conv[block_id],
|
|
kernel_size=kernel_size_conv[block_id],
|
|
epsilon=epsilon,
|
|
positive_function_type=positive_function_type,
|
|
beta=beta,
|
|
iterations=iterations,
|
|
local_learning=local_learning[block_id],
|
|
local_learning_kl=local_learning_kl,
|
|
use_reconstruction=use_reconstruction,
|
|
skip_connection=skip_connection[block_id],
|
|
)
|
|
else:
|
|
list_other_id.append(len(network))
|
|
|
|
kernel_size_conv_internal = list(kernel_size_conv[block_id])
|
|
|
|
if kernel_size_conv[block_id][0] == -1:
|
|
kernel_size_conv_internal[0] = test_image.shape[-2]
|
|
|
|
if kernel_size_conv[block_id][1] == -1:
|
|
kernel_size_conv_internal[1] = test_image.shape[-1]
|
|
|
|
network.append(
|
|
torch.nn.Conv2d(
|
|
in_channels=test_image.shape[1],
|
|
out_channels=number_of_output_channels[block_id],
|
|
kernel_size=kernel_size_conv_internal,
|
|
stride=1,
|
|
padding=0,
|
|
)
|
|
)
|
|
test_image = network[-1](test_image)
|
|
if cnn_top or block_id < len(number_of_output_channels) - 1:
|
|
network.append(torch.nn.ReLU())
|
|
test_image = network[-1](test_image)
|
|
|
|
if cnn_top:
|
|
list_cnn_top_id.append(len(network))
|
|
network.append(
|
|
torch.nn.Conv2d(
|
|
in_channels=test_image.shape[1],
|
|
out_channels=number_of_output_channels[block_id],
|
|
kernel_size=(1, 1),
|
|
stride=(1, 1),
|
|
padding=(0, 0),
|
|
bias=True,
|
|
)
|
|
)
|
|
test_image = network[-1](test_image)
|
|
if block_id < len(number_of_output_channels) - 1:
|
|
network.append(torch.nn.ReLU())
|
|
test_image = network[-1](test_image)
|
|
|
|
if (kernel_size_pool[block_id][0] > 0) and (kernel_size_pool[block_id][1] > 0):
|
|
if max_pool:
|
|
network.append(
|
|
torch.nn.MaxPool2d(
|
|
kernel_size=kernel_size_pool[block_id],
|
|
stride=stride_pool[block_id],
|
|
padding=padding_pool[block_id],
|
|
)
|
|
)
|
|
else:
|
|
network.append(
|
|
torch.nn.AvgPool2d(
|
|
kernel_size=kernel_size_pool[block_id],
|
|
stride=stride_pool[block_id],
|
|
padding=padding_pool[block_id],
|
|
)
|
|
)
|
|
test_image = network[-1](test_image)
|
|
|
|
network.append(torch.nn.Flatten())
|
|
test_image = network[-1](test_image)
|
|
|
|
network.append(torch.nn.Softmax(dim=1))
|
|
test_image = network[-1](test_image)
|
|
|
|
return network, list_cnn_top_id, list_other_id
|