pytorch二分类的程序解释

torch.max(F.softmax(out, dim=1), 1)[1]

方括号里面的如果是1,输出的就是1和0的矩阵。如果是0,输出的就是概率的矩阵。
中间那个1是max函数索引的维度0/1,0是每列的最大值,1是每行的最大值。
左边那个1,是说,按行进行归一化。

loss_func = torch.nn.CrossEntropyLoss()
loss = loss_func(out, y)

这里的out和y并不是同一个shape的。y是标签值,是单列的布尔矩阵,但是注意这个shape是[32423423]这样的,而不是[32423423,1]。 out是多列的,有几列取决于你最后一层的神经元个数。理解见此文章。所以说,给他的out就是网络最后输出的几个值的矩阵,y相当于是类别,他这里有两步计算,一个是LogSoftmax,一个是NLLLoss。也就是说在定义网络时,最后一层要写class数目的神经元,之后在训练时for循环里面拿输出出来求loss。如果要求正确率,就在后面用prediction = torch.max(F.softmax(out, dim=1), 1)[1]获得预测的class,再通过判断求正确率。

解释一下我的模型

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()#先是继承一下nn.module
        self.linear_relu_stack = nn.Sequential(
            nn.Conv1d(in_channels=1,out_channels=10,kernel_size=3,padding=1),
            # 这个conv1d实际上就是先看输入的维度,很明显,
            #这里的时域的信息只有一种,所以in_channels=1,
            #然后我希望他能提取出多个维度的信息,所以我给了out_channels=10
            #所以会得到一个470806*10*480的tensor,470806是我的数据的行数,480是我的数据的列数。
            #卷积核的大小先给了个3看看效果,如果想让输出的还是480,就要padding=1.
            nn.BatchNorm1d(10),#这个函数意思是纠正数据分布,里面的数字是数据的维度,因为我上面卷积把维度提高到了10,所以这里面应该是10.
            nn.Linear(480, 100),#注意这里,前面的480,是和维度无关的,也就是说不管卷积提取了多少维,都只和每个维度上的数据有关,也就是和之前的数据长度,卷积核大小和填白大小有关。
            nn.ReLU(),
            nn.Conv1d(in_channels=10,out_channels=1,kernel_size=3,padding=1),
            #可能是提高维度后参数数模大大增加了,所以我在让他经过一个线性层后变成了1个维度,这样减少计算量。
            nn.Linear(100, 10),
            nn.BatchNorm1d(1),
            nn.ReLU(),
            nn.Linear(10, 2)#因为是2分类问题,所以输出是两个神经元。
        )

    def forward(self, x):
        logits = self.linear_relu_stack(x)
#         print(logits.shape)
        logits=logits.reshape([logits.shape[0],logits.shape[2]])
        #这里输出不知道为什么是三维的,所以我把他变成两维的。
        return logits

    

然后我直接打开GPU进行运算,发现几十G,运行不了,想起来应该是要我手动再做batchsize。

然后得到了结果后。我发现这个1的标签和0的标签的比例相差太大了,1的比例占到了95%。所以,需要改loss,不能直接用crossentropy了,需要拆开来做。
还有就是训练和测试时,要进行模式切换,也就是在训练前加上model.train() 测试前加model.eval() 。
在测试时,还要注意,因为我们现在的数据是在GPU的tensor,所以要先把数据搬运到CPU上,再把tensor变成numpy数组,就像这样

pred_y = prediction.cpu().numpy()
target_y = test_label.cpu().numpy()

反正,我是觉得这个pytorch比TensorFlow麻烦多了。。。
今天先写这么多,明天继续。
还需解决的问题是
1、训练速度较慢,不知道是不是没有开启平行训练还是什么情况。
2、标签占比相差太大的问题,需要把loss的weight调一下。
3、模型的逻辑问题,我认为30ms的信号,如果不给足够的前文,人类也不一定能分辨出是否有语音,所以可能后续需要用到LSTM。这个可能需要较久了。
2021年7月25日21:29:51

开启平行训练,有两种方式,一种是分布式训练,一种是并行训练。前者是

model = torch.nn.parallel.DistributedDataParallel(model,
device_ids=[arg.local_rank],
output_device=arg.local_rank)

我没有用这个`。我用的是dataparallel

device = torch.device("cuda:{}".format(0) if torch.cuda.is_available() else "cpu")
net = NeuralNetwork()
net = nn.DataParallel(net, device_ids=[0,1,2,3])
net=net.to(device)

现在就可以了。还有一个坑,就是如果你训练代码中有任何的tensor没有放到GPU上,比如损失函数中的权重。这都会造成他用上CPU,导致用上两个设备而报错。具体可以参考此文
但是我发现dataparallel在我这个服务器用不了,实际上没有给其他的卡分配任务,就那个主卡在工作。。。还是得看分布式的,这篇文章
明天看下别人的代码
https://blog.csdn.net/lqfarmer/article/details/109101549
2021年7月27日23:51:11

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朝不闻道,夕不可死

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值