Как преобразовать мультиклассовые данные в двоичный класс в Python для классификации изображений? - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь выполнить классификацию изображений двоичного класса с помощью PyTorch. У меня есть CSV-файл, в котором хранятся мои классы набора данных ( V00XRKL ). Набор данных имеет пять классов, но я хотел бы преобразовать его в двоичный класс, используя условие типа , если V00XRKL <2 </em>, тогда Class = 1 , в противном случае Класс = 2 . Вот пример моего набора данных enter image description here.

Для этой цели я написал свой код следующим образом

# read the csv file

classfile = pd.read_csv(csvroot)
print('df length orig:', len(classfile))

# remove the NA value from the file
df_NA = classfile.dropna(how='any', axis=0)
print('df length no NA:', len(df_NA))

# Dropout the duplicates of number from ID and Side
df_drop = df_NA.drop_duplicates(subset=['ID', 'SIDE'])
print('df length no dup:', len(df_drop))

# reset the index
df_in = df_drop.reset_index(drop=True)
df_in.loc[df_in['V00XRKL'] < 2, 'V00XRKL'] = 1
df_in.loc[df_in['V00XRKL'] >= 2, 'V00XRKL'] = 2
#df_in.to_clipboard(sep=',')

После запуска этого кода я увидел, что мой кодданные преобразованы в двоичный класс, вот скриншот преобразованных данных enter image description here.

Но проблема в том, что всякий раз, когда я пытаюсь обучить свою модель cnn, я получаю эти сообщения об ошибках.

Traceback (most recent call last):
  File "/home/Downloads/test to con.py", line 379, in <module>
    model, train_loss, valid_loss,val_acc = train_model(net,  patience, n_epochs,costFunction)
  File "/home/Downloads/test to con.py", line 165, in train_model
    loss = criterion(output, labels)
  File "/home/miniconda3/lib/python3.6/site-packages/torch/nn/modules/module.py", line 493, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/miniconda3/lib/python3.6/site-packages/torch/nn/modules/loss.py", line 942, in forward
    ignore_index=self.ignore_index, reduction=self.reduction)
  File "/home/miniconda3/lib/python3.6/site-packages/torch/nn/functional.py", line 2056, in cross_entropy
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
  File "/home/miniconda3/lib/python3.6/site-packages/torch/nn/functional.py", line 1871, in nll_loss
    ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
RuntimeError: Assertion `cur_target >= 0 && cur_target < n_classes' failed.  at /opt/conda/conda-bld/pytorch_1556653099582/work/aten/src/THNN/generic/ClassNLLCriterion.c:92

Вот мой код, который я использовал для создания класса набора данных

#make a class for data
class MyDataset(Dataset):
    def __init__(self, csv_file,root_dir, transform=None):
       # self.data = pd.read_csv(csv_file, header=None)
       self.df_data= csv_file
       self.root_dir = root_dir


       self.transform = transform


    def __len__(self):
       return len(self.df_data)

    def __getitem__(self,idx):
        img_name = os.path.join(self.root_dir, str(self.df_data['ID'].iloc[idx])+'.npy')

        patches, p_id = np.load(img_name, allow_pickle= True)


        img_class = int(self.df_data.iloc[idx,2])

        side = self.df_data.iloc[idx,1]


        if side ==1:
            image = Image.fromarray(patches['R'].astype('uint8'), 'L')                                              #[image['R':side]|image['L':side]]
        else:
            image = Image.fromarray(patches['L'].astype('uint8'), 'L')

        if self.transform is not None:
             image = self.transform(image)

        sample = {'image': image, 'grade':img_class}

        return sample

А это модель CNN

class ConvNet(nn.Module):
    def __init__(self):
            super(ConvNet, self).__init__()
          # Convolution 1
            self.layer1 = nn.Sequential(
                nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=2),
                nn.BatchNorm2d(32),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=2, stride=2)) # maxpolling layer 1
          # Convolution 1
            self.layer2 = nn.Sequential(
                nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
                nn.BatchNorm2d(64),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=2, stride=2))
            self.drop_out = nn.Dropout(0.2)
          # Fully connected
            self.fc1 = nn.Linear(16 * 16 * 64, 1000)
            self.fc2 = nn.Linear(1000,2)

    def forward(self, x):
           out = self.layer1(x)
           out = self.layer2(out)
           out = out.reshape(out.size(0), -1)
           #print(out.shape)
           out = self.drop_out(out)
           out = self.fc1(out)
           out = self.fc2(out)
           return out

Буду признателен за любой видпомощи в этом отношении.

...