TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | Kaynağı GitHub'da görüntüleyin | Not defterini indir |
import collections
import tensorflow as tf
tf.compat.v2.enable_v2_behavior()
import tensorflow_probability as tfp
tfd = tfp.distributions
tfb = tfp.bijectors
temel bilgiler
TensorFlow Dağılımları şekilleri ile ilişkili üç önemli kavram vardır:
- Olay şekli dağılımı tek çizmek şeklini tarif eder; boyutlar arasında bağımlı olabilir. Sayıl dağılımlar için, olay şekildir
[]
. 5-boyutlu MultivariateNormal için, etkinlik şekli[5]
. - Toplu şekli aynı dağılımların bir "toplu" aka çizer dağıtılan değil, bağımsız açıklar.
- Numune şekli, aynı dağıtılan bağımsız açıklar dağıtım aileden serilerin çizer.
Olay şekli ve toplu şekli özellikleri olan Distribution
örnek şekil için özel bir çağrı ile ilişkili olan ise, nesne sample
veya log_prob
.
Bu defterin amacı, bu kavramları örneklerle açıklamaktır, bu yüzden bu hemen açık değilse endişelenmeyin!
Bu kavramların başka kavramsal bakış için bkz bu blog yazısı .
TensorFlow Hevesli hakkında bir not.
Bu, tüm dizüstü kullanılarak yazılır istekli TensorFlow . Zaman istekli, dağıtım kesikli ve olay şekilleri değerlendirildi (ve dolayısıyla da bilinir) vardır ile her ne kadar kavramların hiçbiri, istekli güvenmek sunulan Distribution
nesne Python oluşturulur grafiktir (non-istekli modu) ise, dağılımları tanımlamak mümkündür olay ve toplu şekiller grafik çalıştırılana kadar belirsizdir.
Skaler Dağılımlar
Yukarıda belirtildiği gibi, bir Distribution
nesnesinin olay ve toplu şekiller tanımlamıştır. Dağıtımları açıklamak için bir yardımcı programla başlayacağız:
def describe_distributions(distributions):
print('\n'.join([str(d) for d in distributions]))
Bu bölümde sayısal dağılımlarını inceleyeceğiz: dağılımlarını bir olay şeklinde []
. Tipik bir örnek olarak belirtilen Poisson dağılımı, bir rate
:
poisson_distributions = [
tfd.Poisson(rate=1., name='One Poisson Scalar Batch'),
tfd.Poisson(rate=[1., 10., 100.], name='Three Poissons'),
tfd.Poisson(rate=[[1., 10., 100.,], [2., 20., 200.]],
name='Two-by-Three Poissons'),
tfd.Poisson(rate=[1.], name='One Poisson Vector Batch'),
tfd.Poisson(rate=[[1.]], name='One Poisson Expanded Batch')
]
describe_distributions(poisson_distributions)
tfp.distributions.Poisson("One_Poisson_Scalar_Batch", batch_shape=[], event_shape=[], dtype=float32) tfp.distributions.Poisson("Three_Poissons", batch_shape=[3], event_shape=[], dtype=float32) tfp.distributions.Poisson("Two_by_Three_Poissons", batch_shape=[2, 3], event_shape=[], dtype=float32) tfp.distributions.Poisson("One_Poisson_Vector_Batch", batch_shape=[1], event_shape=[], dtype=float32) tfp.distributions.Poisson("One_Poisson_Expanded_Batch", batch_shape=[1, 1], event_shape=[], dtype=float32)
, Olay şekli her zaman çok Poisson dağılımı, bir skaler dağılımıdır []
. Daha fazla oran belirtirsek, bunlar parti şeklinde görünür. Son örnek çifti ilginçtir: yalnızca tek bir oran vardır, ancak bu oran boş olmayan şekle sahip bir numpy dizisine gömülü olduğundan, bu şekil toplu şekil olur.
Standart Normal dağılım da bir skalerdir. It olay şekli []
sadece Poisson için olduğu gibi, ama biz yayın bizim ilk örneğini görmek için onunla oynayacağız. Normal kullanılarak belirtilir loc
ve scale
parametrelerine:
normal_distributions = [
tfd.Normal(loc=0., scale=1., name='Standard'),
tfd.Normal(loc=[0.], scale=1., name='Standard Vector Batch'),
tfd.Normal(loc=[0., 1., 2., 3.], scale=1., name='Different Locs'),
tfd.Normal(loc=[0., 1., 2., 3.], scale=[[1.], [5.]],
name='Broadcasting Scale')
]
describe_distributions(normal_distributions)
tfp.distributions.Normal("Standard", batch_shape=[], event_shape=[], dtype=float32) tfp.distributions.Normal("Standard_Vector_Batch", batch_shape=[1], event_shape=[], dtype=float32) tfp.distributions.Normal("Different_Locs", batch_shape=[4], event_shape=[], dtype=float32) tfp.distributions.Normal("Broadcasting_Scale", batch_shape=[2, 4], event_shape=[], dtype=float32)
İlginç bir örnek üzerinde olduğu Broadcasting Scale
dağılımı. loc
parametresi şekline sahip [4]
, ve scale
parametre şekle sahiptir [2, 1]
. Kullanma Numpy yayın kuralları , toplu şekli [2, 4]
. Tanımlamak için bir eşdeğer (ama daha az zarif ve-önerilmez) yolu "Broadcasting Scale"
dağıtımı olacaktır:
describe_distributions(
[tfd.Normal(loc=[[0., 1., 2., 3], [0., 1., 2., 3.]],
scale=[[1., 1., 1., 1.], [5., 5., 5., 5.]])])
tfp.distributions.Normal("Normal", batch_shape=[2, 4], event_shape=[], dtype=float32)
Aynı zamanda bir baş ağrısı ve hata kaynağı olmasına rağmen, yayın gösteriminin neden yararlı olduğunu görebiliriz.
Skaler Dağılımları Örnekleme
Biz dağılımları ile yapabileceğiniz iki şey vardır: biz edebilirsiniz sample
onlardan ve biz hesaplayabilir log_prob
s. Önce örneklemeyi inceleyelim. Temel kural bir dağılımdan örnek zaman, elde edilen tensör şekle sahip olmasıdır [sample_shape, batch_shape, event_shape]
, batch_shape
ve event_shape
tarafından sağlanan Distribution
nesnesi ve sample_shape
çağrısı ile sağlanır sample
. Skalar dağılımlar için, event_shape = []
, bu yüzden tensör şekle sahip olacaktır numuneden geri [sample_shape, batch_shape]
. Hadi deneyelim:
def describe_sample_tensor_shape(sample_shape, distribution):
print('Sample shape:', sample_shape)
print('Returned sample tensor shape:',
distribution.sample(sample_shape).shape)
def describe_sample_tensor_shapes(distributions, sample_shapes):
started = False
for distribution in distributions:
print(distribution)
for sample_shape in sample_shapes:
describe_sample_tensor_shape(sample_shape, distribution)
print()
sample_shapes = [1, 2, [1, 5], [3, 4, 5]]
describe_sample_tensor_shapes(poisson_distributions, sample_shapes)
tfp.distributions.Poisson("One_Poisson_Scalar_Batch", batch_shape=[], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1,) Sample shape: 2 Returned sample tensor shape: (2,) Sample shape: [1, 5] Returned sample tensor shape: (1, 5) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5) tfp.distributions.Poisson("Three_Poissons", batch_shape=[3], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 3) Sample shape: 2 Returned sample tensor shape: (2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 3) tfp.distributions.Poisson("Two_by_Three_Poissons", batch_shape=[2, 3], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 2, 3) Sample shape: 2 Returned sample tensor shape: (2, 2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 2, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 2, 3) tfp.distributions.Poisson("One_Poisson_Vector_Batch", batch_shape=[1], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 1) Sample shape: 2 Returned sample tensor shape: (2, 1) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 1) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 1) tfp.distributions.Poisson("One_Poisson_Expanded_Batch", batch_shape=[1, 1], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 1, 1) Sample shape: 2 Returned sample tensor shape: (2, 1, 1) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 1, 1) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 1, 1)
describe_sample_tensor_shapes(normal_distributions, sample_shapes)
tfp.distributions.Normal("Standard", batch_shape=[], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1,) Sample shape: 2 Returned sample tensor shape: (2,) Sample shape: [1, 5] Returned sample tensor shape: (1, 5) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5) tfp.distributions.Normal("Standard_Vector_Batch", batch_shape=[1], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 1) Sample shape: 2 Returned sample tensor shape: (2, 1) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 1) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 1) tfp.distributions.Normal("Different_Locs", batch_shape=[4], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 4) Sample shape: 2 Returned sample tensor shape: (2, 4) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 4) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 4) tfp.distributions.Normal("Broadcasting_Scale", batch_shape=[2, 4], event_shape=[], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 2, 4) Sample shape: 2 Returned sample tensor shape: (2, 2, 4) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 2, 4) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 2, 4)
Hakkında söylenecek var tüm ilgili en That sample
: döndürdü örnek tansörler şekle sahip [sample_shape, batch_shape, event_shape]
.
Bilgisayar log_prob
Skaler Dağılımları İçin
Şimdi de tabloya bakalım log_prob
biraz daha zordur. log_prob
girdi olarak hesaplamak için hangi yer (ler) temsil eden bir (boş olmayan) tensörü alır log_prob
dağıtımı için. En basit durumda bu tensör formunun bir şekle sahip olacaktır [sample_shape, batch_shape, event_shape]
, burada batch_shape
ve event_shape
eşleme dağılımının toplu ve olay şekilleri. Hatırlama kez daha o sayıl dağılımlar için, event_shape = []
, giriş tensör şekline sahiptir, böylece [sample_shape, batch_shape]
Bu durumda, şeklin bir tensörünü geri almak [sample_shape, batch_shape]
:
three_poissons = tfd.Poisson(rate=[1., 10., 100.], name='Three Poissons')
three_poissons
<tfp.distributions.Poisson 'Three_Poissons' batch_shape=[3] event_shape=[] dtype=float32>
three_poissons.log_prob([[1., 10., 100.], [100., 10., 1]]) # sample_shape is [2].
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -2.0785608, -3.2223587], [-364.73938 , -2.0785608, -95.39484 ]], dtype=float32)>
three_poissons.log_prob([[[[1., 10., 100.], [100., 10., 1.]]]]) # sample_shape is [1, 1, 2].
<tf.Tensor: shape=(1, 1, 2, 3), dtype=float32, numpy= array([[[[ -1. , -2.0785608, -3.2223587], [-364.73938 , -2.0785608, -95.39484 ]]]], dtype=float32)>
Not İlk örnekte, giriş ve çıkış şekline sahip nasıl [2, 3]
ve şekle sahip ikinci bir örnekte [1, 1, 2, 3]
.
Yayın için olmasaydı, söylenecek tek şey bu olurdu. İşte yayıncılığı hesaba kattığımızda kurallar. Bunu tam bir genellemeyle açıklıyoruz ve skaler dağılımlar için sadeleştirmeleri not ediyoruz:
- Tanımlama
n = len(batch_shape) + len(event_shape)
. (Skalar dağılımlar için,len(event_shape)=0
). - Giriş tensör Eğer
t
den az olann
büyüklükte boyutları ekleyerek boyutları, ped şeklini1
sol tam olarak sahip olana kadarn
boyutları. Ortaya çıkan tensör Çağrıt'
. - Yayın
n
en sağdaki boyutlarıt'
karşı[batch_shape, event_shape]
bir işlem konum dağılımınınlog_prob
için. Daha ayrıntılı olarak: boyutlar içint'
zaten dağılımını maçları, hiçbir şey yapmak ve boyutlart'
, kopyalayan a tek sahip olduğu zamanlarda uygun sayıda tekil. Diğer herhangi bir durum bir hatadır. (Skaler dağılımlar için, biz sadece karşı yayınbatch_shape
event_shape = beri,[]
.) - Artık nihayet hesaplamak mümkün olacaktır
log_prob
. Elde edilen tensör şekle sahip olacaktır[sample_shape, batch_shape]
,sample_shape
herhangi boyutları olarak tanımlanırt
veyat'
sağdan solan
: -rightmost boyutlarısample_shape = shape(t)[:-n]
.
Ne anlama geldiğini bilmiyorsanız bu bir karışıklık olabilir, o yüzden bazı örnekler üzerinde çalışalım:
three_poissons.log_prob([10.])
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([-16.104412 , -2.0785608, -69.05272 ], dtype=float32)>
Tensör [10.]
(şekle sahip [1]
) boyunca yayın batch_shape
biz 10 değeri her üç Poisson log olasılık değerlendirmek, böylece 3.
three_poissons.log_prob([[[1.], [10.]], [[100.], [1000.]]])
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[-1.0000000e+00, -7.6974149e+00, -9.5394836e+01], [-1.6104412e+01, -2.0785608e+00, -6.9052719e+01]], [[-3.6473938e+02, -1.4348087e+02, -3.2223587e+00], [-5.9131279e+03, -3.6195427e+03, -1.4069575e+03]]], dtype=float32)>
Yukarıdaki örnekte, giriş tensör şekle sahiptir [2, 2, 1]
dağılımları nesnenin her biri için 3 So bir parti biçimindeyken [2, 2]
Örnek boyutlar, temin edilen tek bir değer her bir broadcats alır üç Poisson'dan.
Bir muhtemelen yararlı bir yol düşünmek çünkü: three_poissons
sahip batch_shape = [2, 3]
, bir çağrı log_prob
son boyut, ya 1 ya da 3 olan bir Tensörü almalıdır; başka bir şey bir hatadır. (Numpy yayın kuralları şekilli bir Tensörün tamamen eşdeğer olarak bir sayısal özel bir durumunu tedavi [1]
).
Daha karmaşık Poisson dağılımına sahip oynayarak pirzola Let test batch_shape = [2, 3]
:
poisson_2_by_3 = tfd.Poisson(
rate=[[1., 10., 100.,], [2., 20., 200.]],
name='Two-by-Three Poissons')
poisson_2_by_3.log_prob(1.)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], dtype=float32)>
poisson_2_by_3.log_prob([1.]) # Exactly equivalent to above, demonstrating the scalar special case.
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], dtype=float32)>
poisson_2_by_3.log_prob([[1., 1., 1.], [1., 1., 1.]]) # Another way to write the same thing. No broadcasting.
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], dtype=float32)>
poisson_2_by_3.log_prob([[1., 10., 100.]]) # Input is [1, 3] broadcast to [2, 3].
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -2.0785608, -3.2223587], [ -1.3068528, -5.14709 , -33.90767 ]], dtype=float32)>
poisson_2_by_3.log_prob([[1., 10., 100.], [1., 10., 100.]]) # Equivalent to above. No broadcasting.
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -2.0785608, -3.2223587], [ -1.3068528, -5.14709 , -33.90767 ]], dtype=float32)>
poisson_2_by_3.log_prob([[1., 1., 1.], [2., 2., 2.]]) # No broadcasting.
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -14.701683 , -190.09653 ]], dtype=float32)>
poisson_2_by_3.log_prob([[1.], [2.]]) # Equivalent to above. Input shape [2, 1] broadcast to [2, 3].
<tf.Tensor: shape=(2, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -14.701683 , -190.09653 ]], dtype=float32)>
Yukarıdaki örnekler, yığın üzerinden yayın yapmayı içeriyordu, ancak numune şekli boştu. Bir değerler koleksiyonumuz olduğunu ve partideki her noktada her değerin günlük olasılığını elde etmek istediğimizi varsayalım. Bunu manuel olarak yapabiliriz:
poisson_2_by_3.log_prob([[[1., 1., 1.], [1., 1., 1.]], [[2., 2., 2.], [2., 2., 2.]]]) # Input shape [2, 2, 3].
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], [[ -1.6931472, -6.087977 , -91.48282 ], [ -1.3068528, -14.701683 , -190.09653 ]]], dtype=float32)>
Veya yayının son toplu iş boyutunu ele almasına izin verebiliriz:
poisson_2_by_3.log_prob([[[1.], [1.]], [[2.], [2.]]]) # Input shape [2, 2, 1].
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], [[ -1.6931472, -6.087977 , -91.48282 ], [ -1.3068528, -14.701683 , -190.09653 ]]], dtype=float32)>
Ayrıca (belki daha az doğal olarak) yayının yalnızca ilk toplu iş boyutunu ele almasına izin verebiliriz:
poisson_2_by_3.log_prob([[[1., 1., 1.]], [[2., 2., 2.]]]) # Input shape [2, 1, 3].
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], [[ -1.6931472, -6.087977 , -91.48282 ], [ -1.3068528, -14.701683 , -190.09653 ]]], dtype=float32)>
Ya da sap hem toplu boyutlarını yayın izin verebilir:
poisson_2_by_3.log_prob([[[1.]], [[2.]]]) # Input shape [2, 1, 1].
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], [[ -1.6931472, -6.087977 , -91.48282 ], [ -1.3068528, -14.701683 , -190.09653 ]]], dtype=float32)>
İstediğimiz yalnızca iki değere sahip olduğumuzda yukarıdakiler işe yaradı, ancak her parti noktasında değerlendirmek istediğimiz uzun bir değer listemiz olduğunu varsayalım. Bunun için, şeklin sağ tarafına ekstra boyut 1 ekleyen aşağıdaki gösterim son derece yararlıdır:
poisson_2_by_3.log_prob(tf.constant([1., 2.])[..., tf.newaxis, tf.newaxis])
<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy= array([[[ -1. , -7.697415 , -95.39484 ], [ -1.3068528, -17.004269 , -194.70169 ]], [[ -1.6931472, -6.087977 , -91.48282 ], [ -1.3068528, -14.701683 , -190.09653 ]]], dtype=float32)>
Bu bir örneğidir strided dilim gösterimde bilerek değer.
Dönersek three_poissons
tamlığı için, aynı örnek görünüyor gibi:
three_poissons.log_prob([[1.], [10.], [50.], [100.]])
<tf.Tensor: shape=(4, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -16.104412 , -2.0785608, -69.05272 ], [-149.47777 , -43.34851 , -18.219261 ], [-364.73938 , -143.48087 , -3.2223587]], dtype=float32)>
three_poissons.log_prob(tf.constant([1., 10., 50., 100.])[..., tf.newaxis]) # Equivalent to above.
<tf.Tensor: shape=(4, 3), dtype=float32, numpy= array([[ -1. , -7.697415 , -95.39484 ], [ -16.104412 , -2.0785608, -69.05272 ], [-149.47777 , -43.34851 , -18.219261 ], [-364.73938 , -143.48087 , -3.2223587]], dtype=float32)>
Çok değişkenli dağılımlar
Şimdi boş olmayan olay şekline sahip çok değişkenli dağılımlara dönüyoruz. Şimdi çok terimli dağılımlara bakalım.
multinomial_distributions = [
# Multinomial is a vector-valued distribution: if we have k classes,
# an individual sample from the distribution has k values in it, so the
# event_shape is `[k]`.
tfd.Multinomial(total_count=100., probs=[.5, .4, .1],
name='One Multinomial'),
tfd.Multinomial(total_count=[100., 1000.], probs=[.5, .4, .1],
name='Two Multinomials Same Probs'),
tfd.Multinomial(total_count=100., probs=[[.5, .4, .1], [.1, .2, .7]],
name='Two Multinomials Same Counts'),
tfd.Multinomial(total_count=[100., 1000.],
probs=[[.5, .4, .1], [.1, .2, .7]],
name='Two Multinomials Different Everything')
]
describe_distributions(multinomial_distributions)
tfp.distributions.Multinomial("One_Multinomial", batch_shape=[], event_shape=[3], dtype=float32) tfp.distributions.Multinomial("Two_Multinomials_Same_Probs", batch_shape=[2], event_shape=[3], dtype=float32) tfp.distributions.Multinomial("Two_Multinomials_Same_Counts", batch_shape=[2], event_shape=[3], dtype=float32) tfp.distributions.Multinomial("Two_Multinomials_Different_Everything", batch_shape=[2], event_shape=[3], dtype=float32)
Not son üç örneklerde, batch_shape daima nasıl [2]
, ama biz var paylaşılan birine yayın kullanabilirsiniz total_count
veya paylaşılan probs
başlık altında aynı şekle sahip yayın, çünkü (veya hiçbiri).
Halihazırda bildiklerimiz göz önüne alındığında, örnekleme basittir:
describe_sample_tensor_shapes(multinomial_distributions, sample_shapes)
tfp.distributions.Multinomial("One_Multinomial", batch_shape=[], event_shape=[3], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 3) Sample shape: 2 Returned sample tensor shape: (2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 3) tfp.distributions.Multinomial("Two_Multinomials_Same_Probs", batch_shape=[2], event_shape=[3], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 2, 3) Sample shape: 2 Returned sample tensor shape: (2, 2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 2, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 2, 3) tfp.distributions.Multinomial("Two_Multinomials_Same_Counts", batch_shape=[2], event_shape=[3], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 2, 3) Sample shape: 2 Returned sample tensor shape: (2, 2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 2, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 2, 3) tfp.distributions.Multinomial("Two_Multinomials_Different_Everything", batch_shape=[2], event_shape=[3], dtype=float32) Sample shape: 1 Returned sample tensor shape: (1, 2, 3) Sample shape: 2 Returned sample tensor shape: (2, 2, 3) Sample shape: [1, 5] Returned sample tensor shape: (1, 5, 2, 3) Sample shape: [3, 4, 5] Returned sample tensor shape: (3, 4, 5, 2, 3)
Günlük olasılıklarını hesaplamak da aynı derecede basittir. Çapraz Çok Değişkenli Normal dağılımlarla bir örnek üzerinde çalışalım. (Sayılar ve olasılıklar üzerindeki kısıtlamalar, yayının genellikle kabul edilemez değerler üreteceği anlamına geldiğinden, çok terimli ifadeler çok yayın dostu değildir.) Aynı ortalama ancak farklı ölçekler (standart sapmalar) ile 2 adet 3 boyutlu dağılım toplu kullanacağız:
two_multivariate_normals = tfd.MultivariateNormalDiag(loc=[1., 2., 3.], scale_identity_multiplier=[1., 2.])
two_multivariate_normals
<tfp.distributions.MultivariateNormalDiag 'MultivariateNormalDiag' batch_shape=[2] event_shape=[3] dtype=float32>
(Biz terazi kimlik katları olan dağılımları kullanılabilir, ancak bu bir kısıtlama değildir Not, biz geçebileceği scale
yerine scale_identity_multiplier
.)
Şimdi her parti noktasının günlük olasılığını kendi ortalamasında ve kaydırılmış bir ortalamada değerlendirelim:
two_multivariate_normals.log_prob([[[1., 2., 3.]], [[3., 4., 5.]]]) # Input has shape [2,1,3].
<tf.Tensor: shape=(2, 2), dtype=float32, numpy= array([[-2.7568154, -4.836257 ], [-8.756816 , -6.336257 ]], dtype=float32)>
Tam eşdeğer olarak kullanabileceğimiz https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/strided-slice fazladan bir şekle = bir sabit ortasında 1 boyut eklemek için:
two_multivariate_normals.log_prob(
tf.constant([[1., 2., 3.], [3., 4., 5.]])[:, tf.newaxis, :]) # Equivalent to above.
<tf.Tensor: shape=(2, 2), dtype=float32, numpy= array([[-2.7568154, -4.836257 ], [-8.756816 , -6.336257 ]], dtype=float32)>
Ekstra bir boyut uç değil, diğer yandan, biz geçmesi [1., 2., 3.]
ilk parti noktasına ve [3., 4., 5.]
ikinci:
two_multivariate_normals.log_prob(tf.constant([[1., 2., 3.], [3., 4., 5.]]))
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([-2.7568154, -6.336257 ], dtype=float32)>
Şekil Manipülasyon Teknikleri
Yeniden Şekillendirme Bijektörü
Reshape
bijector Bir dağılımın event_shape yeniden şekillendirmek için de kullanılabilir. Bir örnek görelim:
six_way_multinomial = tfd.Multinomial(total_count=1000., probs=[.3, .25, .2, .15, .08, .02])
six_way_multinomial
<tfp.distributions.Multinomial 'Multinomial' batch_shape=[] event_shape=[6] dtype=float32>
Biz bir olay şeklinde bir katlıterimini yarattı [6]
. Yeniden şekillendirme Bijector bize ait bir olay şeklinde bir dağıtım olarak tedavi sağlar [2, 3]
.
Bir Bijector
açık alt kümesini türevlenebilir, bire bir fonksiyonu temsil \({\mathbb R}^n\). Bijectors
ile bağlantılı olarak kullanılan TransformedDistribution
, bu model bir dağıtım \(p(y)\) bir baz dağılımı açısından \(p(x)\) ve Bijector
temsil \(Y = g(X)\). Eylemde görelim:
transformed_multinomial = tfd.TransformedDistribution(
distribution=six_way_multinomial,
bijector=tfb.Reshape(event_shape_out=[2, 3]))
transformed_multinomial
<tfp.distributions.TransformedDistribution 'reshapeMultinomial' batch_shape=[] event_shape=[2, 3] dtype=float32>
six_way_multinomial.log_prob([500., 100., 100., 150., 100., 50.])
<tf.Tensor: shape=(), dtype=float32, numpy=-178.22021>
transformed_multinomial.log_prob([[500., 100., 100.], [150., 100., 50.]])
<tf.Tensor: shape=(), dtype=float32, numpy=-178.22021>
Bu tek şey Reshape
bijector yapabilir: bu toplu boyutları veya tersi olarak etkinlik boyutları dönemez.
Bağımsız Dağıtım
Independent
dağılımı tek bir dağılım olarak bağımsız bir,-mutlaka-özdeş olmayan toplanması (aka bir toplu) dağılımları tedavi etmek için kullanılır. Daha öz, Independent
boyutları dönüştürmek sağlar batch_shape
içinde boyutlara event_shape
. Örnekle açıklayacağız:
two_by_five_bernoulli = tfd.Bernoulli(
probs=[[.05, .1, .15, .2, .25], [.3, .35, .4, .45, .5]],
name="Two By Five Bernoulli")
two_by_five_bernoulli
<tfp.distributions.Bernoulli 'Two_By_Five_Bernoulli' batch_shape=[2, 5] event_shape=[] dtype=int32>
Bunu, tura olasılıklarıyla ilişkili ikişer beşlik madeni para dizisi olarak düşünebiliriz. Belirli, rastgele bir birler ve sıfırlar kümesinin olasılığını değerlendirelim:
pattern = [[1., 0., 0., 1., 0.], [0., 0., 1., 1., 1.]]
two_by_five_bernoulli.log_prob(pattern)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy= array([[-2.9957323 , -0.10536052, -0.16251892, -1.609438 , -0.2876821 ], [-0.35667497, -0.4307829 , -0.9162907 , -0.7985077 , -0.6931472 ]], dtype=float32)>
Biz kullanabilirsiniz Independent
biz madalyonun bir "satır" dikkate alınmasını istiyorsanız, kullanışlı olduğu iki farklı "beş Bernoulli setleri" çevirmeye çevirir tek bir sonuç olarak, belirli bir desende geliyor:
two_sets_of_five = tfd.Independent(
distribution=two_by_five_bernoulli,
reinterpreted_batch_ndims=1,
name="Two Sets Of Five")
two_sets_of_five
<tfp.distributions.Independent 'Two_Sets_Of_Five' batch_shape=[2] event_shape=[5] dtype=int32>
Matematiksel olarak, kümedeki beş "bağımsız" yazı turasının log olasılıklarını toplayarak her bir "kümenin" log olasılığını hesaplıyoruz; bu, dağılımın adını aldığı yerdir:
two_sets_of_five.log_prob(pattern)
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([-5.160732 , -3.1954036], dtype=float32)>
Hatta daha ileri giderek kullanabilirsiniz Independent
bireysel olaylar iki tarafından beş Bernoulli bir dizi olduğu bir dağılım oluşturmak için:
one_set_of_two_by_five = tfd.Independent(
distribution=two_by_five_bernoulli, reinterpreted_batch_ndims=2,
name="One Set Of Two By Five")
one_set_of_two_by_five.log_prob(pattern)
<tf.Tensor: shape=(), dtype=float32, numpy=-8.356134>
Perspektifinden belirterek It değerinde sample
kullanılarak Independent
şey değiştirir:
describe_sample_tensor_shapes(
[two_by_five_bernoulli,
two_sets_of_five,
one_set_of_two_by_five],
[[3, 5]])
tfp.distributions.Bernoulli("Two_By_Five_Bernoulli", batch_shape=[2, 5], event_shape=[], dtype=int32) Sample shape: [3, 5] Returned sample tensor shape: (3, 5, 2, 5) tfp.distributions.Independent("Two_Sets_Of_Five", batch_shape=[2], event_shape=[5], dtype=int32) Sample shape: [3, 5] Returned sample tensor shape: (3, 5, 2, 5) tfp.distributions.Independent("One_Set_Of_Two_By_Five", batch_shape=[], event_shape=[2, 5], dtype=int32) Sample shape: [3, 5] Returned sample tensor shape: (3, 5, 2, 5)
Okuyucu için bir veda egzersiz olarak, bir vektör toplu arasındaki farklılıkları ve benzerlikleri dikkate öneririz Normal
dağılımlar ve MultivariateNormalDiag
bir örnekleme ve günlük olasılık açısından dağılımı. Nasıl kullanabilirsiniz Independent
bir inşa etmek MultivariateNormalDiag
Bir grup Normal
s? (Not MultivariateNormalDiag
gerçekten de bu şekilde uygulanmadı.)