Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将keras模型架构转换为Pytorch_Keras_Pytorch - Fatal编程技术网

将keras模型架构转换为Pytorch

将keras模型架构转换为Pytorch,keras,pytorch,Keras,Pytorch,我正在尝试将keras模型转换为pytorch,用于人类活动识别。keras模型可以达到98%的精度,而Pytorch模型只能达到约60%的精度。我想不出这个问题,首先我想到了keras的填充class='same',但我已经调整了pytorch的填充。你能检查一下有什么问题吗 keras代码如上所述 model = keras.Sequential() model.add(layers.Input(shape=[100,12])) model.add(layers.Conv1D(filters

我正在尝试将keras模型转换为pytorch,用于人类活动识别。keras模型可以达到98%的精度,而Pytorch模型只能达到约60%的精度。我想不出这个问题,首先我想到了keras的填充class='same',但我已经调整了pytorch的填充。你能检查一下有什么问题吗

keras代码如上所述

model = keras.Sequential()
model.add(layers.Input(shape=[100,12]))
model.add(layers.Conv1D(filters=32, kernel_size=3, padding="same"))
model.add(layers.BatchNormalization())
model.add(layers.ReLU())
model.add(layers.Conv1D(filters=64, kernel_size=3, padding="same"))
model.add(layers.BatchNormalization())
model.add(layers.ReLU())
model.add(layers.MaxPool1D(2))
model.add(layers.LSTM(64))
model.add(layers.Dense(units=128, activation='relu'))
model.add(layers.Dense(13, activation='softmax'))
model.summary()
我的pytorch模型代码如下

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        seq_len = 100
        # output: [, 32, 100]
        self.conv1 = nn.Conv1d(seq_len, 32, kernel_size=3, stride=1, padding=1)
        self.bn1 = nn.BatchNorm1d(32)
        # output: [, 64, 100]
        self.conv2 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm1d(64)
        # output: [, 64, 50]
        self.mp = nn.MaxPool1d(kernel_size=2, stride=2)
        # output: [, 64]
        self.lstm = nn.LSTM(6, 64, 1)
        # output: [, 128]
        self.fc1 = nn.Linear(64, 128)
        # output: [, 13]
        self.fc2 = nn.Linear(128, 13)
        
    def forward(self, x):
        x = self.conv1(x) 
        x = self.bn1(x)
        x = F.relu(x)

        x = self.conv2(x)
        x = self.bn2(x)
        x = F.relu(x)
        x = self.mp(x)
        
        out, _ = self.lstm(x)
        x = out[:, -1, :]
        
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        
        return x

因为它太长了,无法写在评论中,所以我在用你提到的随机张量(torch.randn(1100,12)(NCH格式)测试PyTorch架构的形状后,将它写在了答案中

这就是结果:

input= torch.Size([1, 100, 12])
1st Conv= torch.Size([1, 32, 12])
1st batchNorm= torch.Size([1, 32, 12])
1st relu= torch.Size([1, 32, 12])
2nd Conv= torch.Size([1, 64, 12])
2nd batchnorm= torch.Size([1, 64, 12])
2nd relu= torch.Size([1, 64, 12])
1st maxPool= torch.Size([1, 64, 6])
LSTM= torch.Size([1, 64])
1st FC= torch.Size([1, 128])
3rd relu= torch.Size([1, 128])
2nd FC= torch.Size([1, 13])
这是您的网络正在接收的100个频道,正如您在Keras中第一次卷积后的评论中提到的,它是[batch_size,100,32],但在torch中它正在更改为[batch_size,32,12]

更改为:

def __init__(self):
        super(CNN, self).__init__()
        in_channels = 12
        # output: [, 32, 100]
        self.conv1 = nn.Conv1d(in_channels, 32, kernel_size=3, stride=1, padding=1)
        self.bn1 = nn.BatchNorm1d(32)
        # output: [, 64, 100]
        self.conv2 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm1d(64)
        # output: [, 64, 50]
        self.mp = nn.MaxPool1d(kernel_size=2, stride=2)
        # output: [, 64]
        self.lstm = nn.LSTM(50, 64, 1)
        # output: [, 128]
        self.fc1 = nn.Linear(64, 128)
        # output: [, 13]
        self.fc2 = nn.Linear(128, 13)
        self.softmax = nn.Softmax()
这方面的输出将是:

input= torch.Size([1, 12, 100])
1st Conv= torch.Size([1, 32, 100])
1st batchNorm= torch.Size([1, 32, 100])
1st relu= torch.Size([1, 32, 100])
2nd Conv= torch.Size([1, 64, 100])
2nd batchnorm= torch.Size([1, 64, 100])
2nd relu= torch.Size([1, 64, 100])
1st maxPool= torch.Size([1, 64, 50])
LSTM= torch.Size([1, 64])
1st FC= torch.Size([1, 128])
3rd relu= torch.Size([1, 128])
2nd FC= torch.Size([1, 13])

图像的输入大小是多少?输入是一个大小序列[batch_size,100,12],其中100是序列长度,12是特征。我发现了一个错误,第一个Conv的padding=1表示padding=“same”。但性能仍然很差。我刚刚编辑了代码。@KnowledgeGainer抱歉,在前面的评论中没有通知您。这也可能是您培训模型的方式。例如,如何调整损耗等。第一次转换将保持序列长度不变,因此输出将为[1,32,100],然后在maxPool中,它将汇集到[1,64,50]。@IveXu是的,但在torch中,相同的事情不会发生。原因是在torchConv1()中,您接受的是100个通道而不是12个通道,这就是为什么在conv后的输出中,100个通道更改为32个,但12个通道保持不变,因为这是根据当前torch网络的序列长度。在这种情况下,100个通道是序列长度,因为kernel_size=3,padding=1,然后序列长度将保留为100,并且有32个输出通道,因此它将是[1,32,100]。@IveXu检查编辑的答案和它的输出,它是working@No,我认为in_通道应该是100,这是序列长度。与Conv2d一样,in通道是图像的通道,对于黑白图像为1,对于RGB图像为3。每个通道的输入大小实际上并不重要。