CNN에서 각각의 새 필터는 각 입력 채널에 대해 서로 다른 가중치를 갖거나 입력 채널에서 사용되는 각 필터의 ​​동일한 가중치를 사용합니까?


28

내 이해는 회선 신경망의 회선 레이어는 input_channels, filter_height, filter_width, number_of_filters의 네 가지 차원을 가지고 있다는 것입니다. 또한 각각의 새로운 필터가 모든 input_channels (또는 이전 레이어의 기능 / 활성화 맵)에 대해 복잡하다는 것을 이해합니다.

그러나 CS231의 아래 그림은 채널 전체에서 사용되는 동일한 필터가 아니라 단일 채널에 적용되는 각 필터 (빨간색)를 보여줍니다. 이것은 각 채널에 대해 별도의 필터가 있음을 나타냅니다 (이 경우 입력 이미지의 세 가지 색상 채널이라고 가정하지만 모든 입력 채널에 동일하게 적용됨).

혼란 스럽습니다. 각 입력 채널마다 다른 고유 필터가 있습니까?

여기에 이미지 설명을 입력하십시오

출처 : http://cs231n.github.io/convolutional-networks/

위의 이미지는 오라일리의 "딥 러닝의 기초" 에서 발췌 한 내용과 모순되는 것 같습니다 .

"... 필터는 단일 기능 맵에서만 작동하지 않습니다. 필터는 특정 레이어에서 생성 된 전체 기능 맵에서 작동합니다. 결과적으로, 기능 맵은 볼륨에서 작동 할 수 있어야합니다. 지역뿐만 아니라 "

... 또한 아래의 이미지는 SAME 필터가 세 입력 채널 모두에 걸쳐 있음을 나타냅니다 (위 CS231 그래픽에 표시된 것과 모순됨).

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오


답변:


13

컨볼 루션 신경망에는 각 입력 채널에 고유 한 필터가 있습니까? 아니면 모든 입력 채널에서 동일한 새 필터가 사용됩니까?

전자. 실제로 각 입력 채널 / 출력 채널 조합에 대해 별도의 커널이 정의되어 있습니다.

일반적으로 CNN 아키텍처의 경우 number_of_filters매개 변수 로 설명 된 단일 필터에서 입력 채널당 하나의 2D 커널이 있습니다. input_channels * number_of_filters가중치 세트 가 있으며 각각 가중치 키는 회선 커널을 설명합니다. 따라서 각 필터의 ​​입력 채널당 하나의 가중치 세트를 보여주는 다이어그램이 정확합니다. 첫 번째 다이어그램은 이러한 커널을 적용한 결과를 합산하고 각 출력 채널에 바이어스를 추가하여 결합 된 결과를 명확하게 보여줍니다.

이것은 입력과 동일한 깊이를 갖는 각 출력 채널에 대해 3D 컨벌루션을 사용하는 것으로 볼 수 있습니다 . 두 번째 다이어그램에 표시되는 내용과 내부적으로 많은 라이브러리가 수행하는 내용입니다. 레이어 유형은 일반적으로 "Conv2D"또는 이와 유사한 레이블이 있지만 수학적으로는 동일한 결과입니다 (깊이가 정확하게 일치하는 경우). 마찬가지로 입력 유형이 복셀 또는 비디오와 같이 본질적으로 3D 인 경우 "Conv3D"레이어를 사용할 수 있지만 내부적으로 4D 컨볼 루션으로 구현할 수 있습니다.


이 설명에 감사드립니다. 각 필터에 실제로 가중치input_channels다른 여러 버전 이있는 것처럼 들립니다 . 이 이해를 확인하는 "공식"소스가 있습니까?
Ryan Chase

@RyanChase : 그렇습니다. CNN
Neil Slater

해당 소스 ( cs231n.github.io/convolutional-networks )에서 필터 (무게 또는 Kernesl)는 볼륨 (예 : 3 차원)이며 동일한 3 차원이 입력 중 하나입니다. 음량. 또한, 그 소스에서 (적어도) 언급 되었 듯이, 입력 볼륨에 대한 필터의 적용을 더 잘 시각화하기 위해 볼륨이 3 차원으로 슬라이스되었습니다. 나는 일반적으로 "각 입력 채널 / 출력 채널 조합에 대해 별도의 커널이 정의되어있다"고 생각하지 않습니다. 맞다.
nbro

필터 (또는 커널)는 학습해야하는 가중치입니다 (즉, 고정되지는 않지만 실제로 CNN의 매개 변수 임). 마지막에 3 차원에서 동일한 것 (즉, 필터 슬라이스) 일 수 있습니다.
nbro

@ nbro : 예 구현할 수 있습니다 . 채널 수와 동일한 커널 깊이를 가진 단일 3D 컨볼 루션으로 여러 2D 슬라이스에서 2D 컨볼 루션을 . 수학적으로 이것은 내 설명과 동일합니다. 또한 공유 가중치를 갖는 잘린 완전히 연결된 피드 포워드 네트워크 (대부분 0)로 볼 수도 있습니다. 이 답변은 OP가 2D 필터가 어떻게 배열되는지에 대해 질문하기 때문에 2D 필터의 관점에 중점을 둡니다. 그것들은 실제로 더 큰 3D 커널로 배열 될 수 있지만, 3D 컨볼 루션이 동등하다는 "트릭"을 사용하여 2D 커널로 여전히 적용됩니다.
닐 슬레이터

12

귀하의 질문에 사용한 다음 그림은 현재 상황을 매우 정확하게 설명합니다. 의 각 요소는3D 필터 (회색 큐브) 는 다른 값 ( 3x3x3=27값)으로 구성됩니다. 그래서, 세 가지 다른 차원 필터 크기는 3x3이것 형성하기 위해 연결될 수있는 3D 필터 크기를 3x3x3.

convnet2D

그림의 3x3x3RGB 청크 에 3D 필터 (회색으로 표시) 가 요소 별로 곱해 집니다. 이 경우 필터에는 가중치가 있습니다. 이 가중치를 요소별로 곱한 다음 합산하면 하나의 값을 제공합니다. 3x3x3=27


각 입력 채널마다 별도의 필터가 있습니까?

, 이미지에 입력 채널 수만큼 2D 필터 가 있습니다. 그러나 둘 이상의 채널이있는 입력 매트릭스의 경우 위의 이미지에 표시된 것처럼 하나의 3D 필터 만 있다고 생각하면 도움이됩니다 .


그렇다면 왜 이것을 2D 컨벌루션 (필터가 3D이고 입력 매트릭스가 3D 인 경우)이라고합니까?

이것은 필터의 보폭이 높이와 너비 치수만을 따르 므로 ( 깊이 아님)이 컨벌루션에 의해 생성 된 출력도 2D 매트릭스이므로 2D 컨벌루션입니다. 필터의 이동 방향 수에 따라 컨볼 루션의 크기가 결정됩니다.

참고 : 여러 2D 필터 대신 단일 3D 필터 를 시각화하여 이해를 구축하는 경우 (각 레이어 당 하나씩) 하면 Resnet, InceptionV3 등과 같은 고급 CNN 아키텍처를 쉽게 이해할 수 있습니다.


이것은 좋은 설명이지만,보다 구체적으로 이해하려고하는 질문은 각 입력 채널에서 작동하는 필터가 동일한 가중치의 사본인지 또는 완전히 다른 가중치인지 여부입니다. 이것은 실제로 이미지에 표시되지 않으며 실제로 이미지 종류는 각 채널에 동일한 가중치가 적용됨을 나타냅니다 (동일한 색상이므로). @ @il slater의 답변에 따르면, 각각의 소리 필터에는 실제로 가중치 input_channels다른 여러 버전이 있습니다 . 이것이 또한 귀하의 이해라면, 이것을 확인하는 "공식적인"출처가 있습니까?
Ryan Chase

그렇습니다, 그것은 저의 이해이기도합니다. 저에게는 그레이 큐브가 27 가지 무게 값으로 구성되어 있다고 생각했을 때 분명했습니다 . 즉, 각 입력 레이어에 동일한 2D 필터가 적용되는 3 개의 2D 필터가 있습니다.
Mohsin Bukhari

이를 확인하는 공식 출처를 찾을 수 없습니다. 그러나이 같은 개념으로 머리를 감싸려고 할 때 Tensorflow에서 더미 입력 및 가중치 필터를 만들고 출력을 관찰했습니다. 나는 그것에 만족했다. 공식적인 설명을 찾으면 위의 답변을 편집하겠습니다.
Mohsin Bukhari

Tensorflow 경로를 따르는 경우. 더미 CNN 레이어에 입력 샘플을 표시 한 후 가중치 필터를 인쇄 할 수 있습니다.
Mohsin Bukhari

@ Moshsin Bukhari 나는 TensorFlow 내에서 필터를 탐색하려고합니다. 필터에 포함 된 내용을 탐색하는 방법에 대한 코드를 기꺼이 공유 하시겠습니까? 예를 들어 네트워크의 각 단계에서 필터 값을 인쇄 할 수 있습니까?
Ryan Chase

3

입력 및 출력 채널과 가중치에 대해 컨볼 루션이 어떻게 작동하는지 더 명확하게 설명하기 위해 위의 답변을 구체적인 예를 들어 설명합니다.

예제를 다음과 같이 보자 (wrt to 1 convolutional layer) :

  • 입력 텐서는 9x9x5, 즉 5 개의 입력 채널이므로 input_channels=5
  • 필터 / 커널 크기는 4x4이고 보폭은 1입니다.
  • 출력 텐서는 6x6x56, 즉 56 개의 출력 채널이므로 output_channels=56
  • 패딩 유형은 'VALID'입니다 (즉, 패딩 없음)

우리는 다음에 주목한다 :

  • 입력에 5 개의 채널이 있기 때문에, 필터 치수는 4x4x5가됩니다. 즉, 크기가 4x4 인 5 개의 분리 된 고유 한 2D 필터가 있습니다 (즉, 각각 16 개의 가중치를 가짐). 9x9x5 크기의 입력을 통해 변환하려면 필터가 3D가되고 4x4x5 크기 여야합니다.
  • 따라서 각 입력 채널마다 16 개의 서로 다른 가중치를 가진 고유 한 2D 필터가 있습니다. 다시 말해, 2D 필터의 수는 입력 채널의 수와 일치합니다
  • 56 개의 출력 채널이 있으므로 4x4x5 크기의 56 개의 3 차원 필터 W0, W1, ..., W55가 있어야합니다 (CS231 그래픽에서 2 개의 3 차원 필터 W0, W1이 2 개의 출력을 설명합니다) 크기 5의 3 차원은 5 개의 입력 채널에 대한 링크를 나타냅니다 (CS231 그래픽에서 각 3D 필터 W0 참조, W1은 3 개의 입력 채널과 일치하는 3 차원 3을 가짐)
  • 따라서 : 3D 필터의 수는 출력 채널의 수와 같습니다

이 컨볼 루션 레이어에는 다음이 포함됩니다.

56 크기 4x4x5 (각각 80 개의 다른 가중치)의 3 차원 필터는 5 개의 입력 채널과 일치하는 3 차원의 값이 5 인 56 개의 출력 채널을 설명합니다. 전체적으로

number_of_filters=input_channel*output_channels=5*56=280

크기가 4x4 인 2D 필터 (예 : 총 280x16 다른 가중치)


0

2D에는 제한이 있습니다. 왜?

완전히 연결된 레이어를 상상해보십시오.

그것은 엄청나게 클 것입니다. 각 뉴런은 아마도 1000x1000x3 입력 뉴런에 연결될 것입니다. 그러나 우리는 주변 픽셀을 처리하는 것이 의미가 있으므로 작은 2D 이웃으로 제한하므로 각 뉴런은 2D의 3x3 근처 뉴런에만 연결됩니다. 우리는 채널에 대해 그런 것을 알지 못하므로 모든 채널에 연결합니다.

여전히 가중치가 너무 많습니다. 그러나 변환 불일치로 인해 한 영역에서 잘 작동하는 필터가 다른 영역에서 가장 유용 할 것입니다. 따라서 2D에서 동일한 가중치 집합을 사용합니다. 다시 말하지만, 채널간에 그러한 변환 불일치가 없으므로 그러한 제한이 없습니다.


0

http://cs231n.github.io/convolutional-networks/의 "로컬 연결"섹션 및 슬라이드 7-18을 참조하십시오 .

필터의 "수용 필드"하이퍼 파라미터는 깊이가 이전 레이어의 깊이에 의해 고정되므로 높이 및 너비만으로 정의됩니다.

"깊이 축을 따라 연결되는 정도는 항상 입력 볼륨의 깊이와 같습니다"또는 활성화 맵의 깊이 (나중 계층의 경우).

직관적으로 이것은 이미지 채널 데이터가 평면이 아닌 인터리브되기 때문입니다. 이러한 방식으로, 필터를 적용하는 것은 열 벡터 곱셈에 의해 간단히 달성 될 수있다.

Convolutional Network는 모든 필터 매개 변수 (깊이 차원 포함)를 학습하며 총 "h w input_layer_depth + 1 (바이어스)"입니다.


0

석사 논문 2.2.1 장을 추천합니다 답으로 추천한다. 나머지 답변에 추가하려면 다음을 수행하십시오.

Keras는 어떻게되는지 이해하는 친구입니다.

from keras.models import Sequential
from keras.layers import Conv2D

model = Sequential()
model.add(Conv2D(32, input_shape=(28, 28, 3),
          kernel_size=(5, 5),
          padding='same',
          use_bias=False))
model.add(Conv2D(17, (3, 3), padding='same', use_bias=False))
model.add(Conv2D(13, (3, 3), padding='same', use_bias=False))
model.add(Conv2D(7, (3, 3), padding='same', use_bias=False))
model.compile(loss='categorical_crossentropy', optimizer='adam')

print(model.summary())

준다

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 28, 28, 32)        2400      
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 28, 28, 17)        4896      
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 28, 28, 13)        1989      
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 28, 28, 7)         819       
=================================================================
Total params: 10,104

옵션을 공식화하십시오. 다른 경우라면 매개 변수에 어떤 의미가 있습니까?

힌트: 2400=32(55)

이 방법은 컨볼 루션 레이어뿐만 아니라 다른 레이어 유형에도 도움이됩니다.

또한 다른 매개 변수를 가질 수있는 다른 솔루션을 자유롭게 구현할 수 있습니다.


0

두 가지 세부 사항을 완전히 명확하게하기 위해 :

당신이 가지고 있다고 2D 입력 채널 2D 출력 채널. 2D의 총 수× 필터 무게는 실제로 2. 그러나 3D 컨벌루션이 어떻게 영향을 받는지, 즉 모든 입력 채널이 모든 출력 채널에 하나의 2D 레이어를 제공하는 경우 각 출력 채널은 처음에 2D 레이어는 어떻게 결합됩니까?

이것은 내가 본 거의 모든 간행물에서 다뤄지는 경향이 있지만 핵심 개념은 2 2D 출력 채널은 서로 인터리브되어 셔플 카드 데크와 같은 출력 채널을 합산하기 전에 컨볼 루션의 채널 치수 (그림에 나와 있지 않음)를 따라 실제로 완전히 연결된 레이어가 있다는 것을 알면이 모든 것이 논리적입니다! 모든 입력 2D 채널에 고유 한 값을 곱한 값×필터는 단일 출력 채널에 2D 출력 레이어를 제공합니다. 일단 결합되면 모든 출력 레이어는 모든 입력 레이어의 조합입니다×독특한 필터. 모든 기여에 대한 모든 것입니다.

이를 자신에게 확신시키는 가장 쉬운 방법은 다른 시나리오에서 발생하는 상황을 상상하고 계산이 저하되는 것을 확인하는 것입니다. 즉, 결과를 인터리브하고 다시 결합하지 않으면 다른 출력이 실제로 아무것도하지 않습니다. '가중이 결합 된 단일 출력과 동일한 효과를 갖습니다.


0

컨볼 루션이 어떻게 계산되는지 이해하려는 사람이라면 Pytorch의 유용한 코드 스 니펫을 참조하십시오.

batch_size = 1
height = 3 
width = 3
conv1_in_channels = 2
conv1_out_channels = 2
conv2_out_channels = 2
kernel_size = 2
# (N, C_in, H, W) is shape of all tensors. (batch_size, channels, height, width)
input = torch.Tensor(np.arange(0, batch_size*height*width*in_channels).reshape(batch_size, in_channels, height, width))
conv1 = nn.Conv2d(in_channels, conv1_out_channels, kernel_size, bias=False) # no bias to make calculations easier
# set the weights of the convolutions to make the convolutions easier to follow
nn.init.constant_(conv1.weight[0][0], 0.25)
nn.init.constant_(conv1.weight[0][1], 0.5)
nn.init.constant_(conv1.weight[1][0], 1) 
nn.init.constant_(conv1.weight[1][1], 2) 
out1 = conv1(input) # compute the convolution

conv2 = nn.Conv2d(conv1_out_channels, conv2_out_channels, kernel_size, bias=False)
nn.init.constant_(conv2.weight[0][0], 0.25)
nn.init.constant_(conv2.weight[0][1], 0.5)
nn.init.constant_(conv2.weight[1][0], 1) 
nn.init.constant_(conv2.weight[1][1], 2) 
out2 = conv2(out1) # compute the convolution

for tensor, name in zip([input, conv1.weight, out1, conv2.weight, out2], ['input', 'conv1', 'out1', 'conv2', 'out2']):
    print('{}: {}'.format(name, tensor))
    print('{} shape: {}'.format(name, tensor.shape))

이것을 실행하면 다음과 같은 결과가 나타납니다.

input: tensor([[[[ 0.,  1.,  2.],
          [ 3.,  4.,  5.],
          [ 6.,  7.,  8.]],

         [[ 9., 10., 11.],
          [12., 13., 14.],
          [15., 16., 17.]]]])
input shape: torch.Size([1, 2, 3, 3])
conv1: Parameter containing:
tensor([[[[0.2500, 0.2500],
          [0.2500, 0.2500]],

         [[0.5000, 0.5000],
          [0.5000, 0.5000]]],


        [[[1.0000, 1.0000],
          [1.0000, 1.0000]],

         [[2.0000, 2.0000],
          [2.0000, 2.0000]]]], requires_grad=True)
conv1 shape: torch.Size([2, 2, 2, 2])
out1: tensor([[[[ 24.,  27.],
          [ 33.,  36.]],

         [[ 96., 108.],
          [132., 144.]]]], grad_fn=<MkldnnConvolutionBackward>)
out1 shape: torch.Size([1, 2, 2, 2])
conv2: Parameter containing:
tensor([[[[0.2500, 0.2500],
          [0.2500, 0.2500]],

         [[0.5000, 0.5000],
          [0.5000, 0.5000]]],


        [[[1.0000, 1.0000],
          [1.0000, 1.0000]],

         [[2.0000, 2.0000],
          [2.0000, 2.0000]]]], requires_grad=True)
conv2 shape: torch.Size([2, 2, 2, 2])
out2: tensor([[[[ 270.]],

         [[1080.]]]], grad_fn=<MkldnnConvolutionBackward>)
out2 shape: torch.Size([1, 2, 1, 1])

컨벌루션의 각 채널이 이전의 모든 채널 출력에서 ​​합산되는 방식에 주목하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.