zoukankan      html  css  js  c++  java
  • 大规模分类问题作业报告

    概述

    这是一个分类任务。每个例子都有2个分类结果和11392个维度特征。一共有2177020个训练样例和220245个测试样例。

    你会被提供以下三个文件:

    1. train.txt

      每一行的格式如下:

       label index0:value0 index2:value2 index3:value3 ...
      

      value0, value1,...都是特征(如果value0等于0它将会被省略),总共只有2个分类label。

    2. test.txt

      这个文件包含一些需要你预测label的特征。每一行的格式如下:

       id index0:value0 index1:value1 index2:value2 ...
      
    3. sample_submission.csv

      你需要提交的文件应该包含以下格式,每一行如下:

       id,label
      

    这个问题的评估矩阵是Categorization Accuracy(multiclass-classification)。输出文件应该包含一个头部和以下格式:

    id,label
    0,1
    1,0
    2,1
    3,0
    etc.
    

    方法一:Liblinear

    我有尝试过常规方法,但是都有内存不够用的问题。因为训练数据规模太大了,就连特征维度也高达11392,所以都不适用。

    Liblinear是一个简单的求解大规模规则化线性分类和回归的软件包,它的速度比较快,而且对大规模数据有内存优化,适用于个人电脑。

    我的实验环境为windows 10 64-bit。关于train程序的参数设置,分类器为 L2-regularized L2-loss support vectorclassification (dual),cost为1,设置epsilon-SVR的损失函数的参数epsilon为0.1。用predict程序跑出来的数据提交到kaggle的分数0.5733。


    方法二:Neural Network + Keras

    keras是一个深度学习框架,基于Theano,可使用GPU做加速运算。

    我的实验环境为windows 10 64-bit、Pycharm和Keras,使用语言为Python 3.5。

    以下为实验步骤:

    1. 对train.txt和test.txt做分割

    因为train.txt的训练样例太多了,不可能同时装进一个矩阵进行运算,所以需要做分割成小文件。我把它分成了train文件夹下的200个part小文件。代码如下:

    #   Preprocess for train
    partnums = 200
    inputfile = open("train.txt", "rb")
    outputlist = []
    for i in range(partnums):
        outputlist.append(open('train/part%04d'%i,'wb'))
    
    index = 0
    while True:
        chunk = inputfile.readline()
        if not chunk:
            break
        outputlist[index].write(chunk)
        index += 1
        if index == partnums:
            index = 0
    
    for i in range(partnums):
        outputlist[i].close()
    

    同理,也把test.txt分割成test文件夹下的20个小文件。

    2. 建立神经网络模型

    我选用了keras框架的Sequence模型。

    隐含层为一层有300个节点的Dense层,其激活函数为Relu。ReLu的使用,使得网络可以自行引入稀疏性,同时使学习周期大大缩短。

    输出层为有1个节点的Dense层,其激活函数为Sigmoid。Sigmoid的使用,可以将上一层的结果映射到 [0, 1] 的区间内,输出结果为1的概率。

    同时,损耗函数为binary_crossentropy,优化器为rmsprop,以下为建模代码:

    #   build model
    print("building model:")
    model = Sequential()
    model.add(Dense(300, input_shape=(11392, ),activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    checkpointer = ModelCheckpoint(filepath="weights.hdf5", verbose=1, save_best_only=True)
    

    3. 分批训练

    逐个读入train文件夹下的各个小文件,将样例的信息还原成一个11392维度的特征矩阵,并提取出train_X和train_y,对模型进行分批训练。批训练样例大小为50,迭代次数为10,验证分割比例为0.05。

    以下为训练代码:

    #   batch train
    print("batch training")
    partnums = 200
    width = 11392
    
    for i in range(partnums):
        lines = open('train/part%04d' % i).readlines()
    
        print("reading the %04d part of train: " % i)
    
        depth = len(lines)
    
        print("depth:", depth)
    
        #   generate train_X and train_y
        train_X = [[0 for _ in range(width)] for __ in range(depth)]
        train_y = [0 for _ in range(depth)]
    
        for y, line in enumerate(lines):
            datas = line.split(' ')
            train_y[y] = int(datas[0])
            datas.pop(0)
    
            for data in datas:
                x = int(data.split(':')[0]) - 1
                train_X[y][x] = 1
                del x
            del datas
    
        print("", len(train_X[0]))
    
        model.fit(train_X, train_y, batch_size=50, nb_epoch=10, validation_split=0.05, callbacks=[checkpointer])
    
        del lines
        del train_X
        del train_y
    

    同时要注意的是,需要在每次迭代后,把临时变量回收掉,不然内存同样不够用。每次训练所使用的内存空间大概为2GB。

    4. 分批预测并保存结果

    由于test.txt被分割成了20个小文件,所以需要分批预测20次。

    因为预测结果是 [0,1] 区间之间的浮点数概率,所以需要做转换处理。当概率大于0.5时,预测结果为1;否则,预测结果为0。同时,合并预测结果写到 submission.csv 文件里。

    以下为代码:

    #   predict
    print("predicting:")
    output = open("submission.csv", "w")
    output.write("Id,label
    ")
    width = 11392
    
    for i in range(20):
        print("reading part %04d of test" % i)
        lines = open("test/part%04d" % i).readlines()
        x_test = [[0 for _ in range(width)] for __ in range(len(lines))]
        indexs = []
    
        for y, line in enumerate(lines):
            datas = line.split(' ')
            indexs.append(datas[0])
            datas.pop(0)
    
            for data in datas:
                x = int(data.split(':')[0]) - 1
                x_test[y][x] = 1
                del x
            del datas
        predicted = model.predict(x_test)
        for j in range(len(indexs)):
            if float(predicted[j]) >= 0.5:
                output.write("%s,%d
    " % (indexs[j], 1))
            else:
                output.write("%s,%d
    " % (indexs[j], 0))
    
        del lines
        del indexs
        del predicted
    
    output.close()
    

    5. 总结

    本次实验在本地机器上的val_acc最高可以达到0.91,但是把结果提交到kaggle上的分数为0.53。

    而且在对前10个train小文件训练完后,val_acc就达到最佳了,后续训练参数似乎无改进。

    以下为前3次训练的log结果:

    第1次训练:

    log1.bmp-2831.4kB

    第2次训练:

    log2.bmp-2657.9kB

    第3次训练:

    log3.bmp-2662kB

  • 相关阅读:
    IIS HTTP 错误 405.0
    读书笔记 (.NET企业级应用架构设计)
    .net core 2.2 使用imagemagick 将pdf转化为png
    mac visual stdio 2019 自动格式化代码的选项
    黑马程序员——OC语言基本语法知识foundation
    黑马程序员——OC语言基本语法知识(五)
    黑马程序员——OC语言基本语法知识(四)
    黑马程序员——OC语言基本语法知识(三)
    黑马程序员——OC语言基本语法知识(二)
    黑马程序员——OC语言基本语法知识(一)
  • 原文地址:https://www.cnblogs.com/linyihan/p/5566695.html
Copyright © 2011-2022 走看看