构建具有基本事实的非图像分类器
Posted
技术标签:
【中文标题】构建具有基本事实的非图像分类器【英文标题】:Building a non-image classifier with ground truths 【发布时间】:2021-10-12 23:16:39 【问题描述】:我有一个如下所示的数据集:
标签基本上是给我的项目列表(比如说,停车场里的汽车),总共有 10 个,标签从 0 到 10。我有 14 个类(比如说,14 个不同的汽车品牌)。每个浮点值只是特定项目所属类别的百分比。例如,项目 2 可能是 2 类,概率为 0.995275:
print(set(list(df['label'])))
> 0, 1, 2, 3, 4, 5, 6, 7, 9
我的目标是训练一个分类器输出一个从 0 到 14 的整数来预测 x 属于哪个类标签。
我正在尝试构建一个具有 3 个隐藏层(+ 输入和输出层)的前馈 NN,并接受 15 个输入并输出从 0 到 14 的预测。这是我迄今为止设计的:
class NNO(nn.Module):
def __init__(self):
super(NNO, self).__init__()
h= [2,1]
self.hidden = nn.Linear(h[0], h[1])
self.hidden = nn.Linear(2,20)
self.hidden = nn.Linear(20,20)
self.output = nn.Linear(20,15)
self.sigmoid = nn.Sigmoid()
self.softmax = nn.Softmax(dim = 1)
def forward(self, y):
x = self.hidden(x)
x = self.sigmoid(x)
x = self.output(x)
x = self.softmax(x)
我的问题是这样的。如何将数据集提供给我的 NN 以开始训练 epoch?我找不到与此类数据集相关的任何资源。
【问题讨论】:
?????????你确定你在问什么?据我所知,标签和班级编号之间存在巨大的相关性。 是的。这只是我正在使用的虚拟数据。它不是真实的,因为我无法在互联网上发布真实数据。真实数据具有完全相同的形状,具有更多真实条目。 所以基本上你只有一个输入和多个输出? 假设您在我的数据中发现的相关性根本不存在。 我的问题:如何将这些数据提供给我构建的 NN? 【参考方案1】:答案如下:
# First I create some dummy data
label = np.random.randint(0, 14, 1000)
random = np.random.random((1000, 14))
total = pd.DataFrame(data=random, columns=[f'i_col' for i in range(14)])
total['label'] = label
'''
From what I understood you need 1 class in output that has the highest probability and hence this is a multi-class classification problem. In my case, I will just use the highest value from `random` as the target class.
'''
class TDataset(torch.utils.data.Dataset):
def __init__(self, df):
self.inputs = df[[f'i_col' for i in range(14)] + ['label']].values
self.outputs = df[[f'i_col' for i in range(14)]].values
def __len__(self):
return len(self.inputs)
def __getitem__(self, idx):
x = torch.tensor(self.inputs[idx], dtype=torch.float)
y = torch.tensor(np.argmax(self.outputs[idx]))
return x, y
ds = TDataset(total)
dl = torch.utils.data.DataLoader(ds, batch_size=64)
# After doing this I will create a model which takes 15 inputs and
# Give 14 outputs in my case which represent the logits
class NNO(nn.Module):
def __init__(self):
super(NNO, self).__init__()
self.hidden = nn.Linear(15, 20)
self.relu = nn.ReLU()
self.output = nn.Linear(20, 14)
def forward(self, x):
x = self.hidden(x)
x = self.relu(x)
x = self.output(x)
return x
# Now we create the model object
m = NNO()
sample = None
for i in dl:
sample = i
break
print(m(sample[0]).shape) # shape = [64, 14] as desired.
# Now we define the loss function and then the optimizer
loss_fn = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(m.parameters())
# Now we define the training loop
for i in range(500): # for 500 epochs
epoch_loss = 0
for idx, data in enumerate(dl):
inputs = data[0]
targets = data[1] # change accordingly for your data
preds = m(inputs)
optimizer.zero_grad()
loss = loss_fn(preds, targets)
epoch_loss += loss
loss.backward()
optimizer.step()
if (i%50 == 0):
print('loss: ', epoch_loss.item() / len(dl))
'''
Now at the time of inference, you just need to apply softmax on the results of your model and select the most probable output.
'''
preds = m(sample[0])
predicted_classes = torch.argmax(torch.nn.functional.softmax(preds), axis=1)
# Here the predicted classes are the desired final output.
【讨论】:
不,我们得到 1 个输出。基本上,从 0 到 14 的整数预测(该项目属于哪个类。) @oo92 我们使用 sigmoid 激活来实现。除非是回归问题,否则我们永远不会得到单个输出。 我需要使用 TDataset 吗?我不能按原样加载我自己的数据集吗? 你为什么根本不训练? 我以为你发出的只是传递参数。以上是关于构建具有基本事实的非图像分类器的主要内容,如果未能解决你的问题,请参考以下文章