我想在astropy.modelling中使用Model.tied
(或Parameter.tied
)屬性,但似乎無法弄清楚它是如何工作的。例如,假設我想創建具有兩個參數的複合模型:flux_0
和flux_1
。但是,我只想在配件中使用flux_0
:flux_1
應始終攜帶值1 - flux_0
。 (最後,我需要擴展該功能使得flux_0 + flux_1 + ... + flux_n = 1
。)在astropy.modeling中綁定參數
我定義模型類和「可調用」爲tied
屬性像這樣:
>>> from astropy.modeling import Fittable1DModel, Parameter
>>>
>>> class MyModel(Fittable1DModel):
... flux = Parameter()
... @staticmethod
... def evaluate(x, flux):
... return flux
...
>>> def tie_fluxes(model):
... flux_1 = 1 - model.flux_0
... return flux_1
...
>>> TwoModel = MyModel + MyModel
>>>
>>> TwoModel
<class '__main__.CompoundModel0'>
Name: CompoundModel0
Inputs: ('x',)
Outputs: ('y',)
Fittable parameters: ('flux_0', 'flux_1')
Expression: [0] + [1]
Components:
[0]: <class '__main__.MyModel'>
Name: MyModel
Inputs: ('x',)
Outputs: ('y',)
Fittable parameters: ('flux',)
[1]: <class '__main__.MyModel'>
Name: MyModel
Inputs: ('x',)
Outputs: ('y',)
Fittable parameters: ('flux',)
然後我檢查tied
屬性。我的理解是,這應該是一個字典(見注),但它不是:
>>> TwoModel.tied
<property object at 0x109523958>
>>>
>>> TwoModel.tied['flux_1'] = tie_fluxes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'property' object does not support item assignment
如果我嘗試設置它作爲一個字典,它不會更新相應的Parameter
:
>>> TwoModel.tied = {'flux_1': tie_fluxes}
>>>
>>> TwoModel.flux_1.tied
False
但是,當我嘗試創建一個對象而不是複合模型類(這不是我想要做的最後)時,對象的tied
屬性是一個字典。不幸的是,設置這個字典仍然沒有產生預期的效果:
>>> TwoSetModel = MyModel(0.2) + MyModel(0.3)
>>>
>>> TwoSetModel
<CompoundModel1(flux_0=0.2, flux_1=0.3)>
>>>
>>> TwoSetModel.tied
{'flux_1': False, 'flux_0': False}
>>>
>>> TwoSetModel.tied['flux_1'] = tie_fluxes
>>>
>>> TwoSetModel
<CompoundModel1(flux_0=0.2, flux_1=0.3)>
>>>
>>> TwoSetModel.flux_1.tied
<function tie_fluxes at 0x102987730>
所以在這個例子中,tied
屬性確實保持正確的功能,但參數的value
沒有相應的更新。
我在這裏做錯了什麼?我完全誤解了tied
屬性?
(我在上面的例子中使用Python 3.5.2與1.3.3 Astropy)
腳註:
運行help(TwoModel)
,我得到以下信息:
⁝
| tied : dict, optional
| Dictionary ``{parameter_name: callable}`` of parameters which are
| linked to some other parameter. The dictionary values are callables
| providing the linking relationship.
|
| Alternatively the `~astropy.modeling.Parameter.tied` property of a
| parameter may be used to set the ``tied`` constraint on individual
| parameters.
⁝
| Examples
| --------
| >>> from astropy.modeling import models
| >>> def tie_center(model):
| ... mean = 50 * model.stddev
| ... return mean
| >>> tied_parameters = {'mean': tie_center}
|
| Specify that ``'mean'`` is a tied parameter in one of two ways:
|
| >>> g1 = models.Gaussian1D(amplitude=10, mean=5, stddev=.3,
| ... tied=tied_parameters)
|
| or
|
| >>> g1 = models.Gaussian1D(amplitude=10, mean=5, stddev=.3)
| >>> g1.mean.tied
| False
| >>> g1.mean.tied = tie_center
| >>> g1.mean.tied
| <function tie_center at 0x...>
⁝
好問題 - 我寫了大部分代碼,所以我應該能夠回答你的問題。我即將出發的一天,但我會盡快找回。不幸的是,IIRC處理複合模型的約束仍然有點棘手。 – Iguananaut
我現在可以告訴你的一件事 - 你似乎陷入了一個常見的誤解,即在手動更新參數值時應用模型約束。不是這種情況。約束條件*只適用於擬合模型的擬合者,以便對參數設置約束條件。不符合擬合約束條件。我曾考慮過改變它,以便它能像你期望的那樣工作。有一個問題在某一點上公開,但我現在似乎無法找到它...... – Iguananaut
我認爲https://github.com/astropy/astropy/issues/2265提供了一些參考。 – Iguananaut