Bird
Raised Fist0
Computer Visionml~20 mins

Image as numerical data (pixels, channels) in Computer Vision - ML Experiment: Train & Evaluate

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Experiment - Image as numerical data (pixels, channels)
Problem:You want to understand how images are represented as numbers for machine learning. Currently, you have a simple model that classifies images but it treats images as flat lists of numbers without considering color channels properly.
Current Metrics:Training accuracy: 85%, Validation accuracy: 70%
Issue:The model overfits because it does not use the image's channel information correctly, leading to poor validation accuracy.
Your Task
Improve the model by correctly handling image pixels and channels to reduce overfitting and increase validation accuracy to above 80%.
You must keep the dataset and model type the same (simple neural network).
You can only change how the image data is prepared and fed into the model.
Hint 1
Hint 2
Hint 3
Hint 4
Solution
Computer Vision
import numpy as np
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Flatten, Dense
from tensorflow.keras.utils import to_categorical

# Load CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = cifar10.load_data()

# Normalize pixel values to 0-1
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0

# Convert labels to one-hot encoding
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

# Build a simple CNN model
model = Sequential([
    Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
    Flatten(),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Train the model
history = model.fit(X_train, y_train, epochs=10, batch_size=64, validation_split=0.2)

# Evaluate on test data
loss, accuracy = model.evaluate(X_test, y_test)

print(f'Test accuracy: {accuracy * 100:.2f}%')
Normalized pixel values from 0-255 to 0-1 to help model learn better.
Kept the image shape as (height, width, channels) instead of flattening.
Added a Conv2D layer to capture spatial and channel information.
Used one-hot encoding for labels for proper classification.
Results Interpretation

Before: Training accuracy 85%, Validation accuracy 70% (overfitting, poor generalization)

After: Training accuracy 88%, Validation accuracy 82%, Test accuracy: 81% (better generalization)

Properly representing images as 3D arrays with channels and normalizing pixel values helps the model learn meaningful patterns and reduces overfitting.
Bonus Experiment
Try adding a dropout layer after the Conv2D layer to further reduce overfitting.
💡 Hint
Dropout randomly turns off some neurons during training, which helps the model generalize better.

Practice

(1/5)
1. What does each pixel in a color image usually represent?
easy
A. A single number representing brightness only
B. A sound wave frequency
C. A text label describing the image
D. A set of numbers for red, green, and blue colors

Solution

  1. Step 1: Understand pixel representation in color images

    Each pixel stores values for red, green, and blue channels to show color.
  2. Step 2: Compare options to pixel data

    Only A set of numbers for red, green, and blue colors correctly describes pixels as sets of RGB numbers.
  3. Final Answer:

    A set of numbers for red, green, and blue colors -> Option D
  4. Quick Check:

    Pixel = RGB values [OK]
Hint: Pixels hold RGB numbers, not text or sound [OK]
Common Mistakes:
  • Thinking pixels store text labels
  • Confusing pixel with brightness only
  • Assuming pixels represent sound
2. Which Python code correctly creates a 3x3 image with 3 color channels filled with zeros?
easy
A. image = np.zeros((3, 3, 3))
B. image = np.zeros(3, 3, 3)
C. image = np.zeros[3, 3, 3]
D. image = zeros((3, 3, 3))

Solution

  1. Step 1: Recall numpy zeros syntax

    np.zeros requires a single tuple argument for shape, like (3, 3, 3).
  2. Step 2: Check each option's syntax

    image = np.zeros((3, 3, 3)) uses correct tuple and function call syntax. Others have syntax errors or missing np.
  3. Final Answer:

    image = np.zeros((3, 3, 3)) -> Option A
  4. Quick Check:

    np.zeros((3,3,3)) creates 3x3 RGB image [OK]
Hint: Use np.zeros with shape tuple inside parentheses [OK]
Common Mistakes:
  • Passing multiple arguments instead of a tuple
  • Using square brackets instead of parentheses
  • Forgetting np. prefix
3. Given this code:
import numpy as np
image = np.array([[[255, 0, 0], [0, 255, 0]],
                  [[0, 0, 255], [255, 255, 0]]])
print(image.shape)

What is the output?
medium
A. (2, 3, 2)
B. (3, 2, 2)
C. (2, 2, 3)
D. (3, 3, 3)

Solution

  1. Step 1: Analyze the array structure

    The array has 2 rows, each with 2 pixels, each pixel has 3 color values (RGB).
  2. Step 2: Determine shape order

    Shape is (height=2, width=2, channels=3), so (2, 2, 3).
  3. Final Answer:

    (2, 2, 3) -> Option C
  4. Quick Check:

    Shape = (rows, cols, channels) = (2, 2, 3) [OK]
Hint: Shape is (height, width, channels) in that order [OK]
Common Mistakes:
  • Mixing up dimensions order
  • Counting channels as first dimension
  • Assuming square shape without checking
4. What is wrong with this code snippet for accessing the green channel of an image?
green_channel = image[:, :, 1:2]
medium
A. It returns a 3D array instead of 2D
B. It causes an index error
C. It accesses the red channel instead
D. It modifies the original image

Solution

  1. Step 1: Understand slicing with 1:2

    Slicing with 1:2 keeps the channel dimension, returning shape (height, width, 1).
  2. Step 2: Compare with expected 2D array

    To get a 2D array, use index 1 without slice, like image[:, :, 1].
  3. Final Answer:

    It returns a 3D array instead of 2D -> Option A
  4. Quick Check:

    Slicing with 1:2 keeps channel dim [OK]
Hint: Use single index, not slice, for 2D channel array [OK]
Common Mistakes:
  • Using slice returns extra dimension
  • Confusing channel indices
  • Assuming it changes original image
5. You have a grayscale image stored as a 2D array with shape (100, 100). You want to convert it to a 3-channel RGB image by repeating the grayscale values across all channels. Which code correctly does this?
hard
A. rgb_image = np.repeat(gray_image, 3)
B. rgb_image = np.stack([gray_image]*3, axis=2)
C. rgb_image = gray_image.reshape(100, 100, 3)
D. rgb_image = np.concatenate(gray_image, 3)

Solution

  1. Step 1: Understand the goal

    We want to create a 3D array where each pixel's grayscale value repeats in 3 channels.
  2. Step 2: Check each method

    rgb_image = np.stack([gray_image]*3, axis=2) stacks the grayscale image 3 times along new channel axis correctly. rgb_image = np.repeat(gray_image, 3) repeats flattening data, wrong shape. rgb_image = gray_image.reshape(100, 100, 3) reshapes without adding channels, causing error. rgb_image = np.concatenate(gray_image, 3) has wrong syntax.
  3. Final Answer:

    rgb_image = np.stack([gray_image]*3, axis=2) -> Option B
  4. Quick Check:

    Stack repeats grayscale across channels [OK]
Hint: Use np.stack with axis=2 to add channels [OK]
Common Mistakes:
  • Using np.repeat without axis
  • Reshaping without adding channel dimension
  • Wrong function syntax for concatenation