• 首頁 智能算法正文

        小衆深度學習開源框架chain使用入門

        52ai 智能算法 2019-06-12 08:55:10 7740 0 技術領域大數據

        1 chainer是什麽

        chainer是一個基于python的深度學習框架,能夠輕松直觀地編寫複雜的神經網絡架構。

        當前大多數深度學習框架都基于“Define-and-Run”方案。也就是說,首先定義網絡,然後用戶定期向其提供小批量的訓練數據。由于網絡靜態定義的,因此所有的邏輯必須作爲數據嵌入到網絡架構中。

        相反,chainer采用“Define-by-Run”方案,即通過實際的前向計算動態定義網絡。更確切地說,chainer存儲計算曆史而不是編程邏輯。這樣,Chainer不需要將條件和循環引入網絡定義 。chainer的核心理念就是Define-by-Run。

        2 chainer訓練准備

        2.1 chainer安裝

        chainer安裝很簡單,只需要在終端輸入下面命令即可安裝:

        pip install chainer

        2.2 數據讀取

        在chainer中讀取數據是非常簡單的。數據讀取部分的代碼如下:

        import numpy as np
        import os
        from PIL import Image
        import glob
        from chainer.datasets import tuple_dataset
        class Dataset():
        def __init__(self, path, width=60, height=60):
        channels = 3
        path = glob.glob('./mouth/*')
        pathsAndLabels = []
        index = 0
        for p in path:
        print(p + "," + str(index))
        pathsAndLabels.append(np.asarray([p, index]))
        index = index + 1
        allData = []
        for pathAndLabel in pathsAndLabels:
        path = pathAndLabel[0]
        label = pathAndLabel[1]
        imagelist = glob.glob(path + "/*")
        for imgName in imagelist:
        allData.append([imgName, label])
        allData = np.random.permutation(allData)
        imageData = []
        labelData = []

        下面解釋下在chainer中讀取數據的一些特色,完整代碼請移步github。

        在chainer中我們通過chainer.datasets模塊來獲取數據集,其最基本的數據集就是一個數組,平時最常見的NumPy和CuPy數組都可以直接用作數據集。在本實例中我們采用的是元組數據集即TupleDataset()來獲取數據。

        2.3 網絡定義

        它的網絡定義和pytorch基本上是相似的,如下:

        class MyModel(Chain):
        def __init__(self):
        super(MyModel, self).__init__()
        with self.init_scope():
        self.conv1 = L.Convolution2D(
        in_channels=3, out_channels=12, ksize=3, stride=2)
        self.bn1 = L.BatchNormalization(12)
        self.conv2 = L.Convolution2D(
        in_channels=12, out_channels=24, ksize=3, stride=2)
        self.bn2 = L.BatchNormalization(24)
        self.conv3 = L.Convolution2D(
        in_channels=24, out_channels=48, ksize=3, stride=2)
        self.bn3 = L.BatchNormalization(48)
        self.fc1 = L.Linear(None, 1200)
        self.fc2 = L.Linear(1200, 128)
        self.fc3 = L.Linear(128, 2)
        def __call__(self,x):
        return self.forward(x)
        def forward(self, x):
        h1 = F.relu(self.conv1(x))
        h2 = F.relu(self.conv2(h1))
        h3 = F.relu(self.conv3(h2))
        h4 = F.relu(self.fc1(h3))
        h5 = F.relu(self.fc2(h4))
        x = self.fc3(h5)
        return (x)

        上面的例子和之前說過的caffe、tensorflow、pytorch等框架采用的網絡結構是一樣。這裏不在贅述,我具體說下這個框架的特色。

        (1) MyModel(Chain)

        Chain在chainer中是一個定義模型的類,我們把模型MyModel定義爲Chain的子類,即繼承Chain這個類,這和Pytorch中的nn.module類似。以後我們在模型定義時都可以通過Chain來構建具有潛在深層功能和鏈接層次的模型。

        (2) Link和Function

        在Chainer中,神經網絡的每一層都可以認爲是由兩種廣泛類型的函數之一組成即Link和Function。

        其中Function是一個沒有可學習參數的函數,而LInk是包括參數的,我們也能把Link理解成一個賦予其參數的Function。

        在我們使用它之前,我們首先需要導入相應的模塊,如下:

        import chainer.links as L
        import chainer.functions as F

        另外在平時使用時我們喜歡用L替代Link,用F代替Function。如L.Convolution2D和F.relu

        (3) __call__

        對于__call__它的作用就是使我們的chain像一個函數一樣容易被調用。

        3 模型訓練

        數據加載和網絡定義好後,我們就可以進行模型訓練了,話不多說,我們直接上代碼。

        model = L.Classifier(MyModel())
        if os.path.isfile('./dataset.pickle'):
        print("dataset.pickle is exist. loading...")
        with open('./dataset.pickle', mode='rb') as f:
        train, test = pickle.load(f)
        print("Loaded")
        else:
        datasets = dataset.Dataset("mouth")
        train, test = datasets.get_dataset()
        with open('./dataset.pickle', mode='wb') as f:
        pickle.dump((train, test), f)
        print("saving train and test...")
        optimizer = optimizers.MomentumSGD(lr=0.001, momentum=0.5)
        optimizer.setup(model)
        train_iter = iterators.SerialIterator(train, 64)
        test_iter = iterators.SerialIterator(test, 64, repeat=False, shuffle=True)
        updater = training.StandardUpdater(train_iter, optimizer, device=-1)
        trainer = training.Trainer(updater, (800, 'epoch'), out='{}_model_result'.format(MyModel.__class__.__name__))

        在chainer中,模型訓練可以分爲如下6個步驟,個人認爲這6個步驟是非常好理解的。

        Step-01-Dataset

        第一步當然就是加載我們的數據集了,我們通常都是通過下面方法加載數據集:

        train, test = datasets.get_dataset()

        Step-02-Iterator

        chainer提供了一些Iterator,通常我們采用下面的方法來從數據集中獲取小批量的數據進行叠代。

        train_iter = iterators.SerialIterator(train, batchsize)
        test_iter = iterators.SerialIterator(test, batchsize, repeat=False, shuffle=True)

        Step-03-Model

        在chainer中chainer.links.Classifier是一個簡單的分類器模型,盡管它裏面有許多參數如predictor、lossfun和accfun,但我們只需賦予其一個參數那就是predictor,即你定義過的模型。

        model = L.Classifier(MyModel())

        Step-04-Optimizer

        模型弄好後,接下來當然是優化了,在chainer.optimizers中有許多我們常見的優化器,部分優化器如下:

        1、chainer.optimizers.AdaDelta
        2、chainer.optimizers.AdaGrad
        3、chainer.optimizers.AdaDelta 
        4、chainer.optimizers.AdaGrad 
        5、chainer.optimizers.Adam 
        6、chainer.optimizers.CorrectedMomentumSGD . 
        7、chainer.optimizers.MomentumSGD 
        8、chainer.optimizers.NesterovAG 
        9、chainer.optimizers.RMSprop 
        10、chainer.optimizers.RMSpropGraves 
        ...

        Step-05-Updater

        當我們想要訓練神經網絡時,我們必須運行多次更新參數,這在chainer中就是Updater所做的工作,在本例我們使用的是 training.StandardUpdater。

        Step-06-Trainer

        上面的工作做完之後我們需要做的就是訓練了。在chainer中,訓練模型采用的是 training.Trainer()。

        4 可視化

        trainer.extend(extensions.dump_graph("main/loss"))
        trainer.extend(extensions.Evaluator(test_iter, model, device=-1))
        trainer.extend(extensions.LogReport())
        trainer.extend(extensions.PrintReport( ['epoch', 'main/loss', 'validation/main/loss', 'main/accuracy', 'validation/main/accuracy']))
        trainer.extend(extensions.PlotReport(['main/loss', 'validation/main/loss'], x_key='epoch', file_name='loss.png'))
        trainer.extend(extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'], x_key='epoch', file_name='accuracy.png'))
        trainer.extend(extensions.ProgressBar())

        在chainer中可視化是非常方便的,我們常通過trainer.extend()來實現我們的可視化,其有下面幾種可視化的方式。

        1、chainer.training.extensions.PrintReport 
        2、chainer.training.extensions.ProgressBar 
        3、chainer.training.extensions.LogReport 
        4、chainer.training.extensions.PlotReport 
        5、chainer.training.extensions.VariableStatisticsPlot 
        6、chainer.training.extensions.dump_graph 

        以上就是利用chain來做一個圖像分類任務的一個小例子。完整代碼可以看配套的git項目,我們看看訓練中的記錄,如下:

        總結

        本文講解了如何使用chainer深度學習框架完成一個分類任務,盡管這個框架用的人不多,但這個框架使用起來還是比較方便的,您在用嗎?如果您在用,可以聯系我們一起交流下!

        分享
        版權聲明

        本文僅代表作者觀點,不代表本站立場。
        本文系作者授權發表,未經許可,不得轉載。

        評論

        X-POWER-BY FNC V0.5.2 FROM ZZ56