MATLAB Examples

Examples of Old Handwritten Japanese Character Classification

Contents

Summary

Center for Open Data in Humanities launched Japanese Classics Character Dataset in November 2016 [1]. This is a large dataset of various hand-written characters from classical documents written in the Edo period. Since these characters were written in running style, most of them are hard to read today (even for Japanese people).

[1] Japanese Classics Character Dataset: http://codh.rois.ac.jp/char-shape/

Load the Dataset

Load the subset of the dataset which is provided as a HDF5 file in [1].

% Check the contents of the HDF5 file
h5disp('train_test_file_list.h5');

% Load the data from the file. This HDF5 file contains 19,909 gray-scale
% 28x28 pixel images for training and 3,514 images for testing.
trainImage = h5read('train_test_file_list.h5','/train_x');
trainLabel = categorical(h5read('train_test_file_list.h5',...
    '/train_y'));
testImage = h5read('train_test_file_list.h5','/test_x');
testLabel = categorical(h5read('train_test_file_list.h5',...
    '/test_y'));

% Characters represented by each label (Unicode)
labelDict = {'3057','306B','306E','3066','308A',...
    '3092','304B','304F','304D','3082'};
labelDec = hex2dec(labelDict);

% Histogram of the dataset
figure
subplot(2,1,1);
histogram(trainLabel);
title('Training Data');
ax = gca;
ax.XTickLabel = char(labelDec);
subplot(2,1,2);
histogram(testLabel);
title('Test Data');
ax = gca;
ax.XTickLabel = char(labelDec);
HDF5 train_test_file_list.h5 
Group '/' 
    Dataset 'test_x' 
        Size:  28x28x3514
        MaxSize:  28x28x3514
        Datatype:   H5T_IEEE_F64LE (double)
        ChunkSize:  []
        Filters:  none
        FillValue:  0.000000
    Dataset 'test_y' 
        Size:  1x3514
        MaxSize:  1x3514
        Datatype:   H5T_STD_U8LE (uint8)
        ChunkSize:  []
        Filters:  none
        FillValue:  0
    Dataset 'train_x' 
        Size:  28x28x19909
        MaxSize:  28x28x19909
        Datatype:   H5T_IEEE_F64LE (double)
        ChunkSize:  []
        Filters:  none
        FillValue:  0.000000
    Dataset 'train_y' 
        Size:  1x19909
        MaxSize:  1x19909
        Datatype:   H5T_STD_U8LE (uint8)
        ChunkSize:  []
        Filters:  none
        FillValue:  0

Display Some of the Images in the Training Dataset

figure
for kk = 1:20
    subplot(4,5,kk);
    imshow(trainImage(:,:,kk)',[]);
    idx = str2num(char(trainLabel(kk)));
    title(['"',char(labelDec(idx+1)),'"']);
end

Data Clustering by t-SNE.

Reshape the training dataset to 19,909x784

X = reshape(trainImage,...
    size(trainImage,1)*size(trainImage,2),...
    size(trainImage,3))';

% For reproducibility
rng default;

% PCA is used to reduce the initial dimensionality to 50.
% Barnes-Hut variant of the t-SNE algorithm is used to save time.
Y = tsne(X,'Algorithm','barneshut','NumPCAComponents',50);

% Display the result
figure
gscatter(Y(:,1), Y(:,2), trainLabel);
title('Data Visualization by t-SNE');
legend(char(labelDec));

Define the CNN and Train it using Training Data

layers = [imageInputLayer([28 28 1])
    convolution2dLayer(5,20)
    reluLayer
    maxPooling2dLayer(2,'Stride',2)
    fullyConnectedLayer(10)
    softmaxLayer
    classificationLayer()];

options = trainingOptions('sgdm','MaxEpochs',15, ...
   	'InitialLearnRate',0.0001);

% Reshape the training data
trainImageNew = zeros(28,28,1,19909);
trainImageNew(:,:,1,:) = trainImage;

convnet = trainNetwork(trainImageNew,trainLabel,layers,options);
Training on single CPU.
Initializing image normalization.
|=========================================================================================|
|     Epoch    |   Iteration  | Time Elapsed |  Mini-batch  |  Mini-batch  | Base Learning|
|              |              |  (seconds)   |     Loss     |   Accuracy   |     Rate     |
|=========================================================================================|
|            1 |            1 |         0.25 |       2.9801 |        6.25% |     1.00e-04 |
|            1 |           50 |        10.66 |       1.0008 |       71.88% |     1.00e-04 |
|            1 |          100 |        21.36 |       0.6804 |       77.34% |     1.00e-04 |
|            1 |          150 |        31.61 |       0.7538 |       77.34% |     1.00e-04 |
|            2 |          200 |        43.29 |       0.5306 |       85.16% |     1.00e-04 |
|            2 |          250 |        53.72 |       0.6145 |       81.25% |     1.00e-04 |
|            2 |          300 |        66.88 |       0.6982 |       82.03% |     1.00e-04 |
|            3 |          350 |        78.58 |       0.8186 |       82.81% |     1.00e-04 |
|            3 |          400 |        90.97 |       0.3380 |       89.84% |     1.00e-04 |
|            3 |          450 |       102.02 |       0.3844 |       90.63% |     1.00e-04 |
|            4 |          500 |       112.78 |       0.4480 |       87.50% |     1.00e-04 |
|            4 |          550 |       125.21 |       0.4456 |       85.94% |     1.00e-04 |
|            4 |          600 |       138.12 |       0.4739 |       86.72% |     1.00e-04 |
|            5 |          650 |       149.59 |       0.4445 |       85.94% |     1.00e-04 |
|            5 |          700 |       161.41 |       0.3495 |       89.06% |     1.00e-04 |
|            5 |          750 |       172.62 |       0.5154 |       85.16% |     1.00e-04 |
|            6 |          800 |       184.28 |       0.2934 |       90.63% |     1.00e-04 |
|            6 |          850 |       199.15 |       0.5250 |       85.94% |     1.00e-04 |
|            6 |          900 |       212.30 |       0.4356 |       87.50% |     1.00e-04 |
|            7 |          950 |       224.66 |       0.2432 |       95.31% |     1.00e-04 |
|            7 |         1000 |       234.79 |       0.4922 |       87.50% |     1.00e-04 |
|            7 |         1050 |       245.52 |       0.2400 |       92.97% |     1.00e-04 |
|            8 |         1100 |       256.88 |       0.2425 |       94.53% |     1.00e-04 |
|            8 |         1150 |       269.64 |       0.2670 |       92.97% |     1.00e-04 |
|            8 |         1200 |       284.31 |       0.4160 |       89.84% |     1.00e-04 |
|            9 |         1250 |       296.72 |       0.2648 |       93.75% |     1.00e-04 |
|            9 |         1300 |       307.56 |       0.3443 |       89.84% |     1.00e-04 |
|            9 |         1350 |       318.06 |       0.2322 |       95.31% |     1.00e-04 |
|           10 |         1400 |       330.14 |       0.3288 |       92.19% |     1.00e-04 |
|           10 |         1450 |       341.19 |       0.2022 |       96.09% |     1.00e-04 |
|           10 |         1500 |       352.55 |       0.2186 |       95.31% |     1.00e-04 |
|           10 |         1550 |       363.45 |       0.2895 |       91.41% |     1.00e-04 |
|           11 |         1600 |       374.62 |       0.2134 |       93.75% |     1.00e-04 |
|           11 |         1650 |       385.40 |       0.2193 |       96.09% |     1.00e-04 |
|           11 |         1700 |       397.88 |       0.2363 |       91.41% |     1.00e-04 |
|           12 |         1750 |       411.23 |       0.2171 |       94.53% |     1.00e-04 |
|           12 |         1800 |       424.64 |       0.3328 |       89.06% |     1.00e-04 |
|           12 |         1850 |       437.48 |       0.3235 |       90.63% |     1.00e-04 |
|           13 |         1900 |       448.35 |       0.4363 |       90.63% |     1.00e-04 |
|           13 |         1950 |       462.78 |       0.2033 |       92.97% |     1.00e-04 |
|           13 |         2000 |       477.48 |       0.1814 |       91.41% |     1.00e-04 |
|           14 |         2050 |       491.26 |       0.1908 |       92.97% |     1.00e-04 |
|           14 |         2100 |       502.92 |       0.2101 |       96.09% |     1.00e-04 |
|           14 |         2150 |       514.41 |       0.2781 |       91.41% |     1.00e-04 |
|           15 |         2200 |       524.65 |       0.2245 |       92.19% |     1.00e-04 |
|           15 |         2250 |       535.53 |       0.2113 |       95.31% |     1.00e-04 |
|           15 |         2300 |       546.67 |       0.3212 |       91.41% |     1.00e-04 |
|           15 |         2325 |       552.29 |       0.2279 |       94.53% |     1.00e-04 |
|=========================================================================================|

Classify the Images in Test Data and Check Accuracy

Reshape the test data

testImageNew = zeros(28,28,1,3514);
testImageNew(:,:,1,:) = testImage;

% Classify the images in test data
testPredLabel = classify(convnet, testImageNew)';

% Calculate the accuracy
accuracy = sum(testPredLabel == testLabel)/numel(testLabel);
disp(['Accuracy: ', num2str(accuracy)]);
Accuracy: 0.91292

Display Some of the Images Correctly Classified

loc = find(testLabel == testPredLabel);

figure
for kk = 1:20
    subplot(4,5,kk);
    imshow(testImage(:,:,loc(kk))',[]);
    idx_t = str2num(char(testLabel(loc(kk))));
    idx_p = str2num(char(testPredLabel(loc(kk))));
    title(['"',char(labelDec(idx_t+1)),'" => "',char(labelDec(idx_p+1)),'"'])
end

Display Some of the Images Incorrectly Classified

loc = find(testLabel ~= testPredLabel);

figure
for kk = 1:20
    subplot(4,5,kk);
    imshow(testImage(:,:,loc(kk))',[]);
    idx_t = str2num(char(testLabel(loc(kk))));
    idx_p = str2num(char(testPredLabel(loc(kk))));
    title(['"',char(labelDec(idx_t+1)),'" => "',char(labelDec(idx_p+1)),'"'])
end