如何修改Keras代码以加载.mat格式的SVHN数据集(替代MNIST)
Got it, let's walk through exactly what you need to change to swap MNIST out for SVHN in your Keras code. Here's a step-by-step breakdown and modified full code:
Key Changes You Need to Make
1. Add Dependency for Loading .mat Files
SVHN comes in .mat format, so you'll need scipy to load it. First, install it if you haven't:
pip install scipy
2. Replace MNIST Dataset Loading with SVHN Loading
Keras doesn't have a built-in SVHN loader, so we'll use scipy.io.loadmat() to read the .mat files. You'll need to download SVHN's train.mat, test.mat (and optionally extra.mat for more training data) first, then point to their file paths in your code.
3. Adjust Image Dimensions & Input Shape
MNIST is 28x28 grayscale (1 channel), while SVHN is 32x32 RGB (3 channels). We'll update the image size variables and input shape to match this.
4. Fix Label Formatting
SVHN uses 1-10 for labels (where 10 represents the digit 0), but MNIST uses 0-9. We'll convert all 10s to 0s to align with your model's output layer (which has 10 units for digits 0-9).
5. Tweak Data Reshaping & Visualization
SVHN's image array is stored in a different shape than MNIST—we'll transpose it to match Keras' expected (num_samples, width, height, channels) format. For visualization, we'll drop the grayscale colormap since SVHN is RGB.
Modified Full Code
from __future__ import print_function import keras from keras import backend as K import tensorflow as tf import matplotlib.pyplot as plt import numpy as np # Added for concatenation if using extra data from keras.models import Sequential from keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D from scipy.io import loadmat # Added for loading .mat files # Update image dimensions for SVHN (32x32 RGB) img_rows, img_cols = 32, 32 num_channels = 3 # Load SVHN dataset (replace paths with your actual file locations) train_data = loadmat('train.mat') test_data = loadmat('test.mat') # Extract images and labels x_train = train_data['X'] y_train = train_data['y'] x_test = test_data['X'] y_test = test_data['y'] # SVHN's X is shaped (width, height, channels, num_samples) — reorder to match Keras' expected format x_train = x_train.transpose((3, 0, 1, 2)) x_test = x_test.transpose((3, 0, 1, 2)) # Convert label 10 to 0 (SVHN uses 10 to represent the digit 0) y_train[y_train == 10] = 0 y_test[y_test == 10] = 0 # Visualize a sample image image_index = 7777 print(y_train[image_index][0]) # SVHN labels are 2D arrays, so index [0] to get the scalar value plt.imshow(x_train[image_index]) # No grayscale colormap needed for RGB images plt.show() # Verify dataset shapes print('x_train shape:', x_train.shape) print('Number of images in x_train:', x_train.shape[0]) print('Number of images in x_test:', x_test.shape[0]) # Normalize pixel values to [0, 1] (same as MNIST, but for 3 channels) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 # Update input shape for RGB images input_shape = (img_rows, img_cols, num_channels) # Model architecture (only input_shape changed; feel free to tweak layers for better SVHN performance) model = Sequential() model.add(Conv2D(28, kernel_size=(3,3), input_shape=input_shape)) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(128, activation=tf.nn.relu)) model.add(Dropout(0.2)) model.add(Dense(10, activation=tf.nn.softmax)) # Compile and train (loss function stays the same since we're using sparse labels) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(x=x_train, y=y_train, epochs=2) # Evaluate model on test set model.evaluate(x_test, y_test) # Test a single prediction image_index = 9999 plt.imshow(x_test[image_index]) pred = model.predict(x_test[image_index].reshape(1, img_rows, img_cols, num_channels)) print(pred.argmax())
Bonus: Using SVHN's Extra Training Data
If you want to boost performance, you can add SVHN's extra.mat dataset to your training set. Add this code right after loading the test data:
# Load extra training data extra_data = loadmat('extra.mat') x_extra = extra_data['X'].transpose((3, 0, 1, 2)) y_extra = extra_data['y'] y_extra[y_extra == 10] = 0 # Merge with training set x_train = np.concatenate([x_train, x_extra]) y_train = np.concatenate([y_train, y_extra])
Note: SVHN is slightly more complex than MNIST, so you might want to add more convolutional layers, increase the number of filters, or train for more epochs to get better accuracy.
内容的提问来源于stack exchange,提问作者dbh91

