forked from brendenlake/omniglot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added python demo and 5 alphabet background sets
- Loading branch information
1 parent
edbf998
commit 32aee47
Showing
10 changed files
with
164 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
matlab_to_python | ||
python/images_background | ||
python/images_background_small1 | ||
python/images_background_small2 | ||
python/images_evaluation | ||
python/one-shot-classification/run** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,52 @@ | ||
# omniglot | ||
Omniglot data set for one-shot character recognition. | ||
# Omniglot data set for one-shot learning | ||
|
||
This dataset contains 1623 handwritten characters from 50 different alphabets. | ||
Each of the 1623 characters was drawn online via Amazon's Mechanical Turk by 20 different people. | ||
Each image is paired with stroke data (formatted as [x,y,time in milliseconds]). | ||
This dataset contains 1623 different handwritten characters from 50 different alphabets. | ||
Each of the 1623 characters was drawn online via Amazon's Mechanical Turk by 20 different people. | ||
Each image is paired with stroke data, a sequences of [x,y,t] coordinates with time (t) in milliseconds. Stroke data is available in MATLAB files only. | ||
|
||
MATLAB: | ||
Learn about the structure of the data set by running 'demo.m'. | ||
There are two main data files: 'data_background.mat' (30 alphabets) and 'data_evaluation.mat' (20 alphabets). The one-shot learning results we report involve only characters from 'data_evaluation', while 'data_background' can be used by algorithms to learn general knowledge about characters. | ||
### CONTENTS | ||
The Omniglot data set contains 50 alphabets total. | ||
|
||
To compare with the one-shot classification results in our paper, use 'demo_classification.m' in the 'one-shot-classification' folder to run the baseline Modified Hausdorff Distance. | ||
Here is the split: | ||
background : 30 alphabets | ||
evaluation : 20 alphabets | ||
|
||
PYTHON: | ||
Coming soon | ||
To compare with the results in our paper, only the background set should be used by algorithms to learn general knowledge about characters (e.g., hyper-parameter inference or feature learning). One-shot learning results are reported using alphabets from the evaluation set. | ||
|
||
To cite this data set, please cite the following paper: | ||
For a smaller and more challenging background set, the sets "background small 1" and "background small 2" contain just 5 alphabets each. | ||
|
||
|
||
### MATLAB | ||
|
||
Learn about the structure of the data set by running the script 'demo.m'. | ||
|
||
Key data files: | ||
data_background.mat | ||
data_evaluation.mat | ||
data_background_small1.mat | ||
data_background_small2.mat | ||
|
||
To compare with the one-shot classification results in our paper, run 'demo_classification.m' in the 'one-shot-classification' folder to demo a baseline model using Modified Hausdorff Distance. | ||
|
||
|
||
### PYTHON | ||
|
||
Python 2.7.* | ||
Requires scipy and numpy | ||
|
||
Key data files: | ||
images_background.zip | ||
images_evaluation.zip | ||
images_background_small1.zip | ||
images_background_small2.zip | ||
|
||
To compare with the one-shot classification results in our paper, enter the 'one-shot-classification' directory and unzip 'all_runs.zip' and place all the folders 'run01',...,'run20' in the current directory. Run 'demo_classification.py' to demo a baseline model using Modified Hausdorff Distance. | ||
|
||
|
||
### Citing this data set | ||
Please cite the following paper: | ||
|
||
Human-level concept learning through probabilistic program induction | ||
By Brenden Lake, Ruslan Salakhutdinov, and Joshua Tenenbaum | ||
Email: brenden at-sign nyu dot edu | ||
By Brenden Lake, Ruslan Salakhutdinov, and Joshua Tenenbaum | ||
|
||
We are grateful for the www.omniglot.com encyclopedia of writing systems for helping to make this data set possible. | ||
We are grateful for the [Omniglot](http://www.omniglot.com/) encyclopedia of writing systems for helping to make this data set possible. |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import numpy as np | ||
import copy | ||
from scipy.ndimage import imread | ||
from scipy.spatial.distance import cdist | ||
|
||
# Parameters | ||
nrun = 20 # number of classification runs | ||
fname_label = 'class_labels.txt' # where class labels are stored for each run | ||
|
||
def classification_run(folder,f_load,f_cost,ftype='cost'): | ||
# Compute error rate for one run of one-shot classification | ||
# | ||
# Input | ||
# folder : contains images for a run of one-shot classification | ||
# f_load : itemA = f_load('file.png') should read in the image file and process it | ||
# f_cost : f_cost(itemA,itemB) should compute similarity between two images, using output of f_load | ||
# ftype : 'cost' if small values from f_cost mean more similar, or 'score' if large values are more similar | ||
# | ||
# Output | ||
# perror : percent errors (0 to 100% error) | ||
# | ||
assert ((ftype=='cost') | (ftype=='score')) | ||
|
||
# get file names | ||
with open(folder+'/'+fname_label) as f: | ||
content = f.read().splitlines() | ||
pairs = [line.split() for line in content] | ||
test_files = [pair[0] for pair in pairs] | ||
train_files = [pair[1] for pair in pairs] | ||
answers_files = copy.copy(train_files) | ||
test_files.sort() | ||
train_files.sort() | ||
ntrain = len(train_files) | ||
ntest = len(test_files) | ||
|
||
# load the images (and, if needed, extract features) | ||
train_items = [f_load(f) for f in train_files] | ||
test_items = [f_load(f) for f in test_files ] | ||
|
||
# compute cost matrix | ||
costM = np.zeros((ntest,ntrain),float) | ||
for i in range(ntest): | ||
for c in range(ntrain): | ||
costM[i,c] = f_cost(test_items[i],train_items[c]) | ||
if ftype == 'cost': | ||
YHAT = np.argmin(costM,axis=1) | ||
elif ftype == 'score': | ||
YHAT = np.argmax(costM,axis=1) | ||
else: | ||
assert False | ||
|
||
# compute the error rate | ||
correct = 0.0 | ||
for i in range(ntest): | ||
if train_files[YHAT[i]] == answers_files[i]: | ||
correct += 1.0 | ||
pcorrect = 100 * correct / ntest | ||
perror = 100 - pcorrect | ||
return perror | ||
|
||
def ModHausdorffDistance(itemA,itemB): | ||
# Modified Hausdorff Distance | ||
# | ||
# Input | ||
# itemA : [n x 2] coordinates of "inked" pixels | ||
# itemB : [m x 2] coordinates of "inked" pixels | ||
# | ||
# M.-P. Dubuisson, A. K. Jain (1994). A modified hausdorff distance for object matching. | ||
# International Conference on Pattern Recognition, pp. 566-568. | ||
# | ||
D = cdist(itemA,itemB) | ||
mindist_A = D.min(axis=1) | ||
mindist_B = D.min(axis=0) | ||
mean_A = np.mean(mindist_A) | ||
mean_B = np.mean(mindist_B) | ||
return max(mean_A,mean_B) | ||
|
||
def LoadImgAsPoints(fn): | ||
# Load image file and return coordinates of 'inked' pixels in the binary image | ||
# | ||
# Output: | ||
# D : [n x 2] rows are coordinates | ||
I = imread(fn,flatten=True) | ||
I = np.array(I,dtype=bool) | ||
I = np.logical_not(I) | ||
(row,col) = I.nonzero() | ||
D = np.array([row,col]) | ||
D = np.transpose(D) | ||
D = D.astype(float) | ||
n = D.shape[0] | ||
mean = np.mean(D,axis=0) | ||
for i in range(n): | ||
D[i,:] = D[i,:] - mean | ||
return D | ||
|
||
if __name__ == "__main__": | ||
# | ||
# Running this demo should lead to a result of 38.8 percent errors. | ||
# | ||
# M.-P. Dubuisson, A. K. Jain (1994). A modified hausdorff distance for object matching. | ||
# International Conference on Pattern Recognition, pp. 566-568. | ||
# | ||
# ** Models should be trained on images in 'images_background' directory to avoid | ||
# using images and alphabets used in the one-shot evaluation ** | ||
# | ||
perror = np.zeros(nrun) | ||
for r in range(1,nrun+1): | ||
rs = str(r) | ||
if len(rs)==1: | ||
rs = '0' + rs | ||
perror[r-1] = classification_run('run'+rs, LoadImgAsPoints, ModHausdorffDistance, 'cost') | ||
print " run " + str(r) + " (error " + str( perror[r-1] ) + "%)" | ||
total = np.mean(perror) | ||
print " average error " + str(total) + "%" |