Jawaban:
Saya ingin menjelaskan dengan gambar dari C3D .
Singkatnya, arah konvolusional & bentuk keluaran itu penting!
↑↑↑↑↑ 1D Konvolusi - Dasar ↑↑↑↑↑
import tensorflow as tf
import numpy as np
sess = tf.Session()
ones_1d = np.ones(5)
weight_1d = np.ones(3)
strides_1d = 1
in_1d = tf.constant(ones_1d, dtype=tf.float32)
filter_1d = tf.constant(weight_1d, dtype=tf.float32)
in_width = int(in_1d.shape[0])
filter_width = int(filter_1d.shape[0])
input_1d = tf.reshape(in_1d, [1, in_width, 1])
kernel_1d = tf.reshape(filter_1d, [filter_width, 1, 1])
output_1d = tf.squeeze(tf.nn.conv1d(input_1d, kernel_1d, strides_1d, padding='SAME'))
print sess.run(output_1d)
↑↑↑↑↑ Konvolusi 2D - Dasar ↑↑↑↑↑
ones_2d = np.ones((5,5))
weight_2d = np.ones((3,3))
strides_2d = [1, 1, 1, 1]
in_2d = tf.constant(ones_2d, dtype=tf.float32)
filter_2d = tf.constant(weight_2d, dtype=tf.float32)
in_width = int(in_2d.shape[0])
in_height = int(in_2d.shape[1])
filter_width = int(filter_2d.shape[0])
filter_height = int(filter_2d.shape[1])
input_2d = tf.reshape(in_2d, [1, in_height, in_width, 1])
kernel_2d = tf.reshape(filter_2d, [filter_height, filter_width, 1, 1])
output_2d = tf.squeeze(tf.nn.conv2d(input_2d, kernel_2d, strides=strides_2d, padding='SAME'))
print sess.run(output_2d)
↑↑↑↑↑ Konvolusi 3D - Dasar ↑↑↑↑↑
ones_3d = np.ones((5,5,5))
weight_3d = np.ones((3,3,3))
strides_3d = [1, 1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_3d = tf.constant(weight_3d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
in_depth = int(in_3d.shape[2])
filter_width = int(filter_3d.shape[0])
filter_height = int(filter_3d.shape[1])
filter_depth = int(filter_3d.shape[2])
input_3d = tf.reshape(in_3d, [1, in_depth, in_height, in_width, 1])
kernel_3d = tf.reshape(filter_3d, [filter_depth, filter_height, filter_width, 1, 1])
output_3d = tf.squeeze(tf.nn.conv3d(input_3d, kernel_3d, strides=strides_3d, padding='SAME'))
print sess.run(output_3d)
↑↑↑↑↑ Konvolusi 2D dengan masukan 3D - LeNet, VGG, ..., ↑↑↑↑↑
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
ones_3d = np.ones((5,5,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae with in_channels
weight_3d = np.ones((3,3,in_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_3d = tf.constant(weight_3d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_3d.shape[0])
filter_height = int(filter_3d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_3d = tf.reshape(filter_3d, [filter_height, filter_width, in_channels, 1])
output_2d = tf.squeeze(tf.nn.conv2d(input_3d, kernel_3d, strides=strides_2d, padding='SAME'))
print sess.run(output_2d)
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
out_channels = 64 # 128, 256, ...
ones_3d = np.ones((5,5,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae x number of filters = 4D
weight_4d = np.ones((3,3,in_channels, out_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_4d = tf.constant(weight_4d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_4d.shape[0])
filter_height = int(filter_4d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_4d = tf.reshape(filter_4d, [filter_height, filter_width, in_channels, out_channels])
#output stacked shape is 3D = 2D x N matrix
output_3d = tf.nn.conv2d(input_3d, kernel_4d, strides=strides_2d, padding='SAME')
print sess.run(output_3d)
↑↑↑↑↑ Bonus 1x1 konv. Di CNN - GoogLeNet, ..., ↑↑↑↑↑
in_channels = 32 # 3 for RGB, 32, 64, 128, ...
out_channels = 64 # 128, 256, ...
ones_3d = np.ones((1,1,in_channels)) # input is 3d, in_channels = 32
# filter must have 3d-shpae x number of filters = 4D
weight_4d = np.ones((3,3,in_channels, out_channels))
strides_2d = [1, 1, 1, 1]
in_3d = tf.constant(ones_3d, dtype=tf.float32)
filter_4d = tf.constant(weight_4d, dtype=tf.float32)
in_width = int(in_3d.shape[0])
in_height = int(in_3d.shape[1])
filter_width = int(filter_4d.shape[0])
filter_height = int(filter_4d.shape[1])
input_3d = tf.reshape(in_3d, [1, in_height, in_width, in_channels])
kernel_4d = tf.reshape(filter_4d, [filter_height, filter_width, in_channels, out_channels])
#output stacked shape is 3D = 2D x N matrix
output_3d = tf.nn.conv2d(input_3d, kernel_4d, strides=strides_2d, padding='SAME')
print sess.run(output_3d)
- Tautan Asli: LINK
- Penulis: Martin Görner
- Twitter: @martin_gorner
- Google +: plus.google.com/+MartinGorne
↑↑↑↑↑ 1D Konvolusi dengan masukan 1D ↑↑↑↑↑
↑↑↑↑↑ 1D Konvolusi dengan masukan 2D ↑↑↑↑↑
in_channels = 32 # 3, 32, 64, 128, ...
out_channels = 64 # 3, 32, 64, 128, ...
ones_4d = np.ones((5,5,5,in_channels))
weight_5d = np.ones((3,3,3,in_channels,out_channels))
strides_3d = [1, 1, 1, 1, 1]
in_4d = tf.constant(ones_4d, dtype=tf.float32)
filter_5d = tf.constant(weight_5d, dtype=tf.float32)
in_width = int(in_4d.shape[0])
in_height = int(in_4d.shape[1])
in_depth = int(in_4d.shape[2])
filter_width = int(filter_5d.shape[0])
filter_height = int(filter_5d.shape[1])
filter_depth = int(filter_5d.shape[2])
input_4d = tf.reshape(in_4d, [1, in_depth, in_height, in_width, in_channels])
kernel_5d = tf.reshape(filter_5d, [filter_depth, filter_height, filter_width, in_channels, out_channels])
output_4d = tf.nn.conv3d(input_4d, kernel_5d, strides=strides_3d, padding='SAME')
print sess.run(output_4d)
sess.close()
1
, lalu → untuk baris 1+stride
. Konvolusi itu sendiri adalah pergeseran invariant, jadi mengapa arah konvolusi itu penting?
Mengikuti jawaban dari @runhani saya menambahkan beberapa detail lagi untuk membuat penjelasannya lebih jelas dan akan mencoba menjelaskannya sedikit lebih banyak (dan tentu saja dengan contoh dari TF1 dan TF2).
Salah satu bit tambahan utama yang saya sertakan adalah,
tf.Variable
Inilah cara Anda melakukan konvolusi 1D menggunakan TF 1 dan TF 2.
Dan untuk lebih spesifiknya, data saya memiliki bentuk berikut,
[batch size, width, in channels]
(misalnya 1, 5, 1
)[width, in channels, out channels]
(misalnya 5, 1, 4
)[batch size, width, out_channels]
(misalnya 1, 5, 4
)import tensorflow as tf
import numpy as np
inp = tf.placeholder(shape=[None, 5, 1], dtype=tf.float32)
kernel = tf.Variable(tf.initializers.glorot_uniform()([5, 1, 4]), dtype=tf.float32)
out = tf.nn.conv1d(inp, kernel, stride=1, padding='SAME')
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(out, feed_dict={inp: np.array([[[0],[1],[2],[3],[4]],[[5],[4],[3],[2],[1]]])}))
import tensorflow as tf
import numpy as np
inp = np.array([[[0],[1],[2],[3],[4]],[[5],[4],[3],[2],[1]]]).astype(np.float32)
kernel = tf.Variable(tf.initializers.glorot_uniform()([5, 1, 4]), dtype=tf.float32)
out = tf.nn.conv1d(inp, kernel, stride=1, padding='SAME')
print(out)
Ini jauh lebih sedikit bekerja dengan TF2 karena TF2 tidak perlu Session
dan variable_initializer
misalnya.
Jadi mari kita pahami apa yang dilakukan ini dengan menggunakan contoh penghalusan sinyal. Di sebelah kiri Anda mendapatkan yang asli dan di sebelah kanan Anda mendapatkan keluaran dari Konvolusi 1D yang memiliki 3 saluran keluaran.
Beberapa saluran pada dasarnya adalah beberapa representasi fitur dari sebuah input. Dalam contoh ini Anda memiliki tiga representasi yang diperoleh dari tiga filter berbeda. Saluran pertama adalah filter smoothing berbobot sama. Yang kedua adalah filter yang memberi bobot lebih pada bagian tengah filter daripada batas. Filter terakhir melakukan kebalikan dari filter kedua. Jadi Anda dapat melihat bagaimana filter yang berbeda ini menghasilkan efek yang berbeda.
Konvolusi 1D telah berhasil digunakan untuk tugas klasifikasi kalimat .
Beralih ke konvolusi 2D. Jika Anda adalah orang yang sangat belajar, kemungkinan Anda belum menemukan konvolusi 2D adalah… hampir nol. Ini digunakan di CNN untuk klasifikasi gambar, deteksi objek, dll. Serta dalam masalah NLP yang melibatkan gambar (misalnya pembuatan keterangan gambar).
Mari kita coba contoh, saya mendapat kernel konvolusi dengan filter berikut di sini,
Dan untuk lebih spesifiknya, data saya memiliki bentuk berikut,
[batch_size, height, width, 1]
(mis. 1, 340, 371, 1
)[height, width, in channels, out channels]
(misalnya 3, 3, 1, 3
)[batch_size, height, width, out_channels]
(misalnya 1, 340, 371, 3
)import tensorflow as tf
import numpy as np
from PIL import Image
im = np.array(Image.open(<some image>).convert('L'))#/255.0
kernel_init = np.array(
[
[[[-1, 1.0/9, 0]],[[-1, 1.0/9, -1]],[[-1, 1.0/9, 0]]],
[[[-1, 1.0/9, -1]],[[8, 1.0/9,5]],[[-1, 1.0/9,-1]]],
[[[-1, 1.0/9,0]],[[-1, 1.0/9,-1]],[[-1, 1.0/9, 0]]]
])
inp = tf.placeholder(shape=[None, image_height, image_width, 1], dtype=tf.float32)
kernel = tf.Variable(kernel_init, dtype=tf.float32)
out = tf.nn.conv2d(inp, kernel, strides=[1,1,1,1], padding='SAME')
with tf.Session() as sess:
tf.global_variables_initializer().run()
res = sess.run(out, feed_dict={inp: np.expand_dims(np.expand_dims(im,0),-1)})
import tensorflow as tf
import numpy as np
from PIL import Image
im = np.array(Image.open(<some image>).convert('L'))#/255.0
x = np.expand_dims(np.expand_dims(im,0),-1)
kernel_init = np.array(
[
[[[-1, 1.0/9, 0]],[[-1, 1.0/9, -1]],[[-1, 1.0/9, 0]]],
[[[-1, 1.0/9, -1]],[[8, 1.0/9,5]],[[-1, 1.0/9,-1]]],
[[[-1, 1.0/9,0]],[[-1, 1.0/9,-1]],[[-1, 1.0/9, 0]]]
])
kernel = tf.Variable(kernel_init, dtype=tf.float32)
out = tf.nn.conv2d(x, kernel, strides=[1,1,1,1], padding='SAME')
Di sini Anda dapat melihat output yang dihasilkan oleh kode di atas. Gambar pertama adalah gambar asli dan berjalan sesuai jam Anda memiliki output dari filter pertama, filter kedua, dan filter 3.
Dalam konteks jika konvolusi 2D, jauh lebih mudah untuk memahami apa arti beberapa saluran ini. Katakanlah Anda sedang melakukan pengenalan wajah. Anda dapat memikirkan (ini adalah penyederhanaan yang sangat tidak realistis tetapi mendapatkan intinya) setiap filter mewakili mata, mulut, hidung, dll. Sehingga setiap peta fitur akan menjadi representasi biner dari apakah fitur itu ada di gambar yang Anda berikan . Saya rasa saya tidak perlu menekankan bahwa untuk model pengenalan wajah, fitur tersebut sangat berharga. Informasi lebih lanjut di artikel ini .
Ini adalah ilustrasi dari apa yang saya coba utarakan.
Konvolusi 2D sangat lazim di ranah pembelajaran mendalam.
CNNs (Convolution Neural Networks) menggunakan operasi konvolusi 2D untuk hampir semua tugas computer vision (misalnya klasifikasi gambar, deteksi objek, klasifikasi video).
Sekarang semakin sulit untuk mengilustrasikan apa yang terjadi seiring dengan bertambahnya jumlah dimensi. Tetapi dengan pemahaman yang baik tentang cara kerja konvolusi 1D dan 2D, sangat mudah untuk menggeneralisasi pemahaman itu ke konvolusi 3D. Jadi begini.
Dan untuk lebih spesifiknya, data saya memiliki bentuk berikut,
[batch size, height, width, depth, in channels]
(mis. 1, 200, 200, 200, 1
)[height, width, depth, in channels, out channels]
(misalnya 5, 5, 5, 1, 3
)[batch size, width, height, width, depth, out_channels]
(misalnya 1, 200, 200, 2000, 3
)import tensorflow as tf
import numpy as np
tf.reset_default_graph()
inp = tf.placeholder(shape=[None, 200, 200, 200, 1], dtype=tf.float32)
kernel = tf.Variable(tf.initializers.glorot_uniform()([5,5,5,1,3]), dtype=tf.float32)
out = tf.nn.conv3d(inp, kernel, strides=[1,1,1,1,1], padding='SAME')
with tf.Session() as sess:
tf.global_variables_initializer().run()
res = sess.run(out, feed_dict={inp: np.random.normal(size=(1,200,200,200,1))})
import tensorflow as tf
import numpy as np
x = np.random.normal(size=(1,200,200,200,1))
kernel = tf.Variable(tf.initializers.glorot_uniform()([5,5,5,1,3]), dtype=tf.float32)
out = tf.nn.conv3d(x, kernel, strides=[1,1,1,1,1], padding='SAME')
Konvolusi 3D telah digunakan saat mengembangkan aplikasi pembelajaran mesin yang melibatkan data LIDAR (Light Detection and Ranging) yang bersifat 3 dimensi.
Baiklah Anda hampir sampai. Jadi tunggu sebentar. Mari kita lihat apa itu stride dan padding. Mereka cukup intuitif jika Anda memikirkannya.
Jika Anda melangkah melintasi koridor, Anda akan sampai di sana lebih cepat dengan langkah yang lebih sedikit. Tetapi itu juga berarti bahwa Anda mengamati sekeliling yang lebih rendah daripada jika Anda berjalan melintasi ruangan. Sekarang mari kita perkuat pemahaman kita dengan gambar yang indah juga! Mari kita pahami ini melalui konvolusi 2D.
Saat Anda menggunakan tf.nn.conv2d
misalnya, Anda perlu mengaturnya sebagai vektor dari 4 elemen. Tidak ada alasan untuk terintimidasi oleh ini. Ini hanya berisi langkah-langkah dalam urutan berikut.
Konvolusi 2D - [batch stride, height stride, width stride, channel stride]
. Di sini, langkah batch dan langkah saluran yang baru saja Anda atur ke satu (saya telah menerapkan model pembelajaran mendalam selama 5 tahun dan tidak pernah harus mengaturnya ke apa pun kecuali satu). Sehingga hanya menyisakan 2 langkah untuk Anda atur.
Konvolusi 3D - [batch stride, height stride, width stride, depth stride, channel stride]
. Di sini Anda hanya khawatir tentang langkah tinggi / lebar / kedalaman.
Sekarang, Anda perhatikan bahwa sekecil apa pun langkah Anda (yaitu 1) ada pengurangan dimensi yang tidak dapat dihindari yang terjadi selama konvolusi (misalnya, lebarnya adalah 3 setelah mengkonvolusi gambar dengan lebar 4 unit). Ini tidak diinginkan terutama saat membangun jaringan neural konvolusi yang dalam. Di sinilah padding datang untuk menyelamatkan. Ada dua jenis bantalan yang paling umum digunakan.
SAME
dan VALID
Di bawah ini Anda dapat melihat perbedaannya.
Kata terakhir : Jika Anda sangat penasaran, Anda mungkin bertanya-tanya. Kami baru saja menjatuhkan bom pada reduksi dimensi otomatis dan sekarang berbicara tentang memiliki langkah yang berbeda. Tetapi hal terbaik tentang langkah adalah Anda mengontrol kapan dan bagaimana dimensinya dikurangi.
Singkatnya, Dalam 1D CNN, kernel bergerak dalam 1 arah. Data masukan dan keluaran 1D CNN adalah 2 dimensi. Kebanyakan digunakan pada data Time-Series.
Dalam 2D CNN, kernel bergerak dalam 2 arah. Data masukan dan keluaran 2D CNN adalah 3 dimensi. Banyak digunakan pada data gambar.
Dalam 3D CNN, kernel bergerak dalam 3 arah. Data masukan dan keluaran 3D CNN adalah 4 dimensi. Kebanyakan digunakan pada data Gambar 3D (MRI, CT Scans).
Anda dapat menemukan detail lebih lanjut di sini: https://medium.com/@xzz201920/conv1d-conv2d-and-conv3d-8a59182c4d6