Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Python DeepLearningに再挑戦 24 CNNの実装

概要

Python DeepLearningに再挑戦 24 CNNの実装

参考書籍

CNNの実装

  • 以下のようなイメージのネットワークを作る。

f:id:riikku:20161226220511p:plain

class SimpleConvNet:

    def __init__(self, input_dim=(1, 28, 28),
                            conv_param={'filter_num':30, 'filter_size':5,'pad':0, 'stride':1},
                            hidden_size=100, output_size=10, weight_init_std=0.01):
        filter_num = conv_param['filter_num']
        filter_size = conv_param['filter_size']
        filter_pad = conv_param['pad']
        filter_stride = conv_param['stride']
        input_size = input_dim[1]
        conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1
        pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))
        # 続いて、重みパラメータの初期化を行う
        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(filter_num, input_dim[0], filter_size, filter_size) #ランダムに重みを設定する。
        self.params['b1'] = np.zeros(filter_num)
        self.params['W2'] = weight_init_std * np.random.randn(pool_output_size, hidden_size) #これは全結合の重みとバイアス
        self.params['b2']=np.zeros(hidden_size)
        self.params['W3']=weight_init_std * np.random.randn(hidden_size, output_size)#これも全結合層の重みとバイアス
        self.params['b3']=np.zeros(output_size)
        #最後に必要なレイヤを生成する。
        self.layers = OrderedDict()
        self.layers['Conv1'] = Convolution(self.params['W1'], self.params['b1'], conv_param['stride'], conv_param['pad'])
        self.layers['Relu1'] = Relu()
        self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2)
        self.layers['Affine1'] = Affine(self.params['W2'], self.params['b2'])
        self.layers['Relu2'] = Relu()
        self.layers['Affine2'] = Affine(self.params['W3'], self.params['b3'])
  • 以上でSimleConvNetの初期化が終了らしい。めっちゃ大変やなぁ(^ ^)

  • 以下で、predict 推論メソッドと、loss損失関数メソッド。

        # 推論と損失関数メソッド
        def predict(self, x):#推論メソッド
            for layer in self.layers.values():#layersのkey:valuesごとに、layey.forwardで出力する。
                x = layer.forward(x)
            return x
        
        def loss(self, x, t):#損失関数,xは入力データ、tは教師ラベル
            y = self.predict(x)
            return self.lastLayer.forward(y, t)#lastLayer.forwardで、損失関数を出力
        def gradient(self, x, t):
            # forward
            self.loss(x, t)
            
            # backward
            dout = 1
            dout = self.lastLayer.backward(dout)
            
            layers = list(self.layers.values())
            layers.reverse()
            for layer in layers:
                dout = layer.backward(dout)
                
            # 設定 勾配 誤差逆伝播法で求める。
            grads = {}
            grads['W1'] = self.layers['Conv1'].dW
            grads['b1'] = self.layers['Conv1'].db
            grads['W2'] = self.layers['Affine1'].dW
            grads['b2'] = self.layers['Affine1'].db
            grads['W3']=self.layers['Affine2'].dW
            grads['b3'] = self.layers['Affine2'].db
            
            return grads

あーこの辺は、あんまり変わらんな。

ch07/train_convnet.pyを実行すると、訓練データの認識 率は 99.82%、テストデータの認識率は 98.96% になるらしい!すごい!!

CNNすげー!