class MSResNet(nn.Module):
def init(self, input_channel, layers=[1, 1, 1, 1], num_classes=10):
self.inplanes3 = 64
self.inplanes5 = 64
self.inplanes7 = 64
self.inplanes9 = 64
    super(MSResNet, self).__init__()

    self.conv1 = nn.Conv1d(input_channel, 64, kernel_size=7, stride=2, padding=3,
                           bias=False)
    self.bn1 = nn.BatchNorm1d(64)
    self.relu = nn.ReLU(inplace=True)
    self.maxpool = nn.MaxPool1d(kernel_size=3, stride=2, padding=1)

    self.layer3x3_1 = self._make_layer3(BasicBlock3x3, 64, layers[0], stride=2)
    self.layer3x3_2 = self._make_layer3(BasicBlock3x3, 128, layers[1], stride=2)
    self.layer3x3_3 = self._make_layer3(BasicBlock3x3, 256, layers[2], stride=2)
    self.layer3x3_4 = self._make_layer3(BasicBlock3x3, 512, layers[3], stride=2)
    self.layer3x3_5 = self._make_layer3(BasicBlock3x3, 1024, layers[3], stride=2)

    # maxplooing kernel size: 16, 11, 6
    self.maxpool3 = nn.AvgPool1d(kernel_size=1, stride=1, padding=0)


    self.layer5x5_1 = self._make_layer5(BasicBlock5x5, 64, layers[0], stride=2)
    self.layer5x5_2 = self._make_layer5(BasicBlock5x5, 128, layers[1], stride=2)
    self.layer5x5_3 = self._make_layer5(BasicBlock5x5, 256, layers[2], stride=2)
    self.layer5x5_4 = self._make_layer5(BasicBlock5x5, 512, layers[3], stride=2)
    self.maxpool5 = nn.AvgPool1d(kernel_size=3, stride=1, padding=0)


    self.layer7x7_1 = self._make_layer7(BasicBlock7x7, 64, layers[0], stride=2)
    self.layer7x7_2 = self._make_layer7(BasicBlock7x7, 128, layers[1], stride=2)
    self.layer7x7_3 = self._make_layer7(BasicBlock7x7, 256, layers[2], stride=2)
    self.layer7x7_4 = self._make_layer7(BasicBlock7x7, 512, layers[3], stride=2)
    self.maxpool7 = nn.AvgPool1d(kernel_size=3, stride=1, padding=0)

    self.layer9x9_1 = self._make_layer9(BasicBlock9x9, 64, layers[0], stride=2)
    self.layer9x9_2 = self._make_layer9(BasicBlock9x9, 128, layers[1], stride=2)
    self.layer9x9_3 = self._make_layer9(BasicBlock9x9, 256, layers[2], stride=2)
    self.layer9x9_4 = self._make_layer9(BasicBlock9x9, 512, layers[3], stride=2)
    self.maxpool9 = nn.AvgPool1d(kernel_size=3, stride=1, padding=0)

    # self.drop = nn.Dropout(p=0.2)
    
    self.fc = nn.Linear(4*256+1024, num_classes)
    
    # todo: modify the initialization
    # for m in self.modules():
    #     if isinstance(m, nn.Conv1d):
    #         n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
    #         m.weight.data.normal_(0, math.sqrt(2. / n))
    #     elif isinstance(m, nn.BatchNorm1d):
    #         m.weight.data.fill_(1)
    #         m.bias.data.zero_()

def _make_layer3(self, block, planes, blocks, stride=2):
    downsample = None
    if stride != 1 or self.inplanes3 != planes * block.expansion:
        downsample = nn.Sequential(
            nn.Conv1d(self.inplanes3, planes * block.expansion,
                      kernel_size=1, stride=stride, bias=False),
            nn.BatchNorm1d(planes * block.expansion),
        )

    layers = []
    layers.append(block(self.inplanes3, planes, stride, downsample))
    self.inplanes3 = planes * block.expansion
    for i in range(1, blocks):
        layers.append(block(self.inplanes3, planes))

    return nn.Sequential(*layers)

def _make_layer5(self, block, planes, blocks, stride=2):
    downsample = None
    if stride != 1 or self.inplanes5 != planes * block.expansion:
        downsample = nn.Sequential(
            nn.Conv1d(self.inplanes5, planes * block.expansion,
                      kernel_size=1, stride=stride, bias=False),
            nn.BatchNorm1d(planes * block.expansion),
        )

    layers = []
    layers.append(block(self.inplanes5, planes, stride, downsample))
    self.inplanes5 = planes * block.expansion
    for i in range(1, blocks):
        layers.append(block(self.inplanes5, planes))

    return nn.Sequential(*layers)


def _make_layer7(self, block, planes, blocks, stride=2):
    downsample = None
    if stride != 1 or self.inplanes7 != planes * block.expansion:
        downsample = nn.Sequential(
            nn.Conv1d(self.inplanes7, planes * block.expansion,
                      kernel_size=1, stride=stride, bias=False),
            nn.BatchNorm1d(planes * block.expansion),
        )

    layers = []
    layers.append(block(self.inplanes7, planes, stride, downsample))
    self.inplanes7 = planes * block.expansion
    for i in range(1, blocks):
        layers.append(block(self.inplanes7, planes))

    return nn.Sequential(*layers)

def _make_layer9(self, block, planes, blocks, stride=2):
    downsample = None
    if stride != 1 or self.inplanes9 != planes * block.expansion:
        downsample = nn.Sequential(
            nn.Conv1d(self.inplanes9, planes * block.expansion,
                      kernel_size=1, stride=stride, bias=False),
            nn.BatchNorm1d(planes * block.expansion),
        )

    layers = []
    layers.append(block(self.inplanes9, planes, stride, downsample))
    self.inplanes9 = planes * block.expansion
    for i in range(1, blocks):
        layers.append(block(self.inplanes9, planes))

    return nn.Sequential(*layers)