MathNumerics.LinearAlgebra Matrix.mapRows проблемы размерности

Итак, я проверил, что начальная версия того, что я пытаюсь сделать, работает, но по какой-то причине при помещении ее в функцию высокого порядка Matrix.map она ломается.

Вот неисправная функция:

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount
    let theta' = theta.ToRowMatrix()
    trainingData     
    |> Matrix.mapRows(fun a r -> (theta' * r) - y.[a] )

Вот несколько примеров тестов

Настраивать:

let tData = matrix [[1.0; 2.0]
                    [1.0; 3.0]
                    [1.0; 3.0]
                    [1.0; 4.0]]   
let yVals = vector [5.0; 6.0; 7.0; 11.0]      
let theta = vector [1.0; 0.2]  

Протестируйте необработанные функциональные возможности базовой операции (тета-транспонирование * вектор - фактический)

let theta' = theta.ToRowMatrix()
(theta.ToRowMatrix() * tData.[0, 0 .. 1]) - yVals.[0]

Тестирование в реальной работе:

tData |> SumSquares theta yVals

Вот копия/вставка фактической ошибки. Это читается так, как будто у меня проблемы с отображением большего вектора на меньший вектор.

Имя параметра: цель

в MathNet.Numerics.LinearAlgebra.Storage.VectorStorage1.CopyToRow(MatrixStorage1 цель, Int32 rowIndex, ExistingData, существующие данные)
в FSI_0061.SumSquares(Vector1 theta, Vector1 y, Matrix`1 trainingData) в C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning. fsx:строка 23
в .$FSI_0084.main@() в C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning.fsx:строка 39
Остановлено из-за ошибки


person David Crook    schedule 17.05.2016    source источник
comment
Это настоящее исключение, верно? System.ArgumentException: All vectors must have the same dimensionality.   -  person s952163    schedule 17.05.2016
comment
Представляет интерес: Тег глубокого обучения   -  person Guy Coder    schedule 17.05.2016
comment
да, мы в основном собираемся использовать это как часть понимания стоимости по мере развития нашего алгоритма обучения.   -  person David Crook    schedule 17.05.2016


Ответы (2)


Поскольку вы знаете количество строк, вы можете просто сопоставить их. Возможно, это некрасиво:

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount
    let theta' = theta.ToRowMatrix()                                             
    [0..m-1] |> List.map (fun i -> (((theta' * trainingData.[i,0..1]) |> Seq.exactlyOne) - yVals.[i] ))

Редактировать:
Я предполагаю, что mapRows хочет, чтобы все было в одной форме, а ваш выходной вектор отличается. Поэтому, если вы хотите придерживаться типа Vector, это просто перечислит проиндексированные строки:

tData.EnumerateRowsIndexed() |> Seq.map (fun (i,r) -> (theta' * r) - yVals.[i])
и вы также можете использовать Matrix.toRowSeqi, если вы предпочитаете передать его и получить матрицу:

tData 
    |> Matrix.toRowSeqi 
    |> Seq.map (fun (i,x) -> (theta' * x) - yVals.[i]) 
    |> DenseMatrix.ofRowSeq
person s952163    schedule 17.05.2016
comment
Последнее - деньги. Это то, что я в итоге реализовал, работает как переворачивающееся очарование! - person David Crook; 17.05.2016
comment
На самом деле я остановился на этом, потому что это сумма квадратов: пусть SumSquares (theta:Vector‹float›) (y:Vector‹float›) (trainingData:Matrix‹float›) = let theta' = theta.ToRowMatrix() trainingData | › Matrix.toRowSeqi |› Seq.map(fun (i,r) -> вектор [квадрат ((theta' * r) - y.[i]) ] ) |› DenseMatrix.ofRowSeq - person David Crook; 17.05.2016
comment
если вы можете продублировать сообщение, которое я только что сделал, я отвечу вам за ответ. - person David Crook; 18.05.2016
comment
Должно быть хорошо, так как это для дальнейшего использования, и ваш комментарий говорит сам за себя. Дал мне возможность взглянуть на Mathnet. Ваше решение довольно чистое и аккуратное. - person s952163; 18.05.2016

Я нашел еще более простой способ сделать это. Я должен отдать должное s952163 за то, что он направил меня по правильному пути, но этот подход еще более оптимизирован:

let square (x:Vector<float>) = x * x 
let subtract (x:Vector<float>) (y:Vector<float>) = y - x
let divideBy (x:float) (y:float) = y / x

let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
    let m = trainingData.RowCount |> float
    (trainingData * theta)
    |> subtract y
    |> square
    |> divideBy m
person David Crook    schedule 17.05.2016