Yanıtlar:
C3D'den bir resimle açıklamak istiyorum .
Özetle, evrişimli yön ve çıktı şekli önemlidir!
↑↑↑↑↑ 1B Konvolüsyonlar - Temel ↑↑↑↑↑
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)
↑↑↑↑↑ 2D Evrişimler - Temel ↑↑↑↑↑
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)
↑↑↑↑↑ 3D Dönüşümler - Temel ↑↑↑↑↑
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)
↑↑↑↑↑ 3D girişli 2D Dönüşümler - 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)
↑↑↑↑↑ CNN'de Bonus 1x1 dönüşüm - 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)
- Orijinal Bağlantı: LINK
- Yazar: Martin Görner
- Twitter: @martin_gorner
- Google +: plus.google.com/+MartinGorne
↑↑↑↑↑ 1D girişli 1D Konvolüsyonlar ↑↑↑↑↑
↑↑↑↑↑ 2D girişli 1D Dönüşümler ↑↑↑↑↑
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
, daha sonra → satır için 1+stride
. Evrişimin kendisi kayma değişmezdir, öyleyse neden evrişimin yönü önemlidir?
@ Runhani'nin cevabını takiben, açıklamayı biraz daha netleştirmek için birkaç ayrıntı daha ekliyorum ve bunu biraz daha açıklamaya çalışacağım (ve tabii ki TF1 ve TF2'deki örneklerle).
Dahil ettiğim ana ek parçalardan biri,
tf.Variable
TF 1 ve TF 2 kullanarak 1B evrişimi nasıl yapabileceğiniz aşağıda açıklanmıştır.
Ve spesifik olmak gerekirse, verilerimin aşağıdaki şekilleri var,
[batch size, width, in channels]
(örneğin 1, 5, 1
)[width, in channels, out channels]
(örneğin 5, 1, 4
)[batch size, width, out_channels]
(örneğin 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)
TF2 ile It yoludur az iş TF2 gerekmez olarak Session
ve variable_initializer
örneğin.
Öyleyse bir sinyal yumuşatma örneği kullanarak bunun ne yaptığını anlayalım. Solda orijinali gördünüz ve sağda 3 çıkış kanalına sahip bir Convolution 1D çıktısını alıyorsunuz.
Çoklu kanallar, temelde bir girişin çoklu özellik temsilleridir. Bu örnekte, üç farklı filtre ile elde edilen üç temsiliniz var. İlk kanal, eşit ağırlıklı yumuşatma filtresidir. İkincisi, filtrenin ortasına sınırlardan daha fazla ağırlık veren bir filtredir. Son filtre, ikincinin tersini yapar. Böylece, bu farklı filtrelerin nasıl farklı etkiler yarattığını görebilirsiniz.
Cümle sınıflandırma görevi için 1 boyutlu evrişim başarılı bir şekilde kullanılmıştır .
Kapalıdan 2D evrişime. Eğer derinlemesine öğrenen bir kişiyseniz, 2D evrişime rastlamama ihtimaliniz ... neredeyse sıfırdır. Görüntü sınıflandırması, nesne algılama vb. İçin CNN'lerde ve aynı zamanda görüntüleri içeren NLP problemlerinde (örneğin, resim yazısı oluşturma) kullanılır.
Bir örnek deneyelim, burada aşağıdaki filtrelerle bir evrişim çekirdeği buldum,
Ve spesifik olmak gerekirse, verilerimin aşağıdaki şekilleri var,
[batch_size, height, width, 1]
(örneğin 1, 340, 371, 1
)[height, width, in channels, out channels]
(örneğin 3, 3, 1, 3
)[batch_size, height, width, out_channels]
(örneğin 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')
Burada yukarıdaki kodun ürettiği çıktıyı görebilirsiniz. İlk görüntü orijinaldir ve saat yönünde ilerleyen 1. filtre, 2. filtre ve 3 filtrenin çıktılarına sahipsiniz.
2B evrişim bağlamında, bu çoklu kanalların ne anlama geldiğini anlamak çok daha kolaydır. Yüz tanıma yaptığınızı söyleyin. Her bir filtre bir gözü, ağzı, burnu vb. Temsil eder (bu çok gerçekçi olmayan bir basitleştirmedir, ancak noktayı alır). Böylece, her özellik haritası, sağladığınız görüntüde o özelliğin olup olmadığının ikili bir temsili olur. . Bir yüz tanıma modeli için bunların çok değerli özellikler olduğunu vurgulamaya ihtiyacım olduğunu sanmıyorum. Bu makalede daha fazla bilgi .
Bu, ifade etmeye çalıştığım şeyin bir örneğidir.
2D evrişim, derin öğrenme alanında çok yaygındır.
CNN'ler (Evrişim Sinir Ağları) neredeyse tüm bilgisayarla görme görevleri için (örneğin Görüntü sınıflandırması, nesne algılama, video sınıflandırması) 2D evrişim işlemini kullanır.
Şimdi boyutların sayısı arttıkça neler olduğunu göstermek giderek zorlaşıyor. Ancak 1B ve 2B evrişimin nasıl çalıştığını iyi anladığımızda, bu anlayışı 3B evrişime genelleştirmek çok basittir. İşte başlıyor.
Ve spesifik olmak gerekirse, verilerimin aşağıdaki şekilleri var,
[batch size, height, width, depth, in channels]
(örneğin 1, 200, 200, 200, 1
)[height, width, depth, in channels, out channels]
(örneğin 5, 5, 5, 1, 3
)[batch size, width, height, width, depth, out_channels]
(örneğin 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')
Doğada 3 boyutlu olan LIDAR (Işık Algılama ve Değişme) verilerini içeren makine öğrenimi uygulamaları geliştirilirken 3D evrişim kullanılmıştır.
Pekala, neredeyse oradasın. Öyleyse bekle. Adım ve dolgu nedir görelim. Onları düşünürseniz oldukça sezgiseldirler.
Bir koridorda ilerlerseniz, oraya daha az adımda daha hızlı varırsınız. Ama aynı zamanda, odanın karşısına geçtiğinizden daha az çevre gözlemlediğiniz anlamına gelir. Şimdi de güzel bir resimle anlayışımızı pekiştirelim! Bunları 2D evrişim ile anlayalım.
tf.nn.conv2d
Örneğin kullandığınızda , onu 4 elemanlı bir vektör olarak ayarlamanız gerekir. Bundan korkmanıza gerek yok. Sadece aşağıdaki sırayla adımları içerir.
2D Evrişim - [batch stride, height stride, width stride, channel stride]
. Burada, toplu adım ve kanal adımını bir taneye ayarladınız (5 yıldır derin öğrenme modellerini uyguluyorum ve bunları biri dışında hiçbir şeye ayarlamak zorunda kalmadım). Böylece sadece 2 adım atmanız yeterli.
3D Evrişim - [batch stride, height stride, width stride, depth stride, channel stride]
. Burada sadece yükseklik / genişlik / derinlik adımlarıyla ilgileniyorsunuz.
Şimdi, adımınız ne kadar küçük olursa olsun (yani 1), evrişim sırasında kaçınılmaz bir boyut azalması olduğunu fark edersiniz (örneğin, 4 birim genişliğinde bir görüntüyü çevirdikten sonra genişlik 3'tür). Bu özellikle derin evrişimli sinir ağları oluştururken istenmeyen bir durumdur. Burası yastığın kurtarmaya geldiği yerdir. En sık kullanılan iki dolgu türü vardır.
SAME
ve VALID
Aşağıda farkı görebilirsiniz.
Son söz : Çok merak ediyorsanız, merak ediyor olabilirsiniz. Tam otomatik boyut küçültme üzerine bir bomba düşürdük ve şimdi farklı adımlardan bahsediyoruz. Ancak adımlarla ilgili en iyi şey, boyutların nerede ve nasıl azalacağını kontrol etmenizdir.
Özetle, 1D CNN'de çekirdek 1 yönde hareket eder. 1D CNN'in giriş ve çıkış verileri 2 boyutludur. Çoğunlukla Zaman Serisi verilerinde kullanılır.
2D CNN'de çekirdek 2 yönde hareket eder. 2D CNN'nin giriş ve çıkış verileri 3 boyutludur. Çoğunlukla Görüntü verilerinde kullanılır.
3B CNN'de çekirdek 3 yönde hareket eder. 3D CNN'in giriş ve çıkış verileri 4 boyutludur. Çoğunlukla 3D Görüntü verilerinde (MRI, CT Taramaları) kullanılır.
Daha fazla bilgiyi burada bulabilirsiniz: https://medium.com/@xzz201920/conv1d-conv2d-and-conv3d-8a59182c4d6