Accuracy issues on Flux

Hello guys. I have a problem with Flux. I have a very low accuracy (about 50%) on this code and I dont know why. i converted some tf code to Flux bu i dont get the issue. i mention that i am new to Julia and Flux so maybe i am doing something wrong.

I have trianing images with dogs and cats(8000) and test images(2000)

using Augmentor
using Flux
using FileIO
using Images
using CUDA
using ProgressMeter
using Statistics
train_datagen = ShearX(0.2) * ShearY(0.2) |> Zoom(0.2) |> FlipX()

# load data from dataset folder
base_dir = "dataset/training_set/"
subdirs = readdir(base_dir)

image_label_pairs = []
for subdir in subdirs
    subdir_path = joinpath(base_dir, subdir)
    for file in readdir(subdir_path)
        # Load the image
        img = Images.load(joinpath(subdir_path, file))
        # Create a tuple of the image and the label (subdirectory name)
        push!(image_label_pairs, (img, subdir))
    end
end

images = map((X) -> augment(X[1], train_datagen), image_label_pairs)
labels = map((X) -> X[2] == "cats" ? 1.0 : 0.0, image_label_pairs)

X = [channelview(imresize(x, (64, 64))) for x in images] |> gpu
X = Flux.batch(X) |> gpu
X = permutedims(X, (2, 3, 1, 4)) |> gpu
X = Float32.(X) |> gpu
y = labels |> gpu
train_loader = Flux.Data.DataLoader((X, y'), batchsize=32, shuffle=true)
model = Chain(
    Conv((3, 3), 3 => 32, relu),
    MaxPool((2, 2)),
    Conv((3, 3), 32 => 64, relu),
    MaxPool((2, 2)),
    Flux.flatten,
    Dense(12544, 128, relu),
    Dense(128, 1),
    sigmoid
) |> gpu

opt = ADAM()


loss(x, y) = Flux.binarycrossentropy(model(x), y)
params = Flux.params(model)
epochs = 25

train_loss = []
for epoch in 1:epochs
    println("Epoch = $epoch/$epochs:")
    train_batch_loss = []
    @showprogress for (image, label) in train_loader
        x = gpu(image)
        y = gpu(label)
        Flux.train!(loss, params, [(x, y)], opt)
        push!(train_batch_loss, loss(x, y))
    end
    push!(train_loss, mean(train_batch_loss))
    println("Loss: $(train_loss[end])")
end
# calculate accuracy
base_dir = "dataset/test_set/"
subdirs = readdir(base_dir)

image_label_pairs = []
for subdir in subdirs
    subdir_path = joinpath(base_dir, subdir)
    for file in readdir(subdir_path)
        # Load the image
        img = Images.load(joinpath(subdir_path, file))
        # Create a tuple of the image and the label (subdirectory name)
        push!(image_label_pairs, (img, subdir))
    end
end

images = map((X) -> X[1], image_label_pairs)
labels = map((X) -> X[2] == "cats" ? 1.0 : 0.0, image_label_pairs)

X_test = [channelview(imresize(x, (64, 64))) for x in images] |> gpu
X_test = Flux.batch(X_test) |> gpu
X_test = permutedims(X_test, (2, 3, 1, 4)) |> gpu
X_test = Float32.(X_test) |> gpu
y_test = labels |> gpu
test_loader = Flux.Data.DataLoader((X_test, y_test'), batchsize=20, shuffle=false)

correct = 0
total = 0
for (image, label) in [(X_test, y_test')]
    ŷ = model(image)
    ŷ = ŷ .> 0.5
    total += length(label)
    correct += sum(ŷ .== label)
end
println(total)
println(correct)
println("Accuracy: $(correct / total)")
1 Like

It may be helpful to put Flux in the title and perhaps tag it as Flux as well.

Thanks. I modified

It’s hard to read your code like that. Would be easier if you used three backticks before your code and after. :pray:t2:

ok. i really wanted to know how to do that here :slight_smile:

can you help me now ? :slight_smile:

Yes i can read your code fine now but I’m AFK right now so cannot test it. Will report back when I’ve had a chance to run it. :relaxed:

1 Like

you had time to try the code? :slight_smile: @DoktorMike

Some things to check:

  1. What are the distribution of labels in your training set? Is the split of classes balanced? If this is heavily weighted towards one class, but the test set isn’t, this could cause poor performance.
  2. What are the training loss curves like? Does the training loss significantly go down vs epochs? If it does not, this could mean that the learning rate is too small or more epochs are needed.
  3. Looking at confusion matrices can be useful in seeing why your classifier is performing poorly, this could tell you about issues with your test/train split or that you need to change the weights of each class.
  4. (EDIT: This is for multiclass, binary expects “true” or “false”) Are the labels starting at zero? I think Flux expects 1 based labels, which could be worth checking. Sometimes you need to just increment each label by 1 to fix this. Could you change the labels to explicitly be booleans?

Sorry that I can’t be more specific with the guidance. These sorts of errors are very difficult to debug, without having access to the data at hand.

i tried with 40 epochs. i still have 54% accuracy. After 40 the loss curve is getting flat.
I tried to covert labels to bolean. same result. my slit is 8000 traing set and 2000 test set.

What about the number of images of cats, and the number of images of dogs? That’s the split that matters more in this case.

there aree equal numbers of cats and dogs.

What does the training accuracy look like? Does this go up over time?

can you show me a code to show to accuracy overtime? i

ok somehow i get too much accuracy now on the test set ;))

1 Like

ok the first problem was augmeantation. Now o get aroun 75% accuracy on the test set. but it get stucked there

ANyone who can help me?

try the same code on MNIST or Cifar10 from MLDatasets.jl and see if everything works as expected. If it doesn’t, post a fully reproducible script.

everything works just fine on MNIST

which accuracy do you get with tensorflow?