1

コンパイルできない次のコードがあります。

  import Numeric.AD

  data Trainable a b = forall n . Floating n =>  Trainable ([n] -> a -> b) (a -> b -> [n] -> n) 

  trainSgdFull :: (Floating n, Ord n) => Trainable a b -> [n] -> a -> b -> [[n]]
  trainSgdFull (Trainable _ cost) init input target =  gradientDescent (cost input target) init

勾配降下法によってトレーニング可能な機械学習システムを表すために、Trainable 型を使用したいと考えています。最初の引数は伝達関数、次の引数はコスト関数、a は入力の型、b は出力/ターゲットの型で、リストには学習可能なパラメーターが含まれます。コンパイラはこれに文句を言います:

 src/MachineLearning/Training.hs:12:73:
Could not deduce (n1 ~ ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n)
from the context (Floating n, Ord n)
  bound by the type signature for
             trainSgdFull :: (Floating n, Ord n) =>
                             Trainable a b -> [n] -> a -> b -> [[n]]
  at src/MachineLearning/Training.hs:12:3-95
or from (Floating n1)
  bound by a pattern with constructor
             Trainable :: forall a b n.
                          Floating n =>
                          ([n] -> a -> b) -> (a -> b -> [n] -> n) -> Trainable a b,
           in an equation for `trainSgdFull'
  at src/MachineLearning/Training.hs:12:17-32
or from (Numeric.AD.Internal.Classes.Mode s)
  bound by a type expected by the context:
             Numeric.AD.Internal.Classes.Mode s =>
             [ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n]
             -> ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n
  at src/MachineLearning/Training.hs:12:56-95
  `n1' is a rigid type variable bound by
       a pattern with constructor
         Trainable :: forall a b n.
                      Floating n =>
                      ([n] -> a -> b) -> (a -> b -> [n] -> n) -> Trainable a b,
       in an equation for `trainSgdFull'
       at src/MachineLearning/Training.hs:12:17
Expected type: [ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n1]
               -> ad-3.3.1.1:Numeric.AD.Internal.Types.AD s n1
  Actual type: [n] -> n
In the return type of a call of `cost'
In the first argument of `gradientDescent', namely
  `(cost input target)'

基本的な考え方は正しいですか?もしそうなら、どうすればコードをコンパイルできますか?

4

1 に答える 1

7

問題はそれです

data Trainable a b = forall n . Floating n =>  Trainable ([n] -> a -> b) (a -> b -> [n] -> n)

意味する

Trainable transfer cost

使用されたタイプnは失われます。わかっているのは、次のようなインスタンスGuessmeを持つ型があるということだけです。Floating

transfer :: [Guessme] -> a -> b
cost :: a -> b -> [Guessme] -> Guessme

のみ、または のみ、または ...に対してTrainableのみ機能する関数を使用してを構築できます。Complex FloatDouble

しかし、

trainSgdFull :: (Floating n, Ord n) => Trainable a b -> [n] -> a -> b -> [[n]]
trainSgdFull (Trainable _ cost) init input target =  gradientDescent (cost input target) init

引数として指定された型で使用しようとしてcostいます。Floating

Trainabletype で動作するように構築されてn0おり、ユーザーが type を指定していますn1が、これらは同じである場合と異なる場合があります。したがって、コンパイラはそれらが同じであると推測できません。

nの型パラメーターを作成したくない場合は、呼び出し元が提供するすべてTrainableの型で動作する多相関数をラップする必要があります Floating

data Trainable a b
    = Trainable (forall n. Floating n => [n] -> a -> b)
                (forall n. Floating n => a -> b -> [n] -> n)

(Rank2Typesまたは が必要です。これは非推奨になる過程にあるためですRankNTypes)。

于 2013-02-06T19:01:28.187 に答える