Dalam CNN, apakah setiap filter baru memiliki bobot berbeda untuk setiap saluran input, atau apakah bobot yang sama dari setiap filter digunakan di seluruh saluran input?


28

Pemahaman saya adalah bahwa lapisan convolutional dari jaringan saraf convolutional memiliki empat dimensi: input_channels, filter_height, filter_width, number_of_filters. Lebih jauh, ini adalah pemahaman saya bahwa setiap filter baru akan berbelit-belit di atas SEMUA input_channels (atau fitur / peta aktivasi dari lapisan sebelumnya).

NAMUN, grafik di bawah ini dari CS231 menunjukkan setiap filter (berwarna merah) diterapkan pada SINGLE CHANNEL, daripada filter yang sama digunakan di seluruh saluran. Ini sepertinya menunjukkan bahwa ada filter terpisah untuk setiap saluran (dalam hal ini saya mengasumsikan mereka adalah tiga saluran warna dari gambar input, tetapi hal yang sama berlaku untuk semua saluran input).

Ini membingungkan - apakah ada filter unik berbeda untuk setiap saluran input?

masukkan deskripsi gambar di sini

Sumber: http://cs231n.github.io/convolutional-networks/

Gambar di atas tampaknya bertentangan dengan kutipan dari "Fundamentals of Deep Learning" O'reilly :

"... filter tidak hanya beroperasi pada satu peta fitur. Mereka beroperasi pada seluruh volume peta fitur yang telah dihasilkan pada lapisan tertentu ... Akibatnya, peta fitur harus dapat beroperasi lebih dari volume, bukan hanya daerah "

... Selain itu, menurut pemahaman saya bahwa gambar-gambar di bawah ini menunjukkan filter SAMA SAMA hanya berbelit-belit di ketiga saluran input (bertentangan dengan apa yang ditampilkan dalam gambar CS231 di atas):

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini


Jawaban:


13

Dalam jaringan saraf convolutional, apakah ada filter unik untuk setiap saluran input atau apakah filter baru yang sama digunakan di semua saluran input?

Mantan. Sebenarnya ada kernel terpisah yang ditentukan untuk setiap saluran input / kombinasi saluran keluaran.

Biasanya untuk arsitektur CNN, dalam satu filter seperti yang dijelaskan oleh number_of_filtersparameter Anda , ada satu kernel 2D per saluran input. Ada input_channels * number_of_filtersset bobot, yang masing-masing menggambarkan kernel konvolusi. Jadi diagram yang menunjukkan satu set bobot per saluran input untuk setiap filter sudah benar. Diagram pertama juga menunjukkan dengan jelas bahwa hasil penerapan kernel tersebut digabungkan dengan menjumlahkannya dan menambahkan bias untuk setiap saluran keluaran.

Ini juga dapat dilihat sebagai menggunakan konvolusi 3D untuk setiap saluran keluaran, yang kebetulan memiliki kedalaman yang sama dengan input. Itulah yang ditunjukkan diagram kedua Anda, dan juga apa yang akan dilakukan banyak perpustakaan secara internal. Secara matematis ini adalah hasil yang sama (asalkan kedalaman benar-benar cocok), meskipun jenis lapisan biasanya diberi label sebagai "Conv2D" atau serupa. Demikian pula jika jenis input Anda secara inheren 3D, seperti voxels atau video, maka Anda mungkin menggunakan lapisan "Conv3D", tetapi secara internal itu bisa diimplementasikan sebagai konvolusi 4D.


terima kasih atas penjelasan ini. Kedengarannya seperti setiap filter sebenarnya memiliki jumlah input_channelsversi dengan bobot berbeda . Apakah Anda memiliki sumber "resmi" yang menegaskan pemahaman ini?
Ryan Chase

@RyanChase: Ya itu benar. Saya hanya akan mengarahkan Anda ke kursus Andrew Ng tentang CNN - mulai dari sini dengan bagaimana gambar warna akan diproses: coursera.org/learn/convolutional-neural-networks/lecture/ctQZz/…
Neil Slater

Saya ingin mencatat bahwa, dalam sumber itu ( cs231n.github.io/convolutional-networks ), filter (bobot atau kernesl) adalah volume (yaitu 3 dimensi), dan mereka memiliki dimensi 3 yang sama memiliki salah satu input. volume. Selanjutnya, seperti yang (setidaknya) sekarang dinyatakan dalam sumber itu, volume telah diiris melintasi dimensi ke-3 untuk memvisualisasikan aplikasi filter dengan lebih baik ke volume input. Saya tidak berpikir bahwa, secara umum, "ada kernel terpisah yang ditentukan untuk setiap saluran input / kombinasi saluran keluaran." benar.
nbro

Perhatikan bahwa filter (atau kernel) adalah bobot yang perlu dipelajari (yaitu tidak diperbaiki, tetapi sebenarnya parameter dari CNN). Bisa jadi mereka (yaitu irisan filter), pada akhirnya, sama di dimensi ke-3.
nbro

@nbro: Ya, Anda dapat menerapkan konvolusi 2D melintasi banyak irisan 2D sebagai konvolusi 3D tunggal dengan kedalaman kernel yang sama dengan jumlah saluran. Secara matematis ini identik dengan deskripsi saya. Anda juga dapat melihatnya sebagai jaringan umpan maju terputus yang terhubung sepenuhnya dengan bobot bersama (banyak di antaranya adalah nol). Jawaban ini berfokus pada apa pandangan dari filter 2D, karena OP bertanya tentang bagaimana filter 2D diatur. Mereka sebenarnya bisa diatur menjadi kernel 3D yang lebih besar, tetapi mereka masih diterapkan sebagai kernel 2D menggunakan "trik" yang konvolusi 3D setara.
Neil Slater

12

Gambar berikut yang Anda gunakan dalam pertanyaan Anda, sangat akurat menggambarkan apa yang terjadi. Ingat bahwa setiap elemen filter 3D (kubus abu-abu) terdiri dari nilai ( 3x3x3=27nilai) yang berbeda. Jadi, tiga filter 2D ukuran yang berbeda 3x3dapat digabungkan untuk membentuk filter ukuran 3D yang satu ini 3x3x3.

convnet2D

The 3x3x3RGB potongan dari gambar yang dikalikan elementwise oleh penyaring 3D (ditampilkan sebagai abu-abu). Dalam hal ini, filter memiliki 3x3x3=27bobot. Ketika bobot ini dikalikan elemen bijak dan kemudian dijumlahkan, itu memberi satu nilai.


Jadi, apakah ada filter terpisah untuk setiap saluran input?

IYA NIH , ada filter 2D sebanyak jumlah saluran input dalam gambar. Namun , ada baiknya jika Anda berpikir bahwa untuk matriks input dengan lebih dari satu saluran, hanya ada satu filter 3D (seperti yang ditunjukkan pada gambar di atas).


Lalu mengapa ini disebut konvolusi 2D (jika filter adalah 3D dan matriks input adalah 3D)?

Ini adalah konvolusi 2D karena langkah filter adalah sepanjang dimensi tinggi dan lebar saja ( BUKAN kedalaman) dan oleh karena itu, output yang dihasilkan oleh konvolusi ini juga merupakan matriks 2D. Jumlah arah gerakan filter menentukan dimensi konvolusi.

Catatan: Jika Anda membangun pemahaman Anda dengan memvisualisasikan filter 3D tunggal alih-alih banyak filter 2D (satu untuk setiap layer), maka Anda akan dengan mudah memahami arsitektur CNN canggih seperti Resnet, InceptionV3, dll.


ini adalah penjelasan yang baik, tetapi lebih khusus pertanyaan yang saya coba pahami adalah apakah filter yang beroperasi pada setiap saluran input adalah salinan dari bobot yang sama, atau bobot yang sama sekali berbeda. Ini sebenarnya tidak ditampilkan dalam gambar dan pada kenyataannya bagi saya bahwa jenis gambar menunjukkan bahwa itu adalah bobot yang sama yang diterapkan pada setiap saluran (karena warnanya sama) ... Per jawaban @neil slater, sepertinya masing-masing Filter sebenarnya memiliki sejumlah input_channelsversi dengan bobot berbeda . Jika ini juga pengertian Anda, apakah ada sumber "resmi" yang mengkonfirmasi hal ini?
Ryan Chase

Ya, memang, itu juga pemahaman saya. Bagi saya, itu jelas ketika saya mencoba memikirkan kubus kelabu yang terdiri dari 27 nilai bobot yang berbeda. Ini berarti bahwa ada 3 filter 2D berbeda daripada filter 2D yang sama diterapkan pada setiap lapisan input.
Mohsin Bukhari

Saya tidak dapat menemukan sumber resmi untuk mengkonfirmasi hal ini. Namun, ketika saya mencoba untuk membungkus kepala saya di sekitar konsep yang sama ini, saya membuat input boneka dan filter berat di Tensorflow dan mengamati hasilnya. Saya puas dengan itu. Jika saya menemukan penjelasan resmi . Saya akan mengedit jawaban saya di atas.
Mohsin Bukhari

Jika Anda mengikuti jalur Tensorflow. Anda dapat mencetak filter berat Anda setelah memperlihatkan sampel input dummy CNN layer Anda.
Mohsin Bukhari

@Moshsin Bukhari Saya pasti akan mencoba mengeksplorasi filter dalam TensorFlow. Apakah Anda bersedia membagikan kode Anda tentang bagaimana Anda menjelajahi tentang apa yang terkandung dalam filter? Apakah Anda dapat mencetak nilai filter pada setiap langkah di jaringan misalnya?
Ryan Chase

3

Saya menindaklanjuti jawaban di atas dengan contoh konkret dengan harapan untuk lebih memperjelas bagaimana konvolusi bekerja sehubungan dengan saluran input dan output dan bobot, masing-masing:

Biarkan contohnya sebagai berikut (wrt to 1 layer convolutional):

  • tensor input adalah 9x9x5, yaitu 5 saluran input, jadi input_channels=5
  • ukuran filter / kernel 4x4 dan langkahnya adalah 1
  • tensor output adalah 6x6x56, yaitu 56 saluran output, jadi output_channels=56
  • jenis padding adalah 'VALID' (yaitu tanpa padding)

Kami mencatat bahwa:

  • karena input memiliki 5 saluran, dimensi filter menjadi 4x4x5, yaitu ada 5 filter 2D unik dan unik berukuran 4x4 (masing-masing memiliki 16 bobot); untuk berbelit-belit dalam input ukuran 9x9x5 filter menjadi 3D dan harus berukuran 4x4x5
  • oleh karena itu: untuk setiap saluran input, terdapat filter 2D yang berbeda dengan masing-masing 16 bobot. Dengan kata lain, jumlah filter 2D cocok dengan jumlah saluran input
  • karena ada 56 saluran keluaran, harus ada 56 filter 3-dimensi W0, W1, ..., W55 dari ukuran 4x4x5 (lih. dalam grafik CS231 ada 2 filter 3-dimensi W0, W1 untuk menjelaskan 2 output saluran), di mana dimensi ke-3 ukuran 5 mewakili tautan ke 5 saluran input (lih. dalam grafik CS231 setiap filter 3D W0, W1 memiliki dimensi ke-3 3, yang cocok dengan 3 saluran input)
  • oleh karena itu: jumlah filter 3D sama dengan jumlah saluran output

Lapisan konvolusional demikian mengandung:

56 filter 3 dimensi dengan ukuran 4x4x5 (= 80 masing-masing bobot berbeda) untuk memperhitungkan 56 saluran output di mana masing-masing memiliki nilai untuk dimensi 3 dari 5 agar cocok dengan 5 saluran input. Total ada

number_of_filters=input_channel*output_channels=5*56=280

Filter 2D ukuran 4x4 (yaitu 280x16 bobot berbeda total).


0

Hanya ada batasan dalam 2D. Mengapa?

Bayangkan sebuah lapisan yang terhubung sepenuhnya.

Ini akan sangat besar, setiap neuron akan terhubung ke mungkin 1000x1000x3 input neuron. Tetapi kita tahu bahwa memproses piksel terdekat itu masuk akal, oleh karena itu kami membatasi diri pada lingkungan 2D kecil, sehingga setiap neuron terhubung ke hanya 3x3 dekat neuron dalam 2D. Kami tidak tahu hal seperti itu tentang saluran, jadi kami terhubung ke semua saluran.

Tetap saja, akan ada terlalu banyak bobot. Tetapi karena invarian terjemahan, filter yang berfungsi dengan baik di satu area paling mungkin berguna di area yang berbeda. Jadi kami menggunakan set bobot yang sama untuk 2D. Sekali lagi, tidak ada invarian terjemahan seperti itu di antara saluran, jadi tidak ada batasan seperti itu di sana.


0

Lihat bagian "Konektivitas Lokal" di http://cs231n.github.io/convolutional-networks/ dan geser 7-18.

Hyperparameter "Bidang Reseptif" filter hanya ditentukan oleh tinggi & lebar, karena kedalaman ditetapkan dengan mendahului kedalaman lapisan.

CATATAN bahwa "Tingkat konektivitas di sepanjang sumbu kedalaman selalu sama dengan KEDALAMAN volume input" -atau- KEDALAMAN peta aktivasi (jika lapisan berikutnya).

Secara intuitif, ini harus karena fakta bahwa data saluran gambar disisipkan, bukan planar. Dengan cara ini, menerapkan filter dapat dicapai hanya dengan penggandaan vektor kolom.

CATATAN bahwa Jaringan Konvolusional mempelajari semua parameter filter (termasuk dimensi kedalaman) dan semuanya " hw input_layer_depth + 1 (bias)" total .


0

Saya merekomendasikan bab 2.2.1 dari tesis master saya sebagai jawaban. Untuk menambah jawaban yang tersisa:

Keras adalah teman Anda untuk memahami apa yang terjadi:

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())

memberi

_________________________________________________________________
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

Cobalah untuk merumuskan opsi Anda. Apa artinya bagi parameter jika ada hal lain yang terjadi?

2400=32(355)

Pendekatan ini juga membantu Anda dengan jenis lapisan lainnya, tidak hanya lapisan konvolusional.

Harap perhatikan juga bahwa Anda bebas menerapkan solusi yang berbeda, yang mungkin memiliki sejumlah parameter lainnya.


0

Hanya untuk membuat dua detail benar-benar jelas:

NN3×3N2N

N2N3×3×

Cara termudah untuk meyakinkan diri sendiri tentang hal ini adalah membayangkan apa yang terjadi dalam skenario lain dan melihat bahwa perhitungannya menjadi merosot - yaitu, jika Anda tidak melakukan interleave dan menggabungkan kembali hasilnya, maka output yang berbeda tidak akan benar-benar melakukan apa pun - mereka akan memiliki efek yang sama dengan output tunggal dengan bobot gabungan.


0

Bagi siapa pun yang mencoba memahami bagaimana konvolusi dihitung, berikut ini cuplikan kode yang berguna di 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))

Menjalankan ini memberikan output sebagai berikut:

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])

Perhatikan bagaimana setiap saluran konvolusi merangkum semua output saluran sebelumnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.