首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我用手电筒训练一个虹膜分类模型,但我的acc是0.4。

问我用手电筒训练一个虹膜分类模型,但我的acc是0.4。
EN

Stack Overflow用户
提问于 2022-08-14 07:51:27
回答 1查看 85关注 0票数 1

我尝试过许多改进,比如增加时代、使用更好的损失函数和优化器、深化网络和洗牌数据集等等,但仍然没有效果。这个问题困扰我很长时间了,谢谢你的帮助。下面是我的密码。

加载和处理数据集(更新)

代码语言:javascript
复制
def Iris_Reader(dataset):
    train_data, test_data, train_label, test_label = train_test_split(dataset.data, dataset.target, test_size=0.4)

    # scaler = StandardScaler()
    # train_data = scaler.fit_transform(train_data)
    # test_data = scaler.transform(test_data)
    
    return torch.FloatTensor(train_data), torch.LongTensor(train_label), torch.FloatTensor(test_data), torch.LongTensor(test_label)

定义分类器

代码语言:javascript
复制
class Classifier(nn.Module):
    def __init__(self):
        super().__init__()
        
        #4*3*3 network
        self.model = nn.Sequential(
            nn.Linear(4,3),
            nn.ReLU(),

            nn.Linear(3,3),
        )
        
        #SGD
        self.optimiser = torch.optim.SGD(self.parameters(), lr = 0.1)
        
        #MSE LOSS_FUNCTION
        self.loss_fn = nn.CrossEntropyLoss()

        self.counter = 0
        self.progress = []

    def forward(self, input):
        return self.model(input)
    
    def train(self, input, target):
        output = self.forward(input)

        loss = self.loss_fn(output, target)

        self.counter += 1
        self.progress.append(loss.item())

        self.optimiser.zero_grad()
        loss.backward()
        self.optimiser.step()
    # plot loss
    def plot_loss(self):
        plt.figure(dpi=100)
        plt.ylim([0,1.0])
        plt.yticks([0, 0.25, 0.5, 1.0])
        plt.scatter(x = [i for i in range(len(self.progress))], y = self.progress, marker = '.', alpha = 0.2)
        plt.grid('on')
        plt.show()

火车

代码语言:javascript
复制
C = Classifier()
epochs = 10
dataset = datasets.load_iris()

for epoch in range(epochs):
    train_data, train_label, _, _ = Iris_Reader(dataset)
    for i, j in zip(train_data, train_label):
        C.train(i, j)

测试

代码语言:javascript
复制
score = 0
num = 0
# for epoch in range(epochs):
_, _, test_data, test_label = Iris_Reader(dataset)
for i,j in zip(test_data, test_label):
    output = C.forward(i).detach().argmax()
    if output == j:
        # print(C.forward(i).detach(), j)
        score += 1
    num += 1
print(score, num, round(score/num, 3))

产出: 53 60 0.883

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-14 08:42:45

这里有很多问题:

  • 首先,您似乎独立地洗牌数据和标签,使数据集毫无用处。
  • 还在循环中重新创建数据集,这是毫无意义的浪费CPU时间。

总的来说,数据集的创建可以缩短为如下所示:

代码语言:javascript
复制
def Iris_Reader(dataset):
    train_data, test_data, train_label, test_label = sklearn.model_selection.train_test_split(dataset.data, dataset.target, test_size=0.2)
    return torch.FloatTensor(train_data), torch.LongTensor(train_label), torch.FloatTensor(test_data), torch.LongTensor(test_label)

并且应该被带到循环之外。

其次,MSELoss()适合于回归。对于分类,CrossEntropyLoss()是默认的选择。

在中间层使用乙状结肠作为激活并不是最好的选择,特别是在较短的时间内。ReLU应该能更好地收敛。

最后但并非最不重要的是,如果你的损失图表看起来要干净得多,如果这些值是每个时代的平均值。

Update:确保目标具有与网络输出相同大小的实现,并附加功能缩放:

代码语言:javascript
复制
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

def Iris_Reader(dataset):
    label = nn.functional.one_hot(torch.LongTensor(dataset.target), num_classes=3).float()

    train_data, test_data,train_label, test_label = train_test_split(dataset.data, label, test_size=0.2)
    scaler = StandardScaler()
    train_data = scaler.fit_transform(train_data)
    test_data = scaler.transform(test_data)
    return torch.FloatTensor(train_data), train_label, torch.FloatTensor(test_data), test_label

哦,而且您可能也应该删除最后的Sigmoid(),因为CrossEntropyLoss()无论如何都会应用logsoftmax。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73349963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档