- CNN(ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง- convolutional neural network)
- ์ด๋ฏธ์ง ์ธ์ + ์์ฑ ์ธ์ ๋ฑ ๋ค์ํ ๊ณณ์์ ์ฌ์ฉ๋จ.
7-1) ์ ์ฒด ๊ตฌ์กฐ
7-2) ํฉ์ฑ๊ณฑ ๊ณ์ธต
- ์ ์ฒด์ ์ธ ๋ฐ์ดํฐ๊ฐ ํ๋ฅธ๋ค๋ ์ฐจ์ด์ ์ด ์์
7-2-1) ์์ ์ฐ๊ฒฐ ๊ณ์ธต์ ๋ฌธ์ ์
- ๋ฐ์ดํฐ์ ํ์์ด ๋ฌด์๋จ

- ex) ๊ธฐ์กด: 3์ฐจ์ ๋ฐ์ดํฐ๋ฅผ 1์ฐจ์ ๋ฐ์ดํฐ๋ก ๋ฐ๊ฟ์ ๊ณ์ฐํ์์
- ์ด๋ฏธ์ง์ ๊ฒฝ์ฐ, 3์ฐจ์์ด๊ธฐ์ 1์ฐจ์์ผ๋ก ๋ฐ๊ฟ๋ฒ๋ฆฌ๋ฉด ๊ทธ์ ๋ด๊ธด ์ ๋ณด๋ค์ด ์ฌ๋ผ์ ธ๋ฒ๋ฆผ
- CNN์ ์ ์ถ๋ ฅ ๋ฐ์ดํฐ: Feature Map(ํน์ง๋งต)์ด๋ผ๊ณ ํจ - ์ ๋ ฅ ํน์ง ๋งต/ ์ถ๋ ฅ ํน์ง ๋งต
7-2-2) ํฉ์ฑ๊ณฑ ์ฐ์ฐ
- ์๋์ฐ: ์ผ์ ๊ฐ๊ฒฉ์ผ๋ก ์ด๋ํด๊ฐ๋ฉฐ ์ ๋ ฅ ๋ฐ์ดํฐ์ ์ ์ฉ (์ฌ๊ธฐ์๋ ์๋์ฐ๊ฐ 3x3)
- ์ ๋ ฅ๊ณผ ํํฐ์์ ๋์ํ๋ ์์๋ค๋ผ๋ฆฌ ๊ณฑํด์ ์ดํฉ ๊ตฌํจ ⇒ ๋จ์ผ ๊ณฑ์ ๋์ฐ
- ํธํฅ : ํํฐ ์ ์ฉํ ํ ์ถ๋ ฅ๊ฐ(2x2)์ ํธํฅ์ ๊ฐ๊ฐ ๋ํด์ค ex) ํธํฅ:3, [18, 19, 9, 18]
7-2-3) ํจ๋ฉ

- ํจ๋ฉ: ์ถ๋ ฅ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ
- ์ ์ฌ์ฉ?: ๊ธฐ์กด (4,4)์ (3,3) ํํฐ๋ฅผ ์ถ๋ ฅํ๋ฉด (2,2)๋ก ์ค์ด๋ฌ. ⇒ ์ด๋ฐ์์ผ๋ก ํฉ์ฑ๊ณฑ ์ฐ์ฐ์ ๊ณ์ ํ๋ฉด ์ค์ด๋ค์ด์ ์ถ๋ ฅ ํฌ๊ธฐ๊ฐ 1์ด ๋์ด๋ฒ๋ฆผ → ๋ ์ด์ ์ฐ์ฐ์ด ์๋จ.
- ๋ฐ๋ผ์, ํจ๋ฉ์ ํ์ฉํด ์ ๋ ฅ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ์ ์งํด์ ๋ค์ ๊ณ์ธต์ ๊ทธ๋๋ก ์ ๋ฌ์ ํ ์ ์์
7-2-4) ์คํธ๋ผ์ด๋
์คํธ๋ผ์ด๋: ํํฐ๋ฅผ ์ ์ฉํ๋ ์์น์ ๊ฐ๊ฒฉ

- ์คํธ๋ผ์ด๋๊ฐ ์ปค์ง๋ฉด ์ถ๋ ฅ ํฌ๊ธฐ๋ ์์์ง ( ๊ทธ๋งํผ ์ด๋ํ๋๊ฒ ์ปค์ง๋ฏ๋ก ์นธ ์๋ ์์์ง
- ํจ๋ฉ์ ํฌ๊ฒ ํ๋ฉด ์ถ๋ ฅ ํฌ๊ธฐ๊ฐ ์ปค์ง

- ์ ๋ ฅ ํฌ๊ธฐ(H,W), ํํฐ ํฌ๊ธฐ(FH,FW), ์ถ๋ ฅ ํฌ๊ธฐ(OH, OW), ํจ๋ฉ(P), ์คํธ๋ผ์ด๋(S)
7-2-5) 3์ฐจ์ ๋ฐ์ดํฐ์ ํฉ์ฑ๊ณฑ ์ฐ์ฐ
7-2-6) ๋ธ๋ก์ผ๋ก ์๊ฐํ๊ธฐ
7-2-7) ๋ฐฐ์น ์ฒ๋ฆฌ
- ์ ๊ฒฝ๋ง์์ ๋ฐฐ์น ์ฒ๋ฆฌ ํด์คฌ์ ⇒ ๋ง์ฐฌ๊ฐ์ง๋ก CNN์์๋ ๋ฏธ๋๋ฐฐ์น ํ์ต ์ง์ํด์ค
- ๊ธฐ์กด 3์ฐจ์์์ 4์ฐจ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฒ ๋จ.
- (๋ฐ์ดํฐ ์, ์ฑ๋ ์, ๋์ด, ๋๋น)
- ** 4์ฐจ์ ๋ฐ์ดํฐ๊ฐ ํ๋ ํ๋ฅผ ๋๋ง๋ค ๋ฐ์ดํฐ N๊ฐ์ ๋ํ ํฉ์ฑ๊ณฑ ์ฐ์ฐ์ด ์ด๋ค์ง.
- ์ฆ, ๊ธฐ์กด ์ ๊ฒฝ๋ง ๋ฏธ๋๋ฐฐ์น์ ๊ฐ์ ๋ง ⇒ Nํ ๋ถ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํ ๋ฒ์ ์ํํด์ค. ( ๋ฏธ๋๋ฐฐ์น 10, ์ ์ฒด 100⇒ 10ํ ๋ถ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํ๋ฒ์ ๋ค ๋๋ ค๋ฒ๋ฆผ)

7-3) ํ๋ง ๊ณ์ธต
7-4) ํฉ์ฑ๊ณฑ/ํ๋ง ๊ณ์ธต ๊ตฌํ
7-4-1) 4์ฐจ์ ๋ฐฐ์ด
- ๋ฐ์ดํฐ์ ํ์์ด (10,1,28,28) ์ด๋ผ๋ฉด ⇒ ๋ฐ์ดํฐ๊ฐ 10๊ฐ, ์ฑ๋ 1๊ฐ, 28*28
- x[0].shape ⇒ (1,28,28) ⇒ ์ฒซ ๋ฒ์งธ ๋ฐ์ดํฐ์ ์ ๊ทผ
- ⇒ im2col์ด๋ผ๋ ํธ๋ฆญ์ด ๋ฌธ์ ๋ฅผ ๋จ์ํ๊ฒ ๋ง๋ค์ด์ค.
7-4-2) im2col(image to column) ๋ฐ์ดํฐ ์ ๊ฐํ๊ธฐ
- ํฉ์ฑ๊ณฑ ์ฐ์ฐ์ ๊ตฌํํ๊ธฐ ์ํด์ for๋ฌธ ๊ฒน๊ฒน์ด ์จ์ผํจ ⇒ ๋จ์ .
- ⇒ im2col( ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ค์น ๊ณ์ฐํ๊ธฐ ์ข๊ฒ ํผ์น๋ ํจ์
- ์ค์ ์ํฉ์์๋ ํํฐ ์ ์ฉ ์์ญ์ด ๊ฒน์น๋ ๊ฒฝ์ฐ๊ฐ ๋๋ถ๋ถ
- ํํฐ ์ ์ฉ ์์ญ์ด ๊ฒน์น๊ฒ ๋๋ฉด im2col๋ก ์ ๊ฐํ ํ์ ์์ ์๊ฐ ์๋๋ณด๋ค ๋ง์์ง (๋ฉ๋ชจ๋ฆฌ ๋ ๋ง์ด ์๋น)
- ์ปดํจํฐ๋ ํฐ ํ๋ ฌ์ ๋ง๋ค์ด ๊ณ์ฐํ๋ ๋ฐ ํ์ํด ํจ์จ ๋์ผ ์ ์์
- ์ด๋ฏธ์ง๋ฅผ ์ด๋ก ๋ถ์
7-4-3) ํฉ์ฑ๊ณฑ ๊ณ์ธต ๊ตฌํ
# im2col ์ฌ์ฉ ๊ตฌํ import sys, os sys.path.append('/deep-learning-from-scratch') from common.util import im2col x1 = np.random.rand(1, 3, 7, 7) # ๋ฐ์ดํฐ ์, ์ฑ๋ ์, ๋์ด, ๋๋น col1 = im2col(x1, 5, 5, stride=1, pad=0) print(col1.shape) x2 = np.random.rand(10, 3, 7, 7) # ๋ฐ์ดํฐ 10๊ฐ col2 = im2col(x2, 5, 5, stride=1, pad=0) print(col2.shape) >>> (9, 75) (90, 75)
- ๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ 2๋ฒ์งธ ์ฐจ์์ ์์๋ 75๊ฐ
- ํํฐ์ ์์ ์์ ๊ฐ์ (์ฑ๋3, 5*5 ๋ฐ์ดํฐ)
- ๋ฐฐ์นํฌ๊ธฐ๊ฐ 1์ผ ๋๋ (9, 75) 10์ผ ๋๋ 10๋ฐฐ์ธ (90, 75)
# ํฉ์ฑ๊ณฑ ๊ณ์ธต ๊ตฌํ - Convolution ํด๋์ค class Convolution: def __init__(self, W, b, stride=1, pad=0): self.W = W self.b = b self.stride = stride self.pad = pad def forward(self, x): FN, C, FH, FW = self.W.shape N, C, H, W = x.shape out_h = int(1 + (H + 2*self.pad - FH) / self.stride) out_w = int(1 + (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) return out
- eshape ๋ ๋ฒ์งธ ์ธ์ -1๋ก ์ง์ ํ๋ฉด ๋ค์ฐจ์ ๋ฐฐ์ด์ ์์ ์๊ฐ ๋ณํ ํ์๋ ๋๊ฐ์ด ์ ์ง๋๋๋ก ๋ฌถ์ด์ค
- transposeํจ์๋ฅผ ์ด์ฉํด ์ถ๋ ฅ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ ํ์์ผ๋ก ๋ฐ๊พธ์ด ์ค
- ์ธ๋ฑ์ค๋ฅผ ์ง์ ํ์ฌ ์ถ์ ์์ ๋ณ๊ฒฝ
- ์ญ์ ํ์์๋ im2col ๋์ col2im ํจ์ ์ฌ์ฉ
7-4-4) ํ๋ง ๊ณ์ธต ๊ตฌํ
- ํ๋ง์ ๊ฒฝ์ฐ์๋ ์ฑ๋์ด ๋ ๋ฆฝ์ ์ด๋ผ๋ ์ ์ด ํฉ์ฑ๊ณฑ๊ณ์ธต๊ณผ ๋ค๋ฅธ ์
- ํฉ์ฑ๊ณฑ ๊ณ์ธต์ ๊ฒฝ์ฐ, ๊ฐ ํํฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณฑํด์ ํ ์นธ์ ๋ค ์์ฑ but, ํ๋ง์ ๊ฒฝ์ฐ ์ด์ด๋ถ์?!
- ์ ๊ฐ ํ ์ต๋๊ฐ ๊ตฌํ๊ณ ์ ์ ํ ํ์์ผ๋ก ๋ฐ๊พธ์ด์ค
class Pooling: def __init__(self, pool_h, pool_w, stride=1, pad=0): self.pool_h=pool_h self.pool_w=pool_w self.stride=stride self.pad=pad def forward(self, x): n, c, h, w=x.shape out_h=int(1+(h-self.pool_h)/self.stride) out_w=int(1+(w-self.pool_w)/self.stride) #์ ๋ ฅ ๋ฐ์ดํฐ ์ ๊ฐ (1) col=im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) #์ ๊ฐ col=col.reshape(-1, self.pool_h*self.pool_w) #์ต๋๊ฐ (2) out=np.max(col, axis=1) #์ต๋๊ฐ ์ฌ๊ธฐ์๋ ์ถ ๊ธฐ์ค์ผ๋ก์ ์ต๋๊ฐ #์ ์ ํ ๋ชจ์์ผ๋ก ์ฑํ (3) out=out.reshape(n, out_h, out_w, c).transpose(0, 3, 1, 2) return out
7-5) CNN ๊ตฌํํ๊ธฐ
- CNN ๋คํธ์ํฌ๋
Convolution-ReLU-Pooling-Affine-ReLU-Affine-Softmax
์์ผ๋ก ํ๋ฆ

- ํ์ดํผ ํ๋ฆฌ๋ฏธํฐ ์ค์
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))
Parameters
input_size : ์ ๋ ฅ ํฌ๊ธฐ๏ผMNIST์ ๊ฒฝ์ฐ์ 784๏ผ hidden_size_list : ๊ฐ ์๋์ธต์ ๋ด๋ฐ ์๋ฅผ ๋ด์ ๋ฆฌ์คํธ๏ผe.g. [100, 100, 100]๏ผ output_size : ์ถ๋ ฅ ํฌ๊ธฐ๏ผMNIST์ ๊ฒฝ์ฐ์ 10๏ผ activation : ํ์ฑํ ํจ์ - 'relu' ํน์ 'sigmoid' weight_init_std : ๊ฐ์ค์น์ ํ์คํธ์ฐจ ์ง์ ๏ผe.g. 0.01๏ผ 'relu'๋ 'he'๋ก ์ง์ ํ๋ฉด 'He ์ด๊น๊ฐ'์ผ๋ก ์ค์ 'sigmoid'๋ 'xavier'๋ก ์ง์ ํ๋ฉด 'Xavier ์ด๊น๊ฐ'์ผ๋ก ์ค์
- 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']) self.last_layer = SoftmaxWithLoss()
- ์ด๊ธฐํ๋ฅผ ๋ง์น ํ์๋ ์ถ๋ก ์ ์ํํ๋ predict ๋ฉ์๋์ ์์คํจ์์ ๊ฐ์ ๊ตฌํ๋ loss ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
def predict(self, x): for layer in self.layers.values(): x = layer.forward(x) return x def loss(self, x, t): """์์ค ํจ์๋ฅผ ๊ตฌํ๋ค. Parameters ---------- x : ์
๋ ฅ ๋ฐ์ดํฐ t : ์ ๋ต ๋ ์ด๋ธ """ y = self.predict(x) return self.last_layer.forward(y, t)
- ์ฌ๊ธฐ๊น์ง๊ฐ ์์ ํ ์ฝ๋
- ์ญ์ ํ ๊ธฐ์ธ๊ธฐ ๊ตฌํ๋ ๊ตฌํ
def gradient(self, x, t): """๊ธฐ์ธ๊ธฐ๋ฅผ ๊ตฌํ๋ค(์ค์ฐจ์ญ์ ํ๋ฒ). Parameters ---------- x : ์
๋ ฅ ๋ฐ์ดํฐ t : ์ ๋ต ๋ ์ด๋ธ Returns ------- ๊ฐ ์ธต์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๋ด์ ์ฌ์ (dictionary) ๋ณ์ grads['W1']ใgrads['W2']ใ... ๊ฐ ์ธต์ ๊ฐ์ค์น grads['b1']ใgrads['b2']ใ... ๊ฐ ์ธต์ ํธํฅ """ # forward self.loss(x, t) # backward dout = 1 dout = self.last_layer.backward(dout) layers = list(self.layers.values()) layers.reverse() for layer in layers: dout = layer.backward(dout) # ๊ฒฐ๊ณผ ์ ์ฅ grads = {} grads['W1'], grads['b1'] = self.layers['Conv1'].dW, self.layers['Conv1'].db grads['W2'], grads['b2'] = self.layers['Affine1'].dW, self.layers['Affine1'].db grads['W3'], grads['b3'] = self.layers['Affine2'].dW, self.layers['Affine2'].db return grads
7-6) CNN ์๊ฐํ

- ํ์ต ์ ์ ํํฐ๋ ๋ฌด์์๋ก ์ด๊ธฐํ ๋จ ⇒ ๊ท์น์ฑ์ด ์์
- ํ์ต ํ์ ํํฐ๋ ๊ท์น์๋ ์ด๋ฏธ์ง๊ฐ ๋จ
- ํฐ์๋ถ๋ถ๊ณผ ๊ฒ์ ์ ๋ถ๋ถ์ผ๋ก ๋๋ ทํ๊ฒ ๋๋ ๊ฒ → ex) ์ผ์ชฝ์ด ํฐ์, ์ค๋ฅธ์ชฝ์ด ๊ฒ์ → ์ธ๋ก ๋ฐฉํฅ์ ์์ง์ ๋ฐ์ํ๋ ํํฐ์.
- ex)

→ ์ธต์ ์ฌ๋ฌ๊ฒน ์๊ฒ ๋๋ฉด ๋ ๋ณต์กํด์ง๊ณ ์ถ์ํ๋ ์ ๋ณด๊ฐ ์ถ์ถ๋จ → ์ฌ๋ฌผ์ ๋ํ ์๋ฏธ ํ์ ์ ๋ณด๋ฅผ ๋ ๋ง์ด ์ ์ ์๊ฒ ๋จ. ex) ์ฒ์์๋ ์์ง๋ง ๋ฐ์ , ๊น์ด์ง์๋ก ๋ ๊ตฌ์ฒดํ๋ ๊ทธ๋ฆผ์

7-7) ๋ํ์ CNN
1) LeNet
'Deep Learning > 2023 DL ๊ธฐ์ด ์ด๋ก ๊ณต๋ถ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ฐ๋ฐ๋ฅ๋ถํฐ ์์ํ๋ ๋ฅ๋ฌ๋ 1] chap6(ํ์ต ๊ด๋ จ ๊ธฐ์ ๋ค) (0) | 2023.07.08 |
---|---|
[ํ์ด์ฌ ๋ฅ๋ฌ๋ ํ์ดํ ์น] Part2 (0) | 2023.07.08 |
[๋ฐ๋ฐ๋ฅ๋ถํฐ ์์ํ๋ ๋ฅ๋ฌ๋ 1] chap8 ๋ฅ๋ฌ๋ (0) | 2023.07.08 |
[ํ์ด์ฌ ๋ฅ๋ฌ๋ ํ์ดํ ์น] Part3 (0) | 2023.07.08 |
[ํ์ด์ฌ ๋ฅ๋ฌ๋ ํ์ดํ ์น] Part5 (0) | 2023.07.08 |