How to do a PCA with Flux

I am trying to use Flux to do a Principal Component Analysis of a simple database (íris) but I am having some problems with Flux.train!` which gives me the following error:

ERROR: MethodError: no method matching loss(::SubArray{Float64, 1, Matrix{Float64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, ::SubArray{Float64, 1, Matrix{Float64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true})
Closest candidates are:
  loss(::Any) at c:\Users\sergio.bacelar\Documents\JULIA\PCA_jl\ex4.jl:32

The code I have been using is:

using Flux, RDatasets, Statistics, StatsBase

# Load the iris dataset
iris = dataset("datasets", "iris")
# Split the data into features (X) and labels (y)
X = Matrix(iris[:, 1:4])
y = iris[:, 5]
# Standardize the data
X_standardized = standardize(ZScoreTransform, X, dims=1)
# Define the PCA model
model = Chain(Dense(4, 2), transpose)
# Define the loss function
loss(x) = sum(abs2, x - mean(x))
# Train the model
opt = ADAM(0.1)
data = [(x, x) for x in eachrow(X_standardized)]

for i = 1:100
Flux.train!(loss, Flux.params(model), data, opt)

# Get the principal components and the transformed data
pcs = model. Layers[1]
X_transformed = model(X_standardized) |> transpose
# Print the results
println("Principal Components: ")
println("Transformed Data: ")

You should read carefully the documentation regarding the train loop
Your loss function has two problems: a) doesn’t use the model; b) takes only one input, while the dataset iterator yields tuples with 2 elements.

1 Like