Convolutionレイヤ(畳み込み層)

CNN(畳み込みニューラルネットワーク)とは?

CNN(Convokution Neural Network)は、画像認識アルゴリズムとして定着した機械学習におけるモデルです。
CNNは「入力層」「隠れ層」「出力層」に大別されます。
入力層の役割は、画像の1ピクセル(画素)毎にニューロンを作成します。
隠れ層の役割は、画像の特徴パターンをを検知するニューロンを作成します。この層の中に「畳み込み層」と「プーリング層」が存在します。
本記事の主題は、この畳み込み層になります。
出力層の役割は、プーリング層からの情報を組み合わせて確信度を0から1までの数値で判定を行います。ここで気がついた方は賢いですね。
そう!出力層で使われるのがソフトマックス関数ですね。

畳み込み層のサンプルプログラム

畳み込み層について「0からDeepLearning」では”Convolutionレイヤ”として紹介されています。
下のプログラムが、「0からDeepLearning」に掲載されていた畳み込み層のサンプルプログラムになります。
im2col関数は、畳み込みを行う処理2重ループをなくしNumPyが効率的に処理できるように2次元配列に変換しているものです。col2im関数は、その逆のことを行っています。
畳み込み層の処理は、画像認識の処理で一番コストがかかる処理になりますので、このような最適化を行うことでパフォーマンス改善していくことが必要です。どういう処理を行ったらパフォーマンスが改善するか、処理スピードを追求していくのも面白いかもしれませんね。
最初からパフォーマンス改善済みでサンプルを提供するあたりが良書と思う理由の1つですね。プログラムの細かい説明は「0からDeepLearning」を買って確認してくださいね。

class Convolution:
    def init(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = stride
        self.pad = pad
        # 中間データ(backward時に使用)
        self.x = None   
        self.col = None
        self.col_W = None
        # 重み・バイアスパラメータの勾配
        self.dW = None
        self.db = None
    def forward(self, x):
        FN, C, FH, FW = self.W.shape
        N, C, H, W = x.shape
        out_h = 1 + int((H + 2*self.pad - FH) / self.stride)
        out_w = 1 + int((W + 2*self.pad - FW) / self.stride)
        col = im2col(x, FH, FW, self.stride, self.pad)
        col_W = self.W.reshape(FN, -1).T
        out = np.dot(col, col_W) + self.b
        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)
        self.x = x
        self.col = col
        self.col_W = col_W
        return out
    def backward(self, dout):
        FN, C, FH, FW = self.W.shape
        dout = dout.transpose(0,2,3,1).reshape(-1, FN)
        self.db = np.sum(dout, axis=0)
        self.dW = np.dot(self.col.T, dout)
        self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)
        dcol = np.dot(dout, self.col_W.T)
        dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)
        return dx
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1
    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))
    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    return col
def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
    N, C, H, W = input_shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1
    col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)
    img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))
    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]
    return img[:, :, pad:H + pad, pad:W + pad]
引用元

オライリーJapan 斎藤康毅 著 「セロから作るDeep Learning」

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.

Accept or Deny