在编辑神经网络的时候出现这样的问题,记录自己的一个问题:
这个问题一般出现在损失函数上面, torch.nn提供很多损失函数MSELoss,L1Loss,CrossEnropyLoss,BCELoss,BCEWithLogitsLoss等。这些是比较常用的,其中MSELoss、L1Loss、CrossEntropyLoss、BCELoss一般用于2分类,这些分类一般在下列使用形式的时候:
loss=nn.MSELoss().cuda()
criterion=loss(output,target)
这个target是可以理解为是个0-1分布(像是【0,1,0,1,0,0,…】),不管是你转化的还是函数帮你自动转化的,你的target.shape一般是(datasize,)或是(1,datasize)这就是错误里面说的 0D和1D。
解决方法:
1.如果你是二分类的话,你可以对自己的label转化为上面说的0-1分布。这里给个例子。
#二分类
def one_hot(target):
#target is a list
#我们设第一个label为0标签,这个取决于你,你可以自己设定一个labelname
temp=target[0]
label=[]
for i in range(len(target)):
if target[i]==temp:
label.append(0)
else:
label.append(1)
return label
2.如果你的是多分类(or多标签2分类),你可以将你的损失函数改为BCEWithLogitsLoss ||nn.MultiMarginLoss ||nn.MultilabelMarginLoss
具体用法可以参考
这里不做loss函数的使用讨论。
这里仅说我遇到的问题:
target size (torch.size([16, 1])) must be the same as input size (torch.size([16, 183]))
你有可能遇到类似上面的报错,还是你的label处理的问题,一般只要你处理成0-1分布就不会有问题(当然有的希望做到一些浓度分析的请根据你自己的方式来设定label)。
解决方法:
1.你已经分类好label了,可能需要自己使用torch.reshape()来调节你的shape
2.如果根本是label分类的问题,这里给出一个例子:
import re
#我用的是一个混合物的数据集
#name_list是你的labelname。numclass是你要分几类
def labelize(name_list,num_class=182):
#因为我这里的name_list前面182个就是我的类别names(单质)
label=[]
for i in range(len(name_list)):
temp=np.zeros(num_class)
if i<num_class:
temp[i]=1
label.append(temp)
else:
#extract label
#这里是我的其他类别名字是类似'[1,100,143]',其中1是代表属于第一类,100属于100类,142属于142类,然后我用re将其从str提取出来,你可以根据你的label名字改变,或者类似我一样先重命名再labelize。
result=name_list[i][1:-1]
result=re.split(',',result)
result=[int(i) for i in result]
#multi_label onehot
temp=np.zeros(num_class)
for k in result:
temp[k]=1
label.append(temp)
return label
结果应该类似下面:
label=[(1,0,0,0,...),
(0,1,0,0,...),
...,
(0,1,0,1,0,0,1,...)]
#label.shape应该是(dataseize,182)
3.如果你坚持使用自己的label还不想改动,或是不想用方便的方法。想自己写一个loss解决,也可以。
使用variable重写的
硬核一些的重写
这里补充一个Loss的参考,需要什么loss直接找名字就好了,需要如何改动也可以按照里面的重载
以上引用若原作者禁止转载,请留言我删除。
除此之外,转载请标明出处。