WedX - журнал о программировании и компьютерных науках

Может ли кто-нибудь помочь мне понять, почему мое преобразование keras в pytorch не работает?

Я пытаюсь перейти с keras на pytorch и получаю противоречивое поведение. Прежде всего, я замечаю, что у меня другое количество параметров, но я также замечаю, что обучение keras сходится намного быстрее и плавнее, чем pytorch. Я сделал что-то не так? Кто-нибудь может помочь? Соответствующий код ниже.

У меня есть следующая простая архитектура в keras:

def identity_block(input_tensor, units):
   x = layers.Dense(units, kernel_regularizer=reg)(input_tensor)
   x = layers.BatchNormalization()(x)
   x = layers.Activation('relu')(x)

   x = layers.Dense(units, kernel_regularizer=reg)(x)
   x = layers.BatchNormalization()(x)
   x = layers.Activation('relu')(x)

   x = layers.Dense(units, kernel_regularizer=reg)(x)
   x = layers.BatchNormalization()(x)
   x = layers.add([x, input_tensor])
   x = layers.Activation('relu')(x)
   return x


def dens_block(input_tensor, units, reps=2):
    x = input_tensor

    for _ in range(reps):
        x = layers.Dense(units, kernel_regularizer=reg)(x)
        x = layers.BatchNormalization()(x)
        x = layers.Activation('relu')(x)

    x = layers.Dense(units, kernel_regularizer=reg)(x)
    x = layers.BatchNormalization()(x)
    shortcut = layers.Dense(units, kernel_regularizer=reg)(input_tensor)
    shortcut = layers.BatchNormalization()(shortcut)
    x = layers.add([x, shortcut])
    x = layers.Activation('relu')(x)
    return x

def resnet_block(input_tensor, width=16):
    x = dens_block(input_tensor, width)
    x = identity_block(x, width)
    x = identity_block(x, width)
    return x

def RegResNet(input_size=8, reps=3, initial_weights=None, width=16, num_gpus=0, lr=1e-4):
    input_layer = layers.Input(shape=(input_size,))
    x = input_layer
    for _ in range(reps):
        x = resnet_block(x, width)

    x = layers.BatchNormalization()(x)
    x = layers.Dense(1, activation=None)(x)

    model = models.Model(inputs=input_layer, outputs=x)
    return model

Что дает сводку, которую я не смог уместить, и следующий подсчет параметров.

==================================================================================================
Total params: 9,905
Trainable params: 8,913
Non-trainable params: 992
==================================================================================================

Ниже приведен мой pytorch-перевод той же архитектуры:

class _DenseBlock(nn.Module):
        def __init__(self, input_size, output_size):
            super(_DenseBlock, self).__init__()
            self.input_size = input_size
            self.output_size = output_size
            self.linear = nn.Linear(self.input_size, self.output_size)
            self.bnorm = nn.BatchNorm1d(self.output_size)

    def forward(self, x):
        x = self.linear(x)
        x = self.bnorm(x)
        x = nn.ReLU()(x)
        return x

class DenseBlock(nn.Module):
    def __init__(self, input_size, output_size, repetitions=2):
        super(DenseBlock, self).__init__()
        self.input_size = input_size
        self.output_size = output_size
        self.repetitions = repetitions
        self.dense_blocks = nn.ModuleList([_DenseBlock(self.input_size, self.output_size)]
                      + [_DenseBlock(self.output_size, self.output_size)
                         for _ in range(self.repetitions - 1)])
        self.b_norm1 = nn.BatchNorm1d(self.output_size)
        self.b_norm2 = nn.BatchNorm1d(self.output_size)
        self.linear_1 = nn.Linear(self.output_size, self.output_size)
        self.linear_2 = nn.Linear(self.input_size, self.output_size)



    def forward(self, x):
        identity = x
        
        for l in self.dense_blocks:
            x = l(x)

        x = self.linear_1(x)
        x = self.b_norm1(x)

        shortcut = self.linear_2(identity)
        shortcut = self.b_norm2(shortcut)

        x = shortcut + x
        x = nn.ReLU()(x)
        return x

class IdentityBlock(nn.Module):
    def __init__(self, input_size, output_size):
        super(IdentityBlock, self).__init__()
        self.input_size = input_size
        self.output_size = output_size
        self.linear_1 = nn.Linear(self.input_size, self.output_size)
        self.linear_2 = nn.Linear(self.input_size, self.output_size)
        self.linear_3 = nn.Linear(self.input_size, self.output_size)
        self.bnorm_1 = nn.BatchNorm1d(self.input_size)
        self.bnorm_2 = nn.BatchNorm1d(self.output_size)
        self.bnorm_3 = nn.BatchNorm1d(self.output_size)

    def forward(self, x):
        input_tensor = x
        x = self.linear_1(x)
        x = self.bnorm_1(x)
        x = nn.ReLU()(x)

        x = self.linear_2(x)
        x = self.bnorm_2(x)
        x = nn.ReLU()(x)

        x = self.linear_3(x)
        x = self.bnorm_3(x)
        x = x + input_tensor
        x = nn.ReLU()(x)
        return x

class ResnetBlock(nn.Module):
    def __init__(self, input_size, output_size):
        super(ResnetBlock, self).__init__()
        self.input_size = input_size
        self.output_size = output_size
        self.dense_block = DenseBlock(self.input_size, self.output_size)
        self.identity_block_1 = IdentityBlock(self.output_size, self.output_size)
        self.identity_block_2 = IdentityBlock(self.output_size, self.output_size)

    def forward(self, x):
        x = self.dense_block(x)
        x = self.identity_block_1(x)
        x = self.identity_block_2(x)
        return x

class RegResNet(nn.Module):

    def __init__(self, input_size, block_width, repititions=3):
        super(RegResNet, self).__init__()
        self.input_size = input_size
        self.repititions = repititions
        self.block_width = block_width
        self.resnet_blocks = nn.ModuleList([ResnetBlock(self.input_size, self.block_width)]
                                           + [ResnetBlock(self.block_width, self.block_width)
                                              for _ in range(self.repititions - 1)])
        self.bnorm = nn.BatchNorm1d(self.block_width)
        self.out = nn.Linear(self.block_width, 1)

    def forward(self, x):
        for layer in self.resnet_blocks:
            x = layer(x)

        x = self.bnorm(x)
        x = self.out(x)
        return x

Используя библиотеку torchsummary, я получил сводку (которая мне не подошла) и следующий счетчик параметров

================================================================
    Total params: 8,913
    Trainable params: 8,913
    Non-trainable params: 0
================================================================
06.08.2020

  • что здесь важно, так это обучаемых параметров нет? и у вас есть такое же количество обучаемых параметров 06.08.2020
  • Ух ты! Спасибо, не могу поверить, что пропустил это! Знаете ли вы, как определяется, какие параметры обучаемы? Это надежный показатель того, что я построил модель правильно, верно? 06.08.2020
  • Я больше похожа на pytorch, но я думаю, что разница здесь может быть связана со слоем пакетной нормализации. в pytorch по умолчанию параметры доступны для изучения, если вы не используете affine=False. Я думаю, что это другой случай в Керасе. возможно, это поможет: stackoverflow.com/questions/47312219/. 06.08.2020
  • Спасибо, я проверю. Я вношу изменения, Керас мертв, и мне надоело бороться за контроль над моими тренировочными циклами. 06.08.2020

Новые материалы

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

ИИ в аэрокосмической отрасли
Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


Для любых предложений по сайту: [email protected]