街景門牌号資料集(SVHN),這是一個現實世界資料集,用于開發目标檢測算法。它需要最少的資料預處理過程。它與 MNIST 資料集有些類似,但是有着更多的标注資料(超過 600,000 張圖像)。這些資料是從谷歌街景中的房屋門牌号中收集而來的。
大小:2.5GB
數量:6,30,420 張圖像,共 10 類
The Street View House Numbers (SVHN) Dataset:下載下傳位址
1、資料集概述
- 10 個類别,每個數字 1 個。數字“1”的标簽為 1,“9”的标簽為 9,“0”的标簽為 10。
- 73257 個數字用于訓練,26032 個數字用于測試,以及 531131 個額外的、難度稍低的樣本,用作額外的訓練資料
- 有兩種格式:
1. 帶有字元級邊界框的原始圖像。
2. 以單個字元為中心的類似 MNIST 的 32×32 圖像(許多圖像确實在側面包含一些幹擾項)。
2、資料集兩種方式
(半監督學習中采用這種方式)方式一:完整數字: train.tar.gz , test.tar.gz , extra.tar.gz
原生的資料集1也就是官網的 Format 1 是一些原始的未經處理的彩色圖檔,如下圖所示(不含有藍色的邊框),下載下傳的資料集含有 PNG 的圖像和 digitStruct.mat 的檔案,其中包含了邊框的位置資訊,這個資料集每張圖檔上有好幾個數字,适用于 OCR 相關方向。這裡采用 Format2, Format2 将這些數字裁剪成32x32的大小,如圖所示,并且資料是 .mat 檔案。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLiJGZ1ETN1MjZjJWY1EWN4UjNzQjMyQzY2IDO2UTZiV2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
這些是帶有字元級别邊界框的原始可變分辨率彩色門牌号圖像,如上面的示例圖像所示。(這裡的藍色邊界框隻是為了說明目的。邊界框資訊存儲在digitStruct.mat中,而不是直接繪制在資料集中的圖像上。)每個 tar.gz 檔案包含 png 格式的原始圖像,以及一個digitStruct.mat 檔案,可以使用 Matlab 加載。digitStruct.mat 檔案包含一個名為digitStruct的結構,其長度與原始圖像的數量相同。digitStruct 中的每個元素都有以下字段:name是一個包含相應圖像檔案名的字元串。 bbox這是一個結構數組,包含圖像中每個數字邊界框的位置、大小和标簽。例如:digitStruct(300).bbox(2).height給出第 300 個圖像中第 2 個數字邊界框的高度。
方式二:裁剪的數字 train_32x32.mat , test_32x32.mat , extra_32x32.mat
以類似 MNIST 的格式表示的字元級基本事實。所有數字都已調整為 32 x 32 像素的固定分辨率。原始字元邊界框在适當的次元上擴充成為方形視窗,是以将它們調整為 32×32 像素不會引入縱橫比失真。然而,這種預處理在感興趣數字的兩側引入了一些分散注意力的數字。加載 .mat 檔案會建立 2 個變量:X是包含圖像的 4 維矩陣,y是類标簽的向量。要通路圖像,X(:,:,:,i)給出第 i 個 32×32 RGB 圖像,類标簽為y(i)。
3.資料處理
資料集含有兩個變量 X 代表圖像, 訓練集 X 的 shape 是 (32,32,3,73257) 也就是(width, height, channels, samples), tensorflow 的張量需要 (samples, width, height, channels),是以需要轉換一下,由于直接調用 cifar 10 的網絡模型,資料隻需要先做個歸一化,所有像素除于255就 OK,另外原始資料 0 的标簽是 10,這裡要轉化成 0,并提供 one_hot 編碼。
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 19 09:55:36 2017
@author: cheers
"""
import scipy.io as sio
import matplotlib.pyplot as plt
import numpy as np
image_size = 32
num_labels = 10
def display_data():
print 'loading Matlab data...'
train = sio.loadmat('train_32x32.mat')
data=train['X']
label=train['y']
for i in range(10):
plt.subplot(2,5,i+1)
plt.title(label[i][0])
plt.imshow(data[...,i])
plt.axis('off')
plt.show()
def load_data(one_hot = False):
train = sio.loadmat('train_32x32.mat')
test = sio.loadmat('test_32x32.mat')
train_data=train['X']
train_label=train['y']
test_data=test['X']
test_label=test['y']
train_data = np.swapaxes(train_data, 0, 3)
train_data = np.swapaxes(train_data, 2, 3)
train_data = np.swapaxes(train_data, 1, 2)
test_data = np.swapaxes(test_data, 0, 3)
test_data = np.swapaxes(test_data, 2, 3)
test_data = np.swapaxes(test_data, 1, 2)
test_data = test_data / 255.
train_data =train_data / 255.
for i in range(train_label.shape[0]):
if train_label[i][0] == 10:
train_label[i][0] = 0
for i in range(test_label.shape[0]):
if test_label[i][0] == 10:
test_label[i][0] = 0
if one_hot:
train_label = (np.arange(num_labels) == train_label[:,]).astype(np.float32)
test_label = (np.arange(num_labels) == test_label[:,]).astype(np.float32)
return train_data,train_label, test_data,test_label
if __name__ == '__main__':
load_data(one_hot = True)
display_data()
3、TFearn 訓練
注意 ImagePreprocessing 對資料做了 0 均值化。網絡結構也比較簡單,直接調用 TFlearn 的 cifar10 例子。
from __future__ import division, print_function, absolute_import
import tflearn
from tflearn.data_utils import shuffle, to_categorical
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.estimator import regression
from tflearn.data_preprocessing import ImagePreprocessing
from tflearn.data_augmentation import ImageAugmentation
# Data loading and preprocessing
import svhn_data as SVHN
X, Y, X_test, Y_test = SVHN.load_data(one_hot = True)
X, Y = shuffle(X, Y)
# Real-time data preprocessing
img_prep = ImagePreprocessing()
img_prep.add_featurewise_zero_center()
img_prep.add_featurewise_stdnorm()
# Convolutional network building
network = input_data(shape=[None, 32, 32, 3],
data_preprocessing=img_prep)
network = conv_2d(network, 32, 3, activation='relu')
network = max_pool_2d(network, 2)
network = conv_2d(network, 64, 3, activation='relu')
network = conv_2d(network, 64, 3, activation='relu')
network = max_pool_2d(network, 2)
network = fully_connected(network, 512, activation='relu')
network = dropout(network, 0.5)
network = fully_connected(network, 10, activation='softmax')
network = regression(network, optimizer='adam',
loss='categorical_crossentropy',
learning_rate=0.001)
# Train using classifier
model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit(X, Y, n_epoch=15, shuffle=True, validation_set=(X_test, Y_test),
show_metric=True, batch_size=96, run_id='svhn_cnn')
訓練結果:
Training Step: 11452 | total loss: 0.68217 | time: 7.973s
| Adam | epoch: 015 | loss: 0.68217 - acc: 0.9329 -- iter: 72576/73257
Training Step: 11453 | total loss: 0.62980 | time: 7.983s
| Adam | epoch: 015 | loss: 0.62980 - acc: 0.9354 -- iter: 72672/73257
Training Step: 11454 | total loss: 0.58649 | time: 7.994s
| Adam | epoch: 015 | loss: 0.58649 - acc: 0.9356 -- iter: 72768/73257
Training Step: 11455 | total loss: 0.53254 | time: 8.005s
| Adam | epoch: 015 | loss: 0.53254 - acc: 0.9421 -- iter: 72864/73257
Training Step: 11456 | total loss: 0.49179 | time: 8.016s
| Adam | epoch: 015 | loss: 0.49179 - acc: 0.9416 -- iter: 72960/73257
Training Step: 11457 | total loss: 0.45679 | time: 8.027s
| Adam | epoch: 015 | loss: 0.45679 - acc: 0.9433 -- iter: 73056/73257
Training Step: 11458 | total loss: 0.42026 | time: 8.038s
| Adam | epoch: 015 | loss: 0.42026 - acc: 0.9469 -- iter: 73152/73257
Training Step: 11459 | total loss: 0.38929 | time: 8.049s
| Adam | epoch: 015 | loss: 0.38929 - acc: 0.9491 -- iter: 73248/73257
Training Step: 11460 | total loss: 0.35542 | time: 9.928s
| Adam | epoch: 015 | loss: 0.35542 - acc: 0.9542 | val_loss: 0.40315 - val_acc: 0.9085 -- iter: 73257/73257