【Kaggle-MNIST之路】两层的神经网络Pytorch(四行代码的模型)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a19990412/article/details/84069622

简述

第一次学习Kaggle。按照之前的要求,先搞个简单的版本来慢慢完善。

所以,第一次的版本特别烂(hhhh)。

任务描述

对mnist数据集进行贴标签。(给图片数据(向量),输出对应的标签。)

  • 得分:0.58
  • 排名:2600+(hhh这时候总共才2700个人)

可以说这个算法基本上等于没搞。但是这个算法框架其实非常简单,所以很适合给大家做以下简单的学习。

闲聊:
因为最近是一直在研究pytorch,所以,这里就尝试着直接搞搞这个。
只考虑神经网络的模型,只用了4行代码(是个非常简单的例子)

代码分解

因为这一篇用简单的篇幅介绍了整个框架之后,之后大家学习就只用在这个上面改善就好了。

导入的包

import pandas as pd
import torch.utils.data as data
import torch
import torch.nn as nn

file = './all/train.csv'
LR = 0.01

导入数据

先自己写了个类,用这个类的话,就是每次需要数据的时候,再分步的拿,而且基于原来的类。就可以直接套用以前学习的框架了。

class MNISTCSVDataset(data.Dataset):

    def __init__(self, csv_file, Train=True):
        self.dataframe = pd.read_csv(csv_file, iterator=True)
        self.Train = Train

    def __len__(self):
        if self.Train:
            return 42000
        else:
            return 28000

    def __getitem__(self, idx):
        data = self.dataframe.get_chunk(100)
        ylabel = data['label'].as_matrix().astype('float')
        xdata = data.ix[:, 1:].as_matrix().astype('float')
        return ylabel, xdata

训练集实例化

mydataset = MNISTCSVDataset(file)
train_loader = torch.utils.data.DataLoader(mydataset, batch_size=1, shuffle=True)

导入到DataLoader中。

搭建神经网络

没错神经网络就已经搭建完了。(是不是觉得pytorch比tf方便多了。。)

net = nn.Sequential(
    nn.Linear(28 * 28, 100),
    nn.ReLU(),
    nn.Linear(100, 10)
)

损失函数

其实这也是非常关键的。

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=LR)

训练模型

最后一句,其实是为了保存训练好的模型。

for step, (yl, xd) in enumerate(train_loader):
    output = net(xd.squeeze().float())
    yl = yl.long()
    loss = loss_function(output, yl.squeeze())
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if step % 20 == 0:
        print('step %d' % step, loss)

torch.save(net, 'divided-net.pkl')

完整代码

import pandas as pd
import torch.utils.data as data
import torch
import torch.nn as nn

file = './all/train.csv'
LR = 0.01


class MNISTCSVDataset(data.Dataset):

    def __init__(self, csv_file, Train=True):
        self.dataframe = pd.read_csv(csv_file, iterator=True)
        self.Train = Train

    def __len__(self):
        if self.Train:
            return 42000
        else:
            return 28000

    def __getitem__(self, idx):
        data = self.dataframe.get_chunk(100)
        ylabel = data['label'].as_matrix().astype('float')
        xdata = data.ix[:, 1:].as_matrix().astype('float')
        return ylabel, xdata


mydataset = MNISTCSVDataset(file)

train_loader = torch.utils.data.DataLoader(mydataset, batch_size=1, shuffle=True)

net = nn.Sequential(
    nn.Linear(28 * 28, 100),
    nn.ReLU(),
    nn.Linear(100, 10)
)

loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=LR)
for step, (yl, xd) in enumerate(train_loader):
    output = net(xd.squeeze().float())
    yl = yl.long()
    loss = loss_function(output, yl.squeeze())
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if step % 20 == 0:
        print('step %d' % step, loss)

torch.save(net, 'divided-net.pkl')

后记

到这里,一个模型就已经训练好了。至于如何调用这个模型,我自己单独写了一个函数。

将训练与测试分开的原因

主要是避免冲突。因为训练的话,有时候担心出bug什么的。就直接调用这个的话,会方便太多了。(易于保存和使用。)

测试的话,其实没什么难度的。。大家随便看看就好了。

import torch
import torch.utils.data as data
import pandas as pd
import csv
file = './all/test.csv'


class MNISTCSVDataset(data.Dataset):

    def __init__(self, csv_file, Train=False):
        self.dataframe = pd.read_csv(csv_file, iterator=True)
        self.Train = Train

    def __len__(self):
        if self.Train:
            return 42000
        else:
            return 28000

    def __getitem__(self, idx):
        data = self.dataframe.get_chunk(100)
        xdata = data.as_matrix().astype('float')
        return xdata


net = torch.load('divided-net.pkl')

myMnist = MNISTCSVDataset(file)
test_loader = torch.utils.data.DataLoader(myMnist, batch_size=1, shuffle=False)

values = []
for _, xd in enumerate(test_loader):
    output = net(xd.squeeze().float())
    values = values + output.argmax(dim=1).numpy().tolist()

with open('./all/sample_submission.csv', 'r') as fp_in, open('newfile.csv', 'w', newline='') as fp_out:
    reader = csv.reader(fp_in)
    writer = csv.writer(fp_out)
    header = 0
    for i, row in enumerate(reader):
        if i == 0:
            writer.writerow(row)
        else:
            row[-1] = str(values[i-1])
            writer.writerow(row)

猜你喜欢

转载自blog.csdn.net/a19990412/article/details/84069622
今日推荐