Örneğin, büyük Jacobian matrisleriyle uğraşırken, sayısal koddaki karmaşıklıkla nasıl başa çıkılır?


10

Doğrusal olmayan bir çiftli denklem sistemini çözüyorum ve bağımsız sistemin Jacobian'ını hesapladım. Sonuç gerçekten karmaşıktır, aşağıda (sadece!) 3 × 9 matrisin ilk 3 sütunu ,3×9

Kısmi Jacobian matrisi

(Karmaşıklık kısmen ortaya çıkar, çünkü sayısal şema kararlılık için üstel uyum gerektirir.)

Jacobians kullanarak sayısal kodların uygulanması hakkında oldukça genel bir sorum var.

Devam edip koddaki bu matrisi uygulayabilirim. Ancak sezgim, karmaşıklığı ve hataların getirilmesinin kaçınılmazlığı nedeniyle birkaç gün (belki haftalar!) Sıkıcı hata ayıklama beklememi söylüyor. Sayısal kodda bunun gibi karmaşıklıkla nasıl başa çıkılır, kaçınılmaz görünüyor ?! Sembolik paketlerden otomatik kod üretme kullanıyor musunuz (daha sonra kodu elle değiştirin)?

Önce analitik Jacobian'ı sonlu fark yaklaşımı ile hata ayıklamayı planlıyorum, herhangi bir tuzaktan haberdar olmalıyım? Kodunuzdaki benzer sorunlarla nasıl başa çıkıyorsunuz?

Güncelleme

Bunu Python'da kodluyorum ve Jacobian'ı üretmek için sempozyum kullandım . Belki kod oluşturma özelliğini kullanabilir miyim?


Jacobian ifadeleri oluşturmak için hangi Bilgisayar Cebir Sistemini kullanıyorsunuz? Maple kullanıyorsanız codegen, ifadelerin her biri veya tamamı için otomatik olarak kompakt ve verimli C veya Fortran kodu oluşturabileceğinden pakete bakmak isteyebilirsiniz .
Pedro

Burada pek çok yararlı cevap var, bir tane seçmek mantıklı değil. Bunu bir Topluluk Wiki yayını yapmalı mıyım?
boyfarrell

Yanıtlar:


6

Tek kelime: Modülerlik .

Jacobian'ınızda kendi işlevleri olarak yazılabilecek birçok tekrarlanan ifade var. Aynı işlemi bir kereden fazla yazmanız için hiçbir neden yoktur ve bu hata ayıklamayı kolaylaştırır; yalnızca bir kez yazarsanız, hata için yalnızca bir yer vardır (teoride).

Modüler kod ayrıca testi kolaylaştırır; Tüm matrisi test etmeye çalışmak yerine Jacobian'ınızın her bir bileşeni için testler yazabilirsiniz. Örneğin, işlevinizi am () modüler bir şekilde yazarsanız, bunun için akıl sağlığı testlerini kolayca yazabilir, düzgün bir şekilde farklılaştırıp ayırmadığınızı kontrol edebilirsiniz, vb.

Başka bir öneri, Jacobian'ı birleştirmek için otomatik farklılaşma kütüphanelerine bakmak olacaktır. Hatasız olduklarının garantisi yoktur, ancak muhtemelen kendi hatalarınızı yazmaktan daha az hata ayıklama / daha az hata olacaktır. İşte bakmak isteyebileceğiniz birkaç tane:

  • Sacado (Sandia Labs)
  • ADIC (Argonne)

Üzgünüz, sadece piton kullandığınızı gördüm. ScientificPython'un AD desteği vardır.


İyi tavsiye. Ara ifadelerin çoğu zaman kendi işlevlerine sahip olması gerekmez; yalnızca ara değişkenlerde saklayın.
David Ketcheson

5

Burada bir hikaye ile ön plana çıkan birkaç dikkat kelimesi ile tartmama izin verin. Uzun zaman önce, yeni başladığımda bir arkadaşımla çalıştım. Çözmek için oldukça dağınık bir hedefi olan bir optimizasyon problemi vardı. Onun çözümü, bir optimizasyon için analitik türevler üretmekti.

Gördüğüm sorun bu türevlerin kötü olmasıydı. Macsyma kullanılarak üretildi, fortran koduna dönüştürüldü, her biri düzinelerce devam ifadesi uzunluğundaydı. Aslında, Fortran derleyici, maksimum devam ifadelerinin sayısını aştığından üzüldü. Bu sorunu çözmemize izin veren bir bayrak bulsak da, başka sorunlar da vardı.

  • Uzun ifadelerde, CA sistemleri tarafından yaygın olarak üretildiği gibi, büyük eksiltme iptali riski vardır. Çok sayıda büyük sayıyı hesaplayın, ancak hepsinin küçük bir sayı elde etmek için birbirlerini iptal ettiklerini bulmak için.

  • Genellikle analitik olarak üretilen türevlerin değerlendirilmesi sonlu farklar kullanılarak sayısal olarak üretilen türevlerden daha pahalıdır. N değişkenler için bir gradyan, objektif işlevinizi değerlendirme maliyetinin n katından fazla sürebilir. (Zamandan tasarruf edebilirsiniz, çünkü terimlerin çoğu çeşitli türevler arasında yeniden kullanılabilir, ancak bu aynı zamanda bilgisayar tarafından üretilen ifadeler kullanmak yerine dikkatli el kodlaması yapmaya da zorlar. ifadelerinde hata olasılığı önemsiz değildir. Bu türevleri doğruluk için doğruladığınızdan emin olun.)

Hikayemin anlamı, bu CA tarafından üretilen ifadelerin kendi sorunları var. Komik olan şey, meslektaşımın problemin karmaşıklığından gurur duymasıydı, cebir çok kötü olduğu için gerçekten zor bir problemi açıkça çözüyordu. Düşündüğünü sanmıyorum, bu cebir aslında doğru olanı hesaplıyorsa, bunu doğru bir şekilde yapıyor muydu ve verimli bir şekilde yapıyor muydu.

O zamanlar bu projede kıdemli kişi olsaydım, ona ayaklanma hareketini okurdum. Gururu, sonlu bir fark temelli eğimin yeterli olup olmadığını kontrol etmeden, muhtemelen gereksiz yere karmaşık olan bir çözüm kullanmasına neden oldu. Bahse girerim, bu optimizasyonu çalıştırmak için belki bir haftalık bir hafta geçirdik. En azından, üretilen gradyanı dikkatlice test etmesi için ona danışmanlık yapardım. Doğru muydu? Sonlu fark türevlerine kıyasla ne kadar doğruydu? Aslında bugün, türev tahminlerindeki hatanın bir tahminini de döndürecek araçlar var. Bu kesinlikle MATLAB'de yazdığım uyarlamalı farklılaşma kodu (derivest) için geçerlidir .

Kodu test edin. Türevleri doğrulayın.

Ancak, HERHANGİ BİRİNİ yapmadan önce, daha iyi optimizasyon şemalarının bir seçenek olup olmadığını düşünün. Örneğin, üstel uydurma yapıyorsanız, bölümlenmiş doğrusal olmayan en küçük kareler (bazen ayrılabilir en küçük kareler olarak adlandırılır) kullanabilmeniz için çok iyi bir şans var. parametre kümesini öz doğrusal ve öz doğrusal olmayan kümelere ayırmaktır. Yalnızca doğrusal olmayan parametrelerde çalışan bir optimizasyon kullanın. Bu parametrelerin "bilindiği" göz önüne alındığında, kendinden doğrusal parametreler basit doğrusal en küçük kareler kullanılarak tahmin edilebilir. Bu şema optimizasyondaki parametre alanını azaltacaktır. Doğrusal parametreler için başlangıç ​​değerleri bulmanız gerekmediğinden sorunu daha sağlam hale getirir. Arama alanınızın boyutsallığını azaltır, böylece sorunun daha hızlı çalışmasını sağlar. Yine sağladımsadece MATLAB'de bu amaç için bir araç .

Analitik türevleri kullanıyorsanız, terimleri yeniden kullanmak için bunları kodlayın. Bu ciddi bir zaman tasarrufu olabilir ve gerçekte hataları azaltarak zamandan tasarruf etmenizi sağlayabilir. Ama sonra bu sayıları kontrol edin!


5

Dikkate alınması gereken birkaç strateji vardır:

  1. Bir CAS kullanarak sembolik formdaki türevleri bulun, sonra türevleri hesaplamak için kodu dışa aktarın.

  2. Fonksiyonları hesaplamak için koddan türevleri hesaplayan kod üretmek için otomatik bir farklılaştırma (AD) aracı kullanın.

  3. Jacobian'a yaklaşmak için sonlu fark yaklaşımlarını kullanın.

Otomatik farklılaşma, tüm Jacobian'ı hesaplamak için daha verimli bir kod üretebilir, daha sonra matristeki her giriş için bir formül üretmek için sembolik hesaplama kullanır. Sonlu farklar, türevlerinizi iki kez kontrol etmenin iyi bir yoludur.



1

BrianBorcher'ın mükemmel önerilerine ek olarak, gerçek değerli işlevler için olası bir başka yaklaşım, karmaşık adım türev yaklaşımını kullanmaktır ( bu makaleye (ödeme duvarı) ve bu makaleye bakın ). Bazı durumlarda, bu yaklaşım, işlevinizdeki değişkenlerin değerlerini gerçek durumdan karmaşık duruma değiştirme pahasına daha doğru sayısal türevler verir. İkinci makalede, karmaşık adım işlevi yaklaşımının bozulabileceği bazı durumlar listelenmektedir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.