深度学习——(5)数据不平衡之class_weight
在对图像或者其他数据进行分类的过程中,当每个类别中的样本数量不相等甚至相差很大的时候——出现数据不平衡的状况,这种状况会使得model在训练过程中一个batch中取到的样本都属于同一类别,同一类别样本学习到的特征都是相等的,造成在训练集上的loss值很低,但是在验证集上准确率不高的状况。
可以在计算loss值的时候加class_weight,具体过程如下:
from sklearn.utils.class_weight import compute_class_weight
import numpy as np
classes=[190,90,121,57,28]
label = np.zeros(train_num)
for i in range(classes[0]):
label[i]=0
for i in range(classes[1]):
label[classes[0]+i]=1
for i in range(classes[2]):
label[classes[0]+classes[1]+i]=2
for i in range(classes[3]):
label[classes[0]+classes[1]+classes[2]+i]=3
for i in range(classes[4]):
label[classes[0]+classes[1]+classes[2]+classes[3]+i]=4
class_weights=compute_class_weight('balanced',np.unique(label),label)
class_weights=torch.tensor(class_weights,dtype=torch.float) # 数据不平衡,在loss计算过程中使用class_weight,给每一类一个权重
loss_function = nn.CrossEntropyLoss(class_weights)
之后计算loss即可,以上代码在CPU上运行是没有问题的,但是放在GPU上跑会报错,如下:
RuntimeError: Expected object of device type cuda but got device type cpu for argument #3 'weight' in call to _thnn_nll_loss_forward
查了查错误原因是因为在cpu上跑,device直接是cpu,直接用tensor就行。但是在GPU上运行一定要将loss中的参数class_weight加载到cuda。
解决方案
在原数据后面加.to(device)
,例如:
loss_function = nn.CrossEntropyLoss(class_weights.to(device))
886,让自己养成随手记录的好习惯~